02微信支付二维码

2.微信支付二维码

2.1 需求分析

用户在提交订单后,如果是选择支付方式为微信支付,那应该跳转到微信支付二维码页面,用户扫描二维码可以进行支付,金额与订单金额相同。

在这里插入图片描述

2.2 实现思路

前端页面向后端传递订单号,后端根据订单号查询订单,检查是否为当前用户的未支付订单,如果是则根据订单号和金额生成支付url返给前端,前端得到支付url生成支付二维码。

2.3 代码实现

2.3.1 提交订单跳转支付页

1)更新changgou_web_order的application.yml,添加读取超时设置

#请求处理的超时时间
ribbon:
  ReadTimeout: 4000
  #请求连接的超时时间
  ConnectTimeout: 3000

在这里插入图片描述

3)更新changgou_service_order中add() ,设置返回值为订单Id

//orderServiceImpl
/**
     * 增加
     * @param order
     */
    @Override
    @GlobalTransactional(name = "order_add")
    public String add(Order order){
        //1.获取购物车的相关数据(redis)
        Map cartMap = cartService.list(order.getUsername());
        List<OrderItem> orderItemList = (List<OrderItem>) cartMap.get("orderItemList");

        //2.统计计算:总金额,总数量
        //3.填充订单数据并保存到tb_order
        order.setTotalNum((Integer) cartMap.get("totalNum"));
        order.setTotalMoney((Integer) cartMap.get("totalMoney"));
        order.setPayMoney((Integer) cartMap.get("totalMoney"));
        order.setCreateTime(new Date());
        order.setUpdateTime(new Date());
        order.setBuyerRate("0"); // 0:未评价  1:已评价
        order.setSourceType("1"); //1:WEB
        order.setOrderStatus("0"); //0:未完成 1:已完成 2:已退货
        order.setPayStatus("0"); //0:未支付 1:已支付
        order.setConsignStatus("0"); //0:未发货 1:已发货
        String orderId = idWorker.nextId()+"";
        order.setId(orderId);
        orderMapper.insertSelective(order);

        //4.填充订单项数据并保存到tb_order_item
        for (OrderItem orderItem : orderItemList) {
            orderItem.setId(idWorker.nextId()+"");
            orderItem.setIsReturn("0"); //0:未退货 1:已退货
            orderItem.setOrderId(orderId);
            orderItemMapper.insertSelective(orderItem);
        }

        //扣减库存并增加销量
        skuFeign.decrCount(order.getUsername());

        //int i =1/0;
        //添加任务数据
        System.out.println("向订单数据库中的任务表去添加任务数据");
        Task task = new Task();
        task.setCreateTime(new Date());
        task.setUpdateTime(new Date());
        task.setMqExchange(RabbitMQConfig.EX_BUYING_ADDPOINTUSER);
        task.setMqRoutingkey(RabbitMQConfig.CG_BUYING_ADDPOINT_KEY);

        Map map = new HashMap();
        map.put("username",order.getUsername());
        map.put("orderId",orderId);
        map.put("point",order.getPayMoney());
        task.setRequestBody(JSON.toJSONString(map));
        taskMapper.insertSelective(task);

        //5.删除购物车数据(redis)
        redisTemplate.delete("cart_"+order.getUsername());

        return orderId;
    }


//orderController
@PostMapping
public Result<String> add(@RequestBody Order order){
	String username = tokenDecode.getUserInfo().get("username");
	order.setUsername(username);
	String orderId = orderService.add(order);
	return new Result(true,StatusCode.OK,"添加成功",orderId);
}
  1. 更新order.html中添加订单js
add:function () {
	axios.post('/api/worder/add',this.order).then(function
(response) {
		if (response.data.flag){
			alert("添加订单成功");
			var orderId = response.data.data;
			location.href="/api/worder/toPayPage?orderId="+orderId;
		}else{
			alert("添加失败");
		}
	})
}

5)在orderController中新增方法,用于跳转支付页
5.1)changgou_service_order_api的OrderFeign新增接口定义

package com.changgou.order.feign;

import com.changgou.entity.Result;
import com.changgou.order.pojo.Order;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

@FeignClient(name = "order")
public interface OrderFeign {

    @PostMapping("/order")
    public Result add(@RequestBody Order order);

    @GetMapping("/order/{id}")
    public Result<Order> findById(@PathVariable("id") String id);
}

5.2) changgou_order_web中的orderController新增方法,跳转支付页

@GetMapping("/toPayPage")
    public String toPayPage(String orderId,Model model){
        //获取到订单的相关信息
        Order order = orderFeign.findById(orderId).getData();
        model.addAttribute("orderId",orderId);
        model.addAttribute("payMoney",order.getPayMoney());
        return "pay";
    }

2.3.2 支付微服务-下单

(1)创建changgou_service_pay (支付微服务), pom.xml添加依赖

 <dependencies>
        <dependency>
            <groupId>com.changgou</groupId>
            <artifactId>changgou_common</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>com.github.wxpay</groupId>
            <artifactId>wxpay-sdk</artifactId>
            <version>3.0.9</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
    </dependencies>

排除log包,否则会因为包冲突无法正常启动
(2)创建配置文件application.yml

server:
  port: 9010
spring:
  application:
    name: pay
  rabbitmq:
    host: 192.168.200.128
  main:
    allow-bean-definition-overriding: true #当遇到同样名字的时候,是否允许覆盖注册
eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:6868/eureka
  instance:
    prefer-ip-address: true
wxpay:
  notify_url: http://weizhaohui.cross.echosite.cn/wxpay/notify #回调地址

(3)创建com.github.wxpay.sdk包,包下创建Config类

package com.github.wxpay.sdk;

import java.io.InputStream;

public class MyConfig extends WXPayConfig {

    @Override
    String getAppID() {
        return "wx8397f8696b538317";
    }

    @Override
    String getMchID() {
        return "1473426802";
    }

    @Override
    String getKey() {
        return "T6m9iK73b0kn9g5v426MKfHQH7X8rKwb";
    }

    @Override
    InputStream getCertStream() {
        return null;
    }

    @Override
    IWXPayDomain getWXPayDomain() {
        return new IWXPayDomain() {
            @Override
            public void report(String s, long l, Exception e) {
            }

            @Override
            public DomainInfo getDomain(WXPayConfig wxPayConfig) {
                return new DomainInfo("api.mch.weixin.qq.com",true);
            }
        };
    }
}

(4)创建com.changgou包,包下创建类PayApplication

package com.changgou.pay;

import com.github.wxpay.sdk.MyConfig;
import com.github.wxpay.sdk.WXPay;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
@EnableEurekaClient
public class PayApplication {

    public static void main(String[] args) {
        SpringApplication.run(PayApplication.class,args);
    }

    @Bean
    public WXPay wxPay(){
        try {
            return new WXPay(new MyConfig());
        } catch (Exception e) {
            e.printStackTrace();
            return  null;
        }
    }
}

@RequestMapping("/wxpay")
@RestController
public class WXPayController {

    @Autowired
    private WXPayService wxPayService;

      //下单
    @GetMapping("/nativePay")
    public Result nativePay(@RequestParam("orderId") String orderId, @RequestParam("money")Integer money){
        Map resultMap = wxPayService.nativePay(orderId, money);
        return  new Result(true, StatusCode.OK,"",resultMap);
    }

}

(5)创建com.changgou.pay.service包,包下创建接口WxPayService

public interface WxPayService {
/**
* 生成微信支付二维码
* @param orderId
* @param money
* @return
*/
Map nativePay(String orderId, Integer money);
}

(6)创建com.changgou.pay.service.impl 包 ,新增服务类WxPayServiceImpl

package com.changgou.pay.service.impl;

import com.changgou.pay.service.WXPayService;
import com.github.wxpay.sdk.WXPay;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.awt.*;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;

@Service
public class WXPayServiceImpl implements WXPayService {

    @Autowired
    private WXPay wxPay;

    @Value("${wxpay.notify_url}")
    private String notify_url;

    //统一下单接口调用
    @Override
    public Map nativePay(String orderId, Integer money) {
        try {
            //1. 封装请求参数
            Map<String,String> map = new HashMap<>();
            map.put("body","畅购");
            map.put("out_trade_no",orderId);

            BigDecimal payMoney = new BigDecimal("0.01");
            BigDecimal fen = payMoney.multiply(new BigDecimal("100")); //1.00
            fen = fen.setScale(0,BigDecimal.ROUND_UP); // 1
            map.put("total_fee",String.valueOf(fen));

            map.put("spbill_create_ip","127.0.0.1");
            map.put("notify_url",notify_url);
            map.put("trade_type","NATIVE");

            //2.基于wxpay完成统一下单接口的调用,并获取返回结果
            Map<String, String> result = wxPay.unifiedOrder(map);
            return result;
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
    }
}

测试:地址栏输入http://localhost:9010/wxpay/nativePay?orderId=990099&money=1

2.3.3 页面对接支付微服务

(1)新增changgou_service_pay_api模块 ,并添加common工程依赖,新增
com.changgou.pay.feign包,包下创建接口

@FeignClient("pay")
public interface WxPayFeign {
/**
* 下单
* @param orderId
* @param money
* @return
*/
@GetMapping("/wxpay/nativePay")
public Result nativePay(@RequestParam("orderId") String orderId,
@RequestParam("money") Integer money );
}

(2)changgou_web_order新增PayController

package com.changgou.web.order.controller;

import com.changgou.entity.Result;
import com.changgou.order.feign.OrderFeign;
import com.changgou.order.pojo.Order;
import com.changgou.pay.feign.PayFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.jws.WebParam;
import java.util.Map;

@Controller
@RequestMapping("/wxpay")
public class PayController {

    @Autowired
    private OrderFeign orderFeign;

    @Autowired
    private PayFeign payFeign;

    //跳转到微信支付二维码页面
    @GetMapping
    public String wxPay(String orderId , Model model){
        //1.根据orderid查询订单,如果订单不存在,跳转到错误页面
        Result<Order> orderResult = orderFeign.findById(orderId);
        if (orderResult.getData() == null){
            return "fail";
        }

        //2.根据订单的支付状态进行判断,如果不是未支付的订单,跳转到错误页面
        Order order = orderResult.getData();
        if (!"0".equals(order.getPayStatus())){
            return "fail";
        }

        //3.基于payFeign调用统计下单接口,并获取返回结果
        Result payResult = payFeign.nativePay(orderId, order.getPayMoney());
        if (payResult.getData() == null){
            return "fail";
        }

        //4.封装结果数据
        Map payMap = (Map) payResult.getData();
        payMap.put("orderId",orderId);
        payMap.put("payMoney",order.getPayMoney());

        model.addAllAttributes(payMap);
        return "wxpay";
    }

}

(3)将静态原型中wxpay.html拷贝到templates文件夹下作为模板,修改模板,部分代码如下:
二维码地址渲染

<script type="text/javascript" th:inline="javascript">
let qrcode = new QRCode(document.getElementById("qrcode"), {
	width : 200,
	height : 200
});
qrcode.makeCode([[${code_url}]]);
</script>

显示订单号与金额

<h4 class="fl tit-txt"><span class="success-icon"></span><span class="successinfo" th:text="|订单提交成功,请您及时付款!订单号:${orderId}|"></span></h4>
<span class="fr"><em class="sui-lead">应付金额:</em><em class="orange money"
th:text="${payMoney}/100"></em></span>

设置支付跳转

<li><a th:href="|/api/wxpay?orderId=${orderId}|"><img src="/img/_/pay3.jpg"></a></li>

(4) 更新网关地址过滤器。添加wxpay路径的拦

在这里插入图片描述

同时更新网关服务的application.yml。添加地址路由标识

在这里插入图片描述

发布了211 篇原创文章 · 获赞 6 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/u014736082/article/details/104764777