Wechat applet access to wechat payment

Open a merchant account

The premise of WeChat payment is: after registering on the WeChat platform, you must open an enterprise merchant account, and you need to submit the business registration certificate, enterprise bank account opening certificate, organization code, etc. for review https://pay.weixin.qq.com/index .php/apply/applyment_home/guide_normal

insert image description here
After opening the merchant account, we need to get the key, certificate and other related information, which is generated according to the following document: https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_8_1.shtml

Mini Program Binding WeChat Pay

If you do not have a WeChat Mini Program, please activate [Enterprise Edition] first. To enable WeChat Pay for a Mini Program, apply for or re-use a WeChat Pay merchant account. After applying for the Mini Program, log in to the background of the Mini Program. Click WeChat Pay on the left navigation bar and activate it on the page Bind
insert image description here
APPID: Then you need to add the associated APPID for binding, the effect is as follows
insert image description here
Agree to authorize: Go back to the background of the WeChat applet - find in the function: WeChat Pay, to agree to authorize

access SDK

WeChat payment needs to prepare the following parameters, refer to the document:
https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_8_1.shtml

  • APPID of the WeChat Mini Program
  • WeChat payment merchant ID: merchantId, WeChat payment platform to obtain
  • WeChat payment certificate: WeChat payment platform to obtain
  • WeChat payment merchant certificate serial number: merchantSerialNumber
  • WeChat payment merchant APIV3 key: apiV3key

WeChat provides an SDK to facilitate our access to WeChat payment:

  • Small program development guidelines: https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_8_2.shtml,

  • Applet payment document: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_1.shtml

  • Mini program interface list: https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_8_3.shtml

  • Small program, code case reference: https://github.com/wechatpay-apiv3/wechatpay-java/blob/main/service/src/example/java/com/wechat/pay/java/service/payments/jsapi/JsapiServiceExtensionExample .java

The first step, we add the Maven package provided by WeChat

<dependencies>
    <dependency>
        <groupId>com.github.wechatpay-apiv3</groupId>
        <artifactId>wechatpay-java</artifactId>
        <version>0.2.8</version>
    </dependency>
    <dependency>
        <groupId>com.github.wechatpay-apiv3</groupId>
        <artifactId>wechatpay-apache-httpclient</artifactId>
        <version>0.4.9</version>
    </dependency>
</dependencies>

For JSAPI payment and APP payment, it is recommended to use the service extension class JsapiServiceExtension and AppServiceExtension, both of which include the method of placing an order and returning the payment parameters. The following is a quick access code example provided by the WeChat platform

/** Native 支付下单为例 */
public class QuickStart {
    
    

    public static String appid = "";
    /** 商户号 */
    public static String merchantId = "";
    /** 商户API私钥路径 */
    public static String privateKeyPath = "D:\\itsource\\data\\apiclient_key.pem";
    /** 商户证书序列号 */
    public static String merchantSerialNumber = "";
    /** 商户APIV3密钥 */
    public static String apiV3key = "";

    public static void main(String[] args) {
    
    
        // 使用自动更新平台证书的RSA配置
        // 一个商户号只能初始化一个配置,否则会因为重复的下载任务报错
        Config config =
                new RSAAutoCertificateConfig.Builder()
                        .merchantId(merchantId)
                        .privateKeyFromPath(privateKeyPath)
                        .merchantSerialNumber(merchantSerialNumber)
                        .apiV3Key(apiV3key)
                        .build();
        // 构建service
        JsapiServiceExtension service = new JsapiServiceExtension.Builder().config(config).build();
        // request.setXxx(val)设置所需参数,具体参数可见Request定义
        PrepayRequest request = new PrepayRequest();
        Amount amount = new Amount();
        amount.setTotal(100);
        request.setAmount(amount);

        Payer payer = new Payer();
        //支付者的微信OpenId
        payer.setOpenid("xxxx");
        request.setPayer(payer);
        request.setAppid(appid);
        request.setMchid(merchantId);
        
    	//分账
        SettleInfo settleInfo = new SettleInfo();
        settleInfo.setProfitSharing(true);
        request.setSettleInfo(settleInfo);
        
        request.setDescription("测试商品标题");
        request.setNotifyUrl("https://notify_url");
        request.setOutTradeNo("out_trade_no_001"+ DateFormatUtils.format(new Date(),"HHmmss"));
        // 调用下单方法,得到应答
        PrepayWithRequestPaymentResponse response = service.prepayWithRequestPayment(request);
        System.out.println(response);

    }
}

We need to subpackage our own WeChat payment logic and write the payment Controller interface according to the above code case. The applet needs to request the payment interface. And the return value is sent to the APP accordingly. The result of PrepayWithRequestPaymentResponse protects the following result values
​​● “timeStamp”: time rubbing
● “nonceStr”: random string, no longer than 32
characters prepay_id parameter value, "prepay_id=xxxx"
● "signType": signature type, the default is RSA, only RSA is supported
● "paySign": signature, the signature value calculated using the fields appId, timeStamp, nonceStr, and package

Mini program transfer payment

The applet gets the payment parameters returned by the background, and then calls wx.requestPayment to call WeChat to complete the payment in the payment component

wx.requestPayment({
    
    
      timeStamp: result.timeStamp,
      nonceStr: result.nonceStr,
      package: result.packageVal,
      signType: result.signType,//'MD5',
      paySign: result.paySign,
      success (payRes) {
    
     
          console.log(res);
      },
      fail (error) {
    
    
          console.log(error);
      }
})

WeChat payment result callback

WeChat payment result notification: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_5.shtml

The WeChat payment platform calls back our interface through notify_url to notify us of the payment result, because our project is deployed on the intranet, and if it is an online environment, this problem does not exist, so this request cannot be adjusted, we need to do intranet penetration Through mapping our application to the external network, so that the payment platform can call us back.

Natapp intranet penetration tutorial address: https://natapp.cn/article/natapp_newbie, the final effect is as follows: insert image description here
when accessing this domain name is equivalent to accessing: 127.0.0.1:10010, but this domain name can be accessed from the external network

We need to modify the notify_url in the parameters of the construction payment request to the domain name address: for example:

request.setNotifyUrl("http://5qsems.natappfree.cc/pay/wx/notify");

Then the address corresponds to the controller interface of the payment service. We need to write the corresponding notify controller interface, refer to the document applet payment notification: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_5_5.shtml. According to the document, WeChat uses the specified notify__url to notify the payment result. The payment result notification is a POST method to access the notification url set by the merchant. The notification data is transmitted through the request body (BODY) in JSON format, and the notification data includes encryption. Details of the payment results for . We need to perform signature verification on the result and decrypt the parameters before performing business processing.

For the result response, the reception is successful: the HTTP response status code needs to return 200 or 204, and there is no need to return a response message. Failed to receive: The HTTP response status code needs to return 5XX or 4XX, and a response message needs to be returned at the same time. The format is as follows:

{
    
      
    "code": "FAIL",
    "message": "失败"
}

For payment result notification processing, you can refer to the official case: https://github.com/wechatpay-apiv3/wechatpay-java, find the callback notification signature verification and decryption part: First
, you need to create a public HTTP on your server Endpoint that accepts callback notifications from WeChat Pay. When receiving the callback notification, use NotificationParser in notification to parse the callback notification. Specific steps are as follows:

  1. Use the callback to notify the requested data and construct the RequestParam.
    ● HTTP header Wechatpay-Signature
    ● HTTP header Wechatpay-Nonce
    ● HTTP header Wechatpay-Timestamp
    ● HTTP header Wechatpay-Serial
    ● HTTP header Wechatpay-Signature-Type
    ● HTTP request body. Remember to use the original message instead of the serialized string of the JSON object to avoid inconsistency between the body of the signature verification and the original text.
  2. Initialize RSAAutoCertificateConfig. The WeChat payment platform certificate is provided by the automatic update platform capability of the SDK, and a local certificate can also be used.
  3. Initialize NotificationParser.
  4. Call NotificationParser.parse() to verify the signature, decrypt and convert the JSON into a specific notification callback object.

According to the official case, we write our own notify interface code, as follows:
● @RequestHeader Map<String, String> headers: Inject the request header
● HttpServletRequest: Obtain the body through the request object

//支付回调
@PostMapping("/wx/notify")
public WxPayNotifyResult notifyHandler(@RequestHeader Map<String, String> headers,
                                       HttpServletRequest request,
                                       HttpServletResponse response){
    
    
    try{
    
    
    	//1.拿到body中的内容
        BufferedReader reader = request.getReader();
        StringBuilder stringBuilder = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
    
    
            stringBuilder.append(line);
        }
        String body = stringBuilder.toString();
        log.info("支付结果通知 {}",body);
        //2.调用微信支付结果处理逻辑
        wxPayService.notifyHandler(body,headers);

        //3.响应码:200代表接受成功,5xx代表代表接受失败
        response.setStatus(HttpServletResponse.SC_OK);
        return WxPayNotifyResult.builder().code("SUCCESS").message("成功").build();
    }catch (Exception e){
    
    
        e.printStackTrace();
        //响应码:200代表接受成功,5xx代表代表接受失败
        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        return WxPayNotifyResult.builder().code("FAIL").message("失败").build();
    }

}

The following is the code logic of verification and parameter decryption written according to the official case.
Transaction: It is the decrypted payment result parameters, including payment status, order number, payment amount, etc.

public Transaction notify2Transaction(String body, Map<String, String> headers) {
    
    
    	
    //从请求头拿到相关参数
    String nonce = headers.get("wechatpay-nonce");
    String signature = headers.get("wechatpay-signature");
    String timestamp = headers.get("wechatpay-timestamp");
    String signaturetype = headers.get("wechatpay-signature-type");
    String  serial = headers.get("wechatpay-serial");

    //构建请求参数对象
    RequestParam requestParam = new RequestParam.Builder()
            .serialNumber(serial)
            .nonce(nonce)
            .signature(signature)
            .timestamp(timestamp)
            .signType(signaturetype)
            .body(body)
            .build();

    // 初始化 NotificationParser , 这里的config是RSAAutoCertificateConfig
    NotificationParser parser = new NotificationParser(config);

    // 以支付通知回调为例,验签、解密并转换成 Transaction
        return parser.parse(requestParam, Transaction.class);

    }

The rest is to process the corresponding business results according to the Transaction.

The article is over, I hope it can help you

Guess you like

Origin blog.csdn.net/u014494148/article/details/131875922