The Way to Fill the Pit with Wechat Small Program Service Provider Model

The Way to Fill the Pit with Wechat Small Program Service Provider Model

Having read the posts of this predecessor, I have come out of the deep pit and added a few easy mistakes by the way: https://blog.csdn.net/qq_18881987/article/details/94428628.
This post discusses the unified backstage order and secondary signature. As for the api on the small program side, the backstage parameter transfer is basically no big problem.
Firstly, download the official sdk of Hangdad's Weixin and import it into the program as follows:

Next, modify the verification method of wxpay class in sdk, and change it to md5 verification. Hangdad's HMACSHA256 has been reporting signature errors.



Next, look at the official documents of Wechat.
https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_sl_api.php?chapter=9_1
Explain each parameter one by one
data.put("appid", Service Util. AppID); // Appid of the public number of the service provider
data.put("mch_id", ServiceUtil.MchID); // Service Provider Business Number (allocated by Wechat Payment Platform)
data.put("sub_mch_id", ServiceUtil.sub_mch_id); // Special Merchant Business Number (Distributed by Wechat Payment Platform)
data.put("sub_appid", ServiceUtil.sub_appid); // Appid of the special merchant applet
data.put("nonce_str", nonce_str); // Random String
data.put("body", body); // Fill in your own type of payment for the order I wrote here
data.put("out_trade_no", serno);//own order number
data.put("total_fee", price); // price
data.put("spbill_create_ip", spbill_create_ip);//address
data.put("notify_url", "127.0.0.1"); //callback address
data.put("trade_type", "JSAPI"); //authentication
data.put("sub_openid", openId); // This parameter I'll haw.
data.put("sign", PayUtil.createSign(data,nonce_str)); signature
data.put("sign_type", "MD5"); signature verification method

sub_openid

After two hours of continuous testing, this parameter is... openid... I read some posts from my predecessors and said that this should be re-passed by wx before payment. login method acquisition. I got the same results here. No matter put it directly in the parameters, we find that it can pass...
Paste me the way to get this parameter.

package com.hsdsoft.wx;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;

import com.hdsoft.util.ServiceUtil;
import com.hdsoft.util.StringUtil;

public class WeChatGetOpenid {
	public static String interfaceUtil(String path,String data) {
    	String openId="";
        try {
            URL url = new URL(path);
            //Open the connection between url and url
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            PrintWriter out = null;
            //Request mode
//          conn.setRequestMethod("POST");
//           // Setting Common Request Properties
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)"); 
            //Set whether to output to httpUrlConnection, whether to read from httpUrlConnection, and whether to send a post request must set these two
            //The most common Http requests are get and post. Get requests can get static pages, or they can put parameters behind URL strings and pass them to servlet s.
            //The difference between post and get is that the parameters of post are not placed in the URL string, but in the body of the http request.
            conn.setDoOutput(true);
            conn.setDoInput(true);
            //Get the output stream corresponding to the URLConnection object
            out = new PrintWriter(conn.getOutputStream());
            //Send request parameters, that is, data
            out.print(data);
            //Buffer data
            out.flush();
            //Get the input stream corresponding to the URLConnection object
            InputStream is = conn.getInputStream();
            //Constructing a character stream cache
            BufferedReader br = new BufferedReader(new InputStreamReader(is));
            String str = "";
            while ((str = br.readLine()) != null) {
            	openId=str;
              
            }
            //Closed flow
            is.close();
            //disconnect, preferably written, when the underlying tcp socket link is idle. If it is being used by other threads, it will not be cut off.
            //Fixed multi-threading, if not disconnected, links will increase until no information can be sent or received. It's normal to write disconnect.
            conn.disconnect();
         
        } catch (Exception e) {
            e.printStackTrace();
        }
        return openId;
    }

	
	 public static String GetOpenID(String appid,String appsecret,String Code) {
	
	    	//Temporary login credentials
	    	String URL = "https://api.weixin.qq.com/sns/jscode2session?appid="+appid+"&secret="+appsecret+"&js_code="+Code+"&grant_type=authorization_code";
	    	
	    	String openId=interfaceUtil(URL, "");
	    
	    	return openId;
	 }
	 public static String getSubOpenId() {
		 
		 return null;
	 }


}


Looking at the explanations in the official documents, I just want to talk about his uncle.
Let's talk about it here. All keys used are keys in the service provider's Wechat payment platform.
If your signature algorithm and key are all right, the unified order should be completed at this moment.

The idea here is that in the Wechat platform (Wechat Payment Platform) of the special merchant, the appid of the special merchant applet must be added to the appid authorization.

Service Provider Configuration: Service Provider Function

Return map set to applet after unifying order

   Map<String, String> rMap = wxpay.unifiedOrder(data);
                System.out.println("Unified single interface return: " + rMap);
                String return_code = (String) rMap.get("return_code");
                String result_code = (String) rMap.get("result_code");
                String nonceStr = WXPayUtil.generateNonceStr();
                resultMap.put("nonceStr", nonceStr);
                Long timeStamp = System.currentTimeMillis() / 1000;
                if ("SUCCESS".equals(return_code) && return_code.equals(result_code)) {
                    String prepayid = rMap.get("prepay_id");
                    System.out.println("prepayid=   "+prepayid);
                    resultMap.put("package", "prepay_id="+prepayid);
                    resultMap.put("signType", "MD5");
                    //The returned timestamp is converted to a string, otherwise the widget will report a signature error if it calls the wx.requestPayment method.
                    resultMap.put("timeStamp", timeStamp + "");
                    //Sign again, which is used to call the wx.requesetPayment method on the widget side
                    resultMap.put("appId",ServiceUtil.sub_appid);            
                    Map resultMap1=new HashMap();
                    resultMap1.put("appId",ServiceUtil.sub_appid);
                    resultMap1.put("timeStamp",timeStamp + "");
                    resultMap1.put("nonceStr",nonceStr);
                    resultMap1.put("package","prepay_id="+prepayid);
                    resultMap1.put("signType","MD5");
                    String sign = WXPayUtil.generateSignature(resultMap1,ServiceUtil.service_key);
                    resultMap.put("paySign", sign);
                    return resultMap;

Note that the appid given here is the appid of the current applet, which is the sub_appid I wrote in the parameter description earlier.
key is a service provider. Don't make a mistake.

This is the end of the road to fill the pit.

Keywords: Java SDK PHP Windows

Added by Pegasys on Wed, 11 Sep 2019 07:24:04 +0300