[] Skills development - a girlfriend can understand Spring integrate third-party payment (micro-channel pay - pay achieve scan code articles)

1.1 Why pay to use the micro-channel in the project?

As we all know, Alipay and TenPay (micro-channel payment) is now the third-party payment of two leading companies, the same micro-channel is a software with a large number of user groups, integration of micro-channel in the project to pay a certain extent, users can easily pay for purchases .

1.2 How to integrate micro-channel pay in Spring Project (SpringBoot) in?

1.2.1 Pre-preparation
  1. Download micro-channel pay an official SDK, related configuration changes (such as automated assembly, in order to adapt SpringBoot development environment)
    I am here and have a good modify SDK, only need to install the Maven repository can, Qingyun wxpay-sdk-click on the link to download
  • IDEA mounted reliance schematic Maven
    Here Insert Picture Description
1.2.2 began to integrate micro-channel pay in the project
1.2.2.1 introduced recently installed to the micro-channel pay sdk relies warehouse
<dependency>
    <groupId>com.github.wxpay</groupId>
    <artifactId>qingyun-wxpay-sdk</artifactId>
    <version>1.0</version>
</dependency>
1.2.2.2 Configuring the basis of micro-channel configuration information required for payment (in this sdk the parameters have been defined)
wechat.appId=xxxxx
wechat.mchId=xxx
wechat.key=xxx
wechat.notifyUrl=异步回调地址
1.2.2.3 create a micro-channel payment implementation class PayServiceImpl, which includes initiating payments, payment status inquiry, asynchronous notification process
package com.qingyun.wechatpay.service.impl;

import com.github.wxpay.sdk.WXPay;
import com.github.wxpay.sdk.WXPayUtil;
import com.qingyun.wechatpay.enums.PayStatusEnum;
import com.qingyun.wechatpay.enums.PayTypeEnum;
import com.qingyun.wechatpay.mapper.OrderMapper;
import com.qingyun.wechatpay.model.Order;
import com.qingyun.wechatpay.service.OrderService;
import com.qingyun.wechatpay.service.PayService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: 李敷斌.
 * Date: 2020-04-03
 * Time: 21:06
 * Explain: 支付业务实现类
 */
@Service
@Slf4j
public class PayServiceImpl implements PayService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderService orderService;

    @Value(value = "${wechat.notifyUrl}")
    private String wechatNotifyUrl;

    @Autowired
    private WXPay wxPay;

    /**
     * 发起支付
     *
     * @param order
     * @param ipStr
     * @return
     */
    @Override
    public Map<String, String> luanchPay(Order order,String ipStr) throws Exception {

        Map<String, String> data = new HashMap<String, String>();
        data.put("body", order.getRemark());
        data.put("out_trade_no", order.getOrderNo());
        data.put("device_info", "WEB");
        data.put("fee_type", "CNY");
        data.put("total_fee", order.getAmount()+"");
        data.put("spbill_create_ip", ipStr);
        data.put("notify_url", wechatNotifyUrl);
        data.put("trade_type", "NATIVE");  // 此处指定为扫码支付
        data.put("product_id", "1");

        Map<String, String> resultMap = wxPay.unifiedOrder(data);

        log.info(resultMap.toString());

        return resultMap;
    }

    /**
     * @param orderNo
     * @return
     */
    @Override
    public String queryPayStatus(String orderNo) throws Exception {

        Map<String, String> data = new HashMap<String, String>();
        data.put("out_trade_no", orderNo);

        Map<String, String> resp = wxPay.orderQuery(data);

        if ("success".equalsIgnoreCase(resp.get("return_code"))){
            if ("success".equalsIgnoreCase(resp.get("trade_state"))){
                Order order=orderService.getOrderByOrderNo(orderNo);

                //修改订单状态
                if (order!=null&&order.getStatus().equals(PayStatusEnum.UNPAID)){
                    order.setPayType(PayTypeEnum.WECHAT_PAY.getCode());
                    order.setStatus(PayStatusEnum.PAID.getCode());
                    order.setTradeNo(resp.get("transaction_id"));
                }
            }
        }

        return resp.get("trade_state");
    }

    /**
     * 微信支付异步通知处理
     *
     * @param request
     * @return
     */
    @Override
    public String wechatNotify(HttpServletRequest request) {
        try{

            String notifyData = ""; // 支付结果通知的xml格式数据

            //1.从request获取XML流,转化成为MAP数据
            InputStream inputStream = request.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
            StringBuffer sb = new StringBuffer();
            String temp;
            while ((temp = reader.readLine()) != null) {
                sb.append(temp);
            }
            reader.close();
            inputStream.close();

            notifyData = sb.toString();


            Map<String, String> notifyMap = WXPayUtil.xmlToMap(notifyData);  // 转换成map

            //对数据进行签名
            if (wxPay.isResponseSignatureValid(notifyMap)) {
                // 签名正确
                // 进行处理。
                // 注意特殊情况:订单已经退款,但收到了支付结果成功的通知,不应把商户侧订单状态从退款改成支付成功

                String returnCode = notifyMap.get("return_code");

                if (returnCode.equals("SUCCESS")) {
                    if(notifyMap.get("result_code").equals("SUCCESS")){
                        //微信支付订单号
                        String transactionId = notifyMap.get("transaction_id");
                        //商户订单号
                        String outTradeNo = notifyMap.get("out_trade_no");
                        Order order = orderService.getOrderByOrderNo(outTradeNo);
                        if (order!=null && order.getStatus()==0) {
                            order.setPayType(PayTypeEnum.WECHAT_PAY.getCode());
                            order.setStatus(PayStatusEnum.PAID.getCode());
                            order.setTradeNo(transactionId);
                            orderService.updateOrder(order);
                        }
                        System.out.println("微信支付成功");
                    } else {
                        System.out.println("微信支付失败,"+notifyMap.get("err_code")+"---"+notifyMap.get("err_code_des"));
                    }

                } else {
                    System.out.println("微信支付失败,"+notifyMap.get("return_msg"));
                }

                return "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";
            } else {
                // 签名错误,如果数据里没有sign字段,也认为是签名错误
                System.out.println("微信支付异步通知,签名错误");
                return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>";
            }
        } catch (Exception e){
            e.printStackTrace();
        }
        return "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[FAILED]]></return_msg></xml>";
    }
}

1.2.2.4 create a payment request controller for processing payment requests
package com.qingyun.wechatpay.controller;

import com.github.wxpay.sdk.WXPay;
import com.qingyun.wechatpay.enums.PayStatusEnum;
import com.qingyun.wechatpay.model.Order;
import com.qingyun.wechatpay.service.OrderService;
import com.qingyun.wechatpay.service.PayService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 * User: 李敷斌.
 * Date: 2020-04-03
 * Time: 18:22
 * Explain: 支付请求控制器
 */
@Controller
@RequestMapping(value = "/pay")
public class PayController {

    @Autowired
    private WXPay wxPay;

    @Autowired
    private PayService payService;

    @Autowired
    private OrderService orderService;

    @RequestMapping(value = "/luanchwechat")
    public String wechatPay(String orderNo, Model model, HttpServletRequest httpServletRequest) throws Exception {

        Order order=orderService.getOrderByOrderNo(orderNo);

        Map<String, String> resp = payService.luanchPay(order,this.getRemortIP(httpServletRequest));

        model.addAttribute("code_url",resp.get("code_url"));
        model.addAttribute("orderNo",order.getOrderNo());

        return "wechatpay";
    }


    @RequestMapping(value = "/querywechat")
    @ResponseBody
    public String payStatusQuery(String orderNo){

        Order order=orderService.getOrderByOrderNo(orderNo);

        if (order.getStatus().equals(PayStatusEnum.PAID.getCode())){
            return "success";
        }else{
            String reuslt= null;
            try {
                reuslt = payService.queryPayStatus(orderNo);
            } catch (Exception e) {
                e.printStackTrace();
            }

            return reuslt;
        }
    }

    @RequestMapping(value = "/wechat/notify")
    public String wechatNotify(HttpServletRequest request){
        return payService.wechatNotify(request);
    }


    /**
     * 获取用户IP
     * @param request
     * @return
     */
    private String getRemortIP(HttpServletRequest request) {

        if (request.getHeader("x-forwarded-for") == null) {

            return request.getRemoteAddr();

        }

        return request.getHeader("x-forwarded-for");

    }

}
1.2.2.5 Create a page for generating and demonstrate micro-channel scan code to pay two-dimensional code (you can use thymeleaf template engine), git repository address static resource pages needed to be given in the text at the end find
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>微信支付页</title>
</head>
<body>
<div id="qrcode" ></div>


</body>
<script type="text/javascript" src="/js/qrcode.min.js"></script>
<script type="text/javascript" src="/js/jquery-1.8.2.min.js"></script>
<script type="text/javascript">
    //显示二维码
    new QRCode(document.getElementById("qrcode"), "[[${code_url}]]");

    //轮询订单是否支付成功
    var t1 = window.setInterval('queryStatus()', 5000);

    function queryStatus(){
        $.ajax({
            type: 'post',
            url: '/pay/querywechat',
            data: {orderNo:"[[${orderNo}]]"},
            success: function(str){
                console.log(str);
                if('SUCCESS' == str){
                    location.href='/success';
                }
            },
            error: function(){
                alert('执行错误!');
            }
        });
    }
</script>
</html>

Source code to see me gitee cloud, wechatpay Demo-click on the blue link to access the font
至此微信支付与spring整合完毕,如果文章对你有帮助的话请给我点个赞哦,也可以关注博主我将持续更新一些组件使用教程❤️ !

Published 140 original articles · won praise 75 · views 20000 +

Guess you like

Origin blog.csdn.net/qq_43199016/article/details/105358260