A, above

Reference based on WxJava wechat Pay SpringBoot back-end interface using wechat Pay – developer documents – small program – small program call up payment API (V3 version)

Wechat Pay — Development Documents — Small Program Payment — Small program Call up payment API (V2) wechat Pay interface Signature Verification tool wechat Official Documents — Small Program — Payment/wX.RequestPayment (V3)

  • Version V2 API, encrypted by MD5 (this post is mainly brief)
  • Version V3 API, using RAS encryption

Ii. Flow chart

Wechat applet ->> wechat applet ->>SpringBoot back-end: invokes the single interface of the back-end SpringBoot back-end ->>SpringBoot back-end: JSAPI unified order SpringBoot back end ->>SpringBoot back end: wechat order data is stored in the database SpringBoot back end ->>SpringBoot back end: generate small programs to adjust the data required for payment SpringBoot back end ->> wechat small programs: Weixin Applet ->> weixin applet: Wx. requestPayment initiates weixin Payment. Weixin Applet ->>SpringBoot back end: SpringBoot back end: payment success/failure callback SpringBoot back end ->>SpringBoot back end: JSAPI query order SpringBoot back-end ->>SpringBoot back-end: confirm payment success and update database

3. SpringBoot interface implementation

2.1 Data required for wechat payment adjustment

Md5Utils

/** * Md5 encryption method **@author weijian
 */
public class Md5Utils
{
    private static final Logger log = LoggerFactory.getLogger(Md5Utils.class);

    /** * Generate MD5 **@paramData Data to be processed *@returnMD5 * / as a result
    public static String MD5(String data) {
        try {
            java.security.MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] array = md.digest(data.getBytes("UTF-8"));
            StringBuilder sb = new StringBuilder();
            for (byte item : array) {
                sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1.3));
            }
            return sb.toString().toUpperCase();
        }catch (Exception e){
            e.printStackTrace();
        }
        return null; }}Copy the code

WxPayment


/** * WxPayment **@author weijian
 */
@apiModel (value="WxPayment", Description ="WxPayment")
public class WxPayment
{
    @ApiModelProperty(value="wxTradeId", required = true)
    @Excel(name = "wxTradeId")
    private Long wxTradeId;

    @apiModelProperty (value=" applet ID ", required = true)
    @excel (name = "applet id")
    private String appId;

    @apiModelProperty (value=" timestamp ", required = true)
    @excel (name = "time stamp ")
    private String timeStamp;

    @apiModelProperty (value=" random string ", required = true)
    @excel (name = "random string ")
    private String nonceStr;

    @apiModelProperty (value=" Order detail extension string ", required = true)
    @excel (name = "order detail extension string ")
    private String _package;

    @apiModelProperty (value=" signature mode ", required = true)
    @excel (name = "signature mode ")
    private String signType;

    @apiModelProperty (value=" signature ", required = true)
    @excel (name = "signature ")
    private String paySign;

    public void sign(String key){
        String sign = ("appId="+appId+"&");
        sign += ("nonceStr="+nonceStr+"&");
        sign += ("package="+_package+"&");
        sign += ("signType="+signType+"&");
        sign += ("timeStamp="+timeStamp+"&");
        sign += ("key="+key);
        System.out.println("sign="+sign);
        setPaySign(Md5Utils.MD5(sign).toUpperCase());
    }

    public Long getWxTradeId(a) {
        return wxTradeId;
    }

    public void setWxTradeId(Long wxTradeId) {
        this.wxTradeId = wxTradeId;
    }

    public String getAppId(a) {
        return appId;
    }

    public void setAppId(String appId) {
        this.appId = appId;
    }

    public String getTimeStamp(a) {
        return timeStamp;
    }

    public void setTimeStamp(String timeStamp) {
        this.timeStamp = timeStamp;
    }

    public String getNonceStr(a) {
        return nonceStr;
    }

    public void setNonceStr(String nonceStr) {
        this.nonceStr = nonceStr;
    }

    public String get_package(a) {
        return _package;
    }

    public void set_package(String _package) {
        this._package = _package;
    }

    public String getSignType(a) {
        return signType;
    }

    public void setSignType(String signType) {
        this.signType = signType;
    }

    public String getPaySign(a) {
        return paySign;
    }

    public void setPaySign(String paySign) {
        this.paySign = paySign;
    }

    @Override
    public String toString(a) {
        return "WxPayment{" +
                "wxTradeId=" + wxTradeId +
                ", appId='" + appId + '\' ' +
                ", timeStamp='" + timeStamp + '\' ' +
                ", nonceStr='" + nonceStr + '\' ' +
                ", _package='" + _package + '\' ' +
                ", signType='" + signType + '\' ' +
                ", paySign='" + paySign + '\' ' +
                '} '; }}Copy the code

2.2 Single Interface

WxPayController


    @ApiOperation(" wechat unified Order ")
// @PreAuthorize("@ss.hasPermi('wallet:update')")
    @log (title = "wechat unified order ", businessType = businessType.UPDATE)
    @PostMapping("/wx/unifiedOrder")
    public AjaxResult wxUnifiedOrder(@ApiParam() Long billId) throws Exception
    {
        Bill bill = billService.selectBillById(billId);
        if(ObjectUtil.isNull(bill)){
            return AjaxResult.error("Bill exception");
        }

		//1. JSAPI wechat unified order
        WxPayUnifiedOrderRequest wxPayUnifiedOrderRequest = new WxPayUnifiedOrderRequest();
        wxPayUnifiedOrderRequest.setOutTradeNo(IdUtils.fastSimpleUUID(16));
        wxPayUnifiedOrderRequest.setTotalFee(1);
        wxPayUnifiedOrderRequest.setSpbillCreateIp(IpUtils.getHostIp());
        wxPayUnifiedOrderRequest.setNotifyUrl("https://www.nb.cn:8080/v1/wx/notify");
        wxPayUnifiedOrderRequest.setTradeType("JSAPI");
        wxPayUnifiedOrderRequest.setBody("Pay the bill");
        wxPayUnifiedOrderRequest.setOpenid(SecurityUtils.getLoginUser().getUser().getTenantOpenId());
        wxPayUnifiedOrderRequest.setAppid("wx********");
        WxPayUnifiedOrderResult wxPayUnifiedOrderResult = wxService.unifiedOrder(wxPayUnifiedOrderRequest);

		//2. Wechat order data is stored in the database
        WxTrade wxTrade = new WxTrade();
        wxTrade.setBillId(billId);
        wxTrade.setUserId(SecurityUtils.getUserId());
        wxTrade.setUserName(SecurityUtils.getUsername());
        wxTrade.setAppId(wxPayUnifiedOrderResult.getAppid());
        wxTrade.setMchId(wxPayUnifiedOrderResult.getMchId());
        wxTrade.setSubMchId(wxPayUnifiedOrderResult.getSubMchId());
        wxTrade.setOutTradeNo(wxPayUnifiedOrderRequest.getOutTradeNo());
        wxTrade.setTotalFee(wxPayUnifiedOrderRequest.getTotalFee());
        wxTrade.setBody(wxPayUnifiedOrderRequest.getBody());
        wxTrade.setStatus(Constants.TRADE_UNKNOWN);
        wxTradeService.insertWxTrade(wxTrade);

		//3. Generate a small program to adjust the data required for payment
        WxPayment wxPayment = new WxPayment();
        wxPayment.setWxTradeId(wxTrade.getId());
        wxPayment.setAppId(wxPayUnifiedOrderResult.getAppid());
        wxPayment.setTimeStamp((System.currentTimeMillis()/1000) +"");
        wxPayment.set_package("prepay_id="+wxPayUnifiedOrderResult.getPrepayId());
        wxPayment.setNonceStr(IdUtils.fastSimpleUUID(32));
        wxPayment.setSignType("MD5");
        wxPayment.sign(wxPayProperties.getMchKey());
        logger.info(wxPayment.toString());

		4 / / return wxPayment
        return AjaxResult.success(wxPayment);
    }
Copy the code

2.3 Payment callback interface

Payment callback interface

  1. Check whether the wechat order has been completed
  2. Confirming that the payment is completed, the specific business logic is executed
    /** * order status, -1: unknown; 0: payment failed. 1: payment is successful */
    public static final int TRADE_UNKNOWN     = -1;
    public static final int TRADE_FAIL        = 0;
    public static final int TRADE_SUCCESS     = 1;
Copy the code
    public int queryWxOrder(String outTradeNo){
        try {
            WxPayOrderQueryResult wxPayOrderQueryResult = wxService.queryOrder(null, outTradeNo);
            logger.info(wxPayOrderQueryResult.toString());
            if(wxPayOrderQueryResult.getTradeState().equals("NOTPAY")) {return Constants.TRADE_UNKNOWN;
            }
            return Constants.TRADE_SUCCESS;
        }catch (Exception e){
// e.printStackTrace();
            // Exception, order does not exist
        }
        return Constants.TRADE_FAIL;
    }
Copy the code

Three, wechat small program implementation

Most of the encryption verification, and wechat pay interface interaction in Java background operation, so wechat small program code is relatively simple.

3.1 Unified ordering by JSAP

  // Unified order
  unifiedOrder(){
    var _this = this
    app.showLoading(true)
    keyueliSdk.wxUnifiedOrder(
      {
        billId: _this.data.id,
      },
      (res) = > {
        console.log("wxUnifiedOrder", res)
        _this.requestPayment(res.data.data)
      },
      (res) = >{})},Copy the code

3.2 Small program to adjust the payment

  // Adjust the payment interface for the official standard payment method
  requestPayment(payData) {
    var _this = this
    wx.requestPayment({
      timeStamp: payData.timeStamp,
      nonceStr: payData.nonceStr,
      package: payData._package,
      signType: payData.signType,
      paySign: payData.paySign,
      success(res) {
        console.log("Successful payment", res)
        _this.paySuccess(payData)
      },
      fail(res) {
        console.log("Payment failure", res)
        app.showLoading(false)
        app.showToast("Payment failure")}})},Copy the code

3.3 Payment callback

  // Record payment success
  paySuccess(payData){
    keyueliSdk.wxPay(
      payData.wxTradeId,
      (res) = > {
        wx.hideLoading()
        console.log("wxPay", res)
        if(res.data.code==200){
          app.showToast("Successful payment")
          wx.navigateBack({
            delta: 1,})return
        }
        app.showToast(res.data.msg)
      },
      (res) = >{})},Copy the code

If you think it’s good, you can connect it with three clicks (like + favorites + follow).