Front-end implementation of WeChat payment (H5, WeChat applet)

1. WeChat payment (H5, WeChat applet)

Usually some e-commerce projects use WeChat payment operations, so we will briefly introduce the specific process of WeChat payment.

1.1 What is WeChat Pay? In what business scenarios will WeChat payment be used?

WeChat payment is the payment interface of WeChat's built-in WeChat browser (other browsers do not support it) or WeChat applet, which is mainly responsible for the process of users performing payment operations to merchants.
For example, in the process of placing an order, a common e-commerce company needs to use the WeChat payment interface to wake up the payment amount and enter the payment password interface. Then, according to whether the payment is successful, jump to the corresponding payment success, payment cancellation or payment failure page.

1.2 The usual WeChat payment process

Generally, payment can be divided into two forms:
1. Jump to the order page on the product details page to perform payment (the order has not been created at this time), corresponding to the following 1.2.1 order payment process that has not been created .
2. On the order page, it is pending payment to pay (the order has been created at this time), corresponding to the order payment process of the following 1.2.2 the order has been created .

1.2.1 Order payment process without order creation

The specific general process is as follows:

  1. On the order page, users enter their delivery information through the form.
  2. Click the button to place an order. In the button event, the user's receipt information is placed in the body through the interface post request, and the backend will return an order number to the frontend. (Order creation interface)
  3. When the front-end gets the order number, it requests to put the order number obtained in step 2 in the body through the interface post request, and the back-end will return a set of payment signature data to the front-end. (Order payment signature interface)
  4. The front end then uses WeChat’s built-in payment interface (take the JSAPI payment interface as an example). When using this interface, pass the payment signature data parameters obtained in step 3 to the WeChat payment server.
  5. At this time, a payment page will be invoked on the user interface, which is an interface for the user to input the payment password.
  6. In the return of the interface JSAPI payment interface, write three if judgment conditions:
    ① The user clicks to close the payment password interface, and the JSAPI payment interface will return res.err_msg="get_brand_wcpay_request: cancel", that is, the user cancels the payment, and the front end writes a jump route jump Go to the payment cancellation page;
    ② After the user enters the wrong payment password, the JSAPI payment interface will return res.err_msg == "get_brand_wcpay_request:fail", that is, the user fails to pay, and the front-end writes the jump route to jump to the payment failure page; ③ User payment
    password After it is correct, the JSAPI payment interface will return res.err_msg == "get_brand_wcpay_request: ok", that is, the user's payment is successful, and the front-end writes the jump route to jump to the payment success page;

1.2.2 The order payment process after the order has been created

The specific general process is as follows:

  1. The user enters the order list page to be paid. At this time, the backend will pass all the orders to be paid by the user and their corresponding order numbers to the frontend (user order list interface) through the interface, and the frontend will display the list.
  2. The user clicks the button to proceed with payment in one of the pending orders. The button event first takes out the order number of an order to be paid.
  3. Then proceed to step 3-6 of 1.2.1 until the order completes the payment process.

1.3 WeChat payment interface

Now, the general WeChat payment interface is divided into two types:
1. JSAPI payment interface
2. wx.chooseWXPay in the JSSDK of the WeChat official account.
Usually the payment interface will be packaged and placed in the global, so that the front-end call can reduce repeated writing.

1.3.1 JSAPI payment interface related code

// 检测支付环境中的 WeixinJSBridge
   if (typeof WeixinJSBridge == "undefined") {
    
    
      if (document.addEventListener) {
    
    
        document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);
      } else if (document.attachEvent) {
    
    
        document.attachEvent('WeixinJSBridgeReady', onBridgeReady);
        document.attachEvent('onWeixinJSBridgeReady', onBridgeReady);
      }
    } else {
    
    
      onBridgeReady();
    }

    function onBridgeReady() {
    
    
        WeixinJSBridge.invoke(
          'getBrandWCPayRequest', {
    
    
            "appId": "appId", //公众号名称,由商户传入
            "timeStamp": "timeStamp", //时间戳,自1970年以来的秒数
            "nonceStr": "nonceStr", //随机串
            "package": "package",
            "signType": "MD5", //微信签名方式:
            "paySign": "paySign" //微信签名
          },
          function(res) {
    
    
            // 支付成功
            if (res.err_msg == "get_brand_wcpay_request:ok") {
    
    
              // 使用以上方式判断前端返回,微信团队郑重提示:
              //res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
            }
            // 支付过程中用户取消
            if (res.err_msg == "get_brand_wcpay_request:cancel") {
    
    

            }
            // 支付失败
            if (res.err_msg == "get_brand_wcpay_request:fail") {
    
    

            }
            /**
            * 其它
            * 1、请检查预支付会话标识prepay_id是否已失效
            * 2、请求的appid与下单接口的appid是否一致
            * */
            if (res.err_msg == "调用支付JSAPI缺少参数:total_fee") {
    
    

            }
          });
      }

From the above code, we can see that the WeixinJSBridge in the payment environment will be detected first. I personally think that it is to judge whether the execution code is in the WeChat environment. When executing the WeixinJSBridge.invoke() interface request, a set of payment signature data will be used, which is exactly what is given by requesting the payment signature through the backend.
They are the following five types of data:

  • appId is the official account name
  • timeStamp is a timestamp, the number of seconds since 1970
  • nonceStr is a random string
  • package is an extended string for order details
  • signType is the WeChat signature method, and the default is MD5
  • paySign is a WeChat signature, which is generated by a signature generation algorithm
    (注意:在调用支付接口的参数,支付签名的数据中的字段名受大小写敏感)

1.3.2 wx.chooseWXPay in the JSSDK of the WeChat official account

1.3.2.1 Preconditions for using wx.chooseWXPay

Before using wx.chooseWXPay, you need to prepare the jweixin-1.6.0.js file, and reference this JS file on the page that needs to be used. For specific instructions, please refer to the WeChat official JSSDK documentation

1.3.2.2 wx.chooseWXPay related code

let WeChatPay = function() {
    
    
// 2、引入js后、获取公众号校验信息
    let timestamp = '',
      nonceStr = '',
      signature = '';
    let v = {
    
    
      // 用于换取微信校验信息的参数:要求不可以包含 “#” 号
      url: location.split('#')[0]
    };

    // 3、通过config接口注入权限验证配置(需要同步进行,在获取到校验信息后方可注入config,否则校验失败!)
    wx.config({
    
    
      debug: true, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
      appId: '', // 必填,公众号的唯一标识
      timestamp: , // 必填,生成签名的时间戳
      nonceStr: '', // 必填,生成签名的随机串
      signature: '', // 必填,签名
      jsApiList: ["checkJsApi", "chooseWXPay", "updateAppMessageShareData", "updateTimelineShareData"] // 必填,需要使用的JS接口列表
    });

    axios.post('/wx/pay/orderPay_XXXX', data).then(res => {
    
    
      // 支付成功状态
      if (res.code == 200) {
    
    
        // 获取支付必备的参数
        let {
    
    
          nonceStr,
          package,
          signType,
          paySign
        } = res.data;
        // 4、通过ready接口处理成功验证
        wx.ready(function() {
    
    
          /* 微信支付 */
          wx.chooseWXPay({
    
    
            timestamp: 0, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
            nonceStr: nonceStr, // 支付签名随机串,不长于 32 位
            package: package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
            signType: signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
            paySign: paySign, // 支付签名
            success: function(res) {
    
    
              // 前端判断返回方式,微信团队郑重提示:不保证绝对可靠,切记!
              if (res.errMsg == 'chooseWXPay:ok') {
    
    
                // 【支付成功】
              } else if (res.errMsg == 'chooseWXPay:cancel') {
    
    
                // 【支付取消】:用户取消支付不会进入这个判断,而是进入complate和cancel函数
              } else {
    
    

              }
            },
            complete: function(res) {
    
    
              // 接口调用完成时执行的回调函数,无论成功或失败都会执行
              if (res.errMsg == 'chooseWXPay:ok') {
    
    
                // 【支付成功】:支付成功提示页面,点击完成按钮之后
                wx.closeWindow(); /* 关闭微信窗口,调用时需要在config中进行校验 */
              } else if (res.errMsg == 'chooseWXPay:cancel') {
    
    
                // 【支付取消】
              } else {
    
    

              }
              /**
              * iOS和Android支付成功点击“完成”后都会进入success和complete函数,都返回'chooseWXPay:ok'
              * (也有人说Android支付成功不进入success函数,)
              * 原因是【iOS和Android返回数据不同。支付成功后Android返回 {"errMsg":"getBrandWCPayRequest:ok"},iOS返回{"err_Info":"success","errMsg":"chooseWXPay:ok"},故Android找不到success方法,导致失败】
              * */
            },
            fail: function(err) {
    
    
              // 接口调用失败
            },
            cancel: function(err) {
    
    
              // 用户点击取消时的回调函数:用户取消支付后实际上进入cancel 和 complate函数
            }
          });
        });
      }
    }).catch(err => {
    
    
      console.log('支付失败:', err);
    });
  }

Observing the above code, compared with the previous JS API payment interface, you can see that there are two more steps 2 and 3, which require permission authentication of the config interface. The following payment scenarios will not be described, and the focus will be on steps 2 and 3.
In this, not only the data of payment signature is required, but also the string array of jsApiList is used. What is the use of the string array of jsApiList? In the following 1.3.2.3 jsApiList will explain in detail.

1.3.2.3 jsApiList

A set of strings in jsApiList is a function.
For example, WeChat's H5 needs to use WeChat's getLocation and shared address library openAddress at the same time.
Then you can write the function you want to use in wx.config permission authentication, namely jsApiList: [“getLocation”, “openAddress”]. The following wx. function name calls this function interface to realize the corresponding function.
For specific functions that can be written in jsApiList, please refer to the official WeChat JSSDK documentation.
Usually, this function can be used when sharing H5 with friends or sharing with Moments. Sharing is a card with a picture and caption text inside. If the wx.config permission authentication is not performed, when the user directly performs the sharing operation, the drawing and sharing is a link.

1.3.2.4 jssdk circle of friends or friends sharing rules in the form of cards

In my previous projects, I encountered business scenarios where H5 needed to be shared through jssdk, but when user A shared it with user B for the first time, it was often not shared in the form of a card.
The card style in the collection is shown in the figure below:
insert image description here
The card style in the friend forwarding interface is shown in the figure below:
insert image description here

After that, I searched online and found that users who share for the first time can use one of the following three rules to share:

  • Open the link in the official account menu to share normally
  • You can open and share through the collection link
  • Change the link to a QR code, scan the code and enter to share and it’s OK

This is the sharing regulation of WeChat official jssdk. The sharing of H5 is not as simple as that of WeChat applet. After all, H5 has fewer online review steps than WeChat applet and is not very rigorous.
After checking online, these sharing solutions are basically the same, so it is best for users who share for the first time to share it with customers through developers (according to the above three sharing rules), and users B or later see it as a card+ What the title + profile looks like

Guess you like

Origin blog.csdn.net/Ak47a7/article/details/130206283