WeChat payment problem

Now, more and more companies choose to take advantage of WeChat to develop their own platforms. Not long after I started working, I was also told that I needed to connect with WeChat payment. Originally thought that such a connection should not be too difficult to follow the documentation, but later, I found out that I was too naive. Here, leave a mark and talk about the problems I encountered with WeChat Pay. 1. About WeChat payment Let’s talk about WeChat payment first. With the boom of WeChat, WeChat payment has also taken up a large area in third-party payment, and more and more companies have integrated WeChat payment on their own apps or websites. From the official website of WeChat Pay https://pay.weixin.qq.com/index.php/home/login?return_url=/, it can be seen that WeChat Pay is mainly divided into four parts, official account payment, APP payment, scanning code Payment (website), card payment. At work, I came into contact with the first three and encountered all kinds of problems. 2. About official documents For developers, it is especially important to read the official documents for this kind of third-party payment. Developers can find the official documents corresponding to different payment modules through the official website. However, please note that this document needs to be improved. If you follow the document completely, your function may not be realized. 3. WeChat payment process  




    The process of WeChat payment is also shown on the official website of WeChat payment. To be more generalized here, in fact, WeChat payment needs a client that integrates WeChat SDK. The customer first browses through the client to complete the order, and then the background first performs the business operation. The system generates an order. After the order is generated, the business system requests the WeChat server to place the order uniformly. After the unified order is placed, WeChat returns relevant information, and the background can form the corresponding payment QR code or encapsulate the information needed to activate WeChat payment. Next, users only need to scan or click to confirm the payment, and then they can call out WeChat payment. After the payment is successful, WeChat will send information to the user, and will also send the corresponding callback information to the address specified by the business system to inform WeChat of the payment result. At the same time, WeChat payment information can also be confirmed by directly requesting WeChat payment in the background. 4. WeChat payment related First of all, WeChat payment has the most important process, which is to place an order in a unified way. Simply put, the developer needs to send the order information in the business system to WeChat, so that the WeChat background can form a payment on WeChat. Order. When requesting to WeChat, the transmitted data is in xml format. WeChat requires that the data transmitted by xml needs to be encrypted once, and then the encrypted string is appended to xml and transmitted to the server side. The order can only be placed after the server side verification is passed. operate. The specific algorithm description address https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3 The following is an encryption algorithm based on java:

view sourceprint?
01.1 /**
02.2 * 微信支付加密工具,需要加入key
03.3 */
04.4 public static String signature(Map<String, String> map, String key) {
05.5 Set<String> keySet = map.keySet();
06.6 String[] str = new String[map.size()];
07.7 StringBuilder tmp = new StringBuilder();
08.8 // 进行字典排序
09.9 str = keySet.toArray(str);
10.10 Arrays.sort(str);
11.11 for (int i = 0; i < str.length; i++) {
12.12 String t = str[i] + '=' + map.get(str[i]) + '&';
13.13 tmp.append(t);
14.14 }
15.15 if (StringUtils.isNotBlank(key)) {
16.16 tmp.append('key=' + key);
17.17 }
18.18 String tosend = tmp.toString();
19.19 MessageDigest md = null;
20.20 byte[] bytes = null;
21.21 try {
22.22
23.23 md = MessageDigest.getInstance('MD5');
24.24 bytes = md.digest(tosend.getBytes('utf-8'));
25.25 } catch (Exception e) {
26.26 e.printStackTrace();
27.27 }
28.28
29.29 String singe = byteToStr(bytes);
30.30 return singe.toUpperCase();
31.31
32.32 }

     The first problem of WeChat payment is the key of data encryption. The pit is that you are not careful. WeChat payment has many keys, including the key we entered when we were bound with WeChat, and the random character key given by WeChat. Here, the key used for encryption is not in our WeChat public account. AppSecret, but the key set in the WeChat payment merchant background, the setting location is: Key setting path: WeChat merchant platform (pay.weixin.qq.com)-->Account Settings-->API Security-->Key Settings If you do not use this key, even if your algorithm is written correctly, the data will still be returned to the user with a signature error. PS: WeChat official provides a tool for verifying the accuracy of the signature. The address of the tool is https://pay.weixin.qq.com/wiki/tools/signverify/, AnyWay, as just said, if the key is not set Correct, for example, if AppSecret is used, then you will find that the encrypted string output by the tool is exactly the same as that obtained by yourself, and then when you send it to the WeChat server, it will always return an error. The second problem of WeChat payment is the post encoding problem. After assembling the data, you need to send the data to the WeChat server in the form of POST. However, the problem is that the data encapsulation of WeChat is completely correct, the key is set correctly, and the verification on the official verification tool is correct. However, WeChat always prompts that the signature is wrong. This problem occurs in the encoding of the post request. When this problem is encountered, when the data is encapsulated, Chinese is added to the xml, and then an error will be reported every time the request is made, but if the Chinese is removed, the order is successful. In the end, I found out that the encoding was not set during the original POST, and it would be fine after setting it to UTF8. However, the returned signature is wrong, and it is really difficult to troubleshoot the third problem of WeChat payment, js-sdk calls up the payment control. In this step, the payment control is activated in H5 in WeChat. It should be noted that to call up the payment control on H5, the first thing you need to do is to add a specified domain name in the background of WeChat public to allow the domain name to call up the control, otherwise, it cannot be called up. The setup tutorial is here: https://pay.weixin.qq.com/wiki/doc/api/jsapi. php?chapter=7_3 . After the setting is completed, the next step is to call it up through js. I will complain here. When I did it for the first time, I copied the official js directly and changed it, but. . . . . . . The full-width and half-width characters on the official JS are mixed, not to mention his JS, even the JS I wrote myself was not transferred in the end. . . . . Then, regarding the prompts, the Apple version is fine, the Android version of WeChat, if you can't call up the controls, it won't respond at all. . Relatively speaking, the Apple version will have a pop-up prompt, so in the later stage, whenever there is a problem, use the Apple test first to see what is wrong. The fourth problem of WeChat payment is data encapsulation on the app side. The order can be placed uniformly, so that the data is encapsulated and returned to the front end. This part still needs to be signed. It stands to reason that the same method is used in the front and the front, so it should not be a big problem. It is true that there is no big problem on the web side and scan code payment, but the problem on the app side comes. When I first started adjusting this with my Android colleagues at the company, I thought it would be done in one afternoon. However, it is not as we thought. We all use the data packaged by the official requirements. After I placed the order in the background, I gave it to Android. As a result, Android could not call the payment control, and it always returned a result of -1. This result can be said a little. Useless. The Android side has been adjusted for a long time at the same time, and no solution has been found. It is worth mentioning that the official Demo provided by it can call up the result interface, but it cannot call up the payment controls. Moreover, his java files, utf-8 and GBK encoding are mixed together. Finally, let's talk about why the app can't call up the payment controls. The fourth problem of WeChat payment is data encapsulation on the app side. The order can be placed uniformly, so that the data is encapsulated and returned to the front end. This part still needs to be signed. It stands to reason that the same method is used in the front and the front, so it should not be a big problem. It is true that there is no big problem on the web side and scan code payment, but the problem on the app side comes. When I first started adjusting this with my Android colleagues at the company, I thought it would be done in one afternoon. However, it is not as we thought. We all use the data packaged by the official requirements. After I placed the order in the background, I gave it to Android. As a result, Android could not call the payment control, and it always returned a result of -1. This result can be said a little. Useless. The Android side has been adjusted for a long time at the same time, and no solution has been found. It is worth mentioning that the official Demo provided by it can call up the result interface, but it cannot call up the payment controls. Moreover, his java files, utf-8 and GBK encoding are mixed together. Finally, let's talk about why the app can't call up the payment controls. The fourth problem of WeChat payment is data encapsulation on the app side. The order can be placed uniformly, so that the data is encapsulated and returned to the front end. This part still needs to be signed. It stands to reason that the same method is used in the front and the front, so it should not be a big problem. It is true that there is no big problem on the web side and scan code payment, but the problem on the app side comes. When I first started adjusting this with my Android colleagues at the company, I thought it would be done in one afternoon. However, it is not as we thought. We all use the data packaged by the official requirements. After I placed the order in the background, I gave it to Android. As a result, Android could not call the payment control, and it always returned a result of -1. This result can be said a little. Useless. The Android side has been adjusted for a long time at the same time, and no solution has been found. It is worth mentioning that the official Demo provided by it can call up the result interface, but it cannot call up the payment controls. Moreover, his java files, utf-8 and GBK encoding are mixed together. Finally, let's talk about why the app can't call up the payment controls.


 figure 1

view sourceprint?
01.1 //网页调起的时候
02.2 String time = Long.toString(System.currentTimeMillis());
03.3 back.put('appId', mchappid);
04.4 back.put('timeStamp', time);
05.5 back.put('nonceStr', '5K8264ILTKCH16CQ2502SI8ZNMTM67VS');
06.6 back.put('package', 'prepay_id=' + order.getPrepay_id());
07.7 back.put('signType', 'MD5');
08.8 String sign2 = SignatureUtils.signature(back, wx_key);
09.9
10.10 JSONObject jsonObject = new JSONObject();
11.11 jsonObject.put('appId', mchappid);
12.12 jsonObject.put('timeStamp', time);
13.13 jsonObject.put('nonceStr', '5K8264ILTKCH16CQ2502SI8ZNMTM67VS');
14.14 jsonObject.put('package', 'prepay_id=' + order.getPrepay_id());
15.15 jsonObject.put('signType', 'MD5');
16.16 jsonObject.put('paySign', sign2);
17.17
18.18 result .put('status', 'success');
19.19 result.put('msg', 'successful order');
20.20 result.put('obj', jsonObject);
21.21 return result;
view sourceprint?
01.1 // When calling up the APP, please note that the camel case method cannot be used on the Android side, and all keys must be lowercase.
02.2 String time = Long.toString(System.currentTimeMillis());
03.3 back.put('appid', app_mchappid);
04.4 back.put('timestamp', time);
05.5 back.put('partnerid', app_mchid);
06.6 back.put('noncestr', ' 5K8264ILTKCH16CQ2502SI8ZNMTM67VS');
07.7 back.put('prepayid', order.getPrepay_id());
08.8 back.put('package', 'Sign=WXPay');
09.9 String sign2 = SignatureUtils.signature(back, wx_key);
10.10
11.11 JSONObject jsonObject = new JSONObject();
12.12 jsonObject.put('appid', app_mchappid);
13.13 jsonObject.put('timestamp', time);
14.14 jsonObject.put('partnerid', app_mchid);
15.15 jsonObject.put('noncestr', '5K8264ILTKCH16CQ2502SI8ZNMTM67VS');
16.16 jsonObject.put('prepayid', order.getPrepay_id());
17.17 //jsonObject.put('package', 'Sign=WXPay');
18.18 jsonObject.put('sign', sign2);
19.19 result.put('status', 'success');
20.20 result.put('msg', 'Order successfully');
21.21 result.put('obj', jsonObject);
22.22 return result;
As shown in the figure, Figure 1 is the sample code for Android to call up the payment control in the official WeChat document, and the next is the encryption algorithm when the web side calls up the payment control, Finally, it is the code for data encapsulation when returning to the APP data after solving the problem. The problem is that its data encapsulation does not use the camel case method as mentioned on the official website. When the app is used, all characters need to be lowercase,,,lowercase,,,,,,,,. In addition, the official packageValue is wrong, and the package is used because of these errors, the encrypted data is wrong, so the app side cannot call the payment control. Here's a moment of silence for my colleague who was transferred to collapse.
  The problems encountered so far are roughly the same as above, take notes, and hope to be useful to friends who are also developers. Finally, attach a java-based WeChat payment background demo on github https://github.com/Seanid/wechatPay

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325941478&siteId=291194637