WeChat payment--the unified payment interface was pitted

       Let’s write something today, let’s write WeChat payment. My brother was tossed by the WeChat payment interface.

       About May 22, we started to develop WeChat, and it has been a month now. The boss asked to take out the WeChat membership system in 3 months, which felt a little overhang. I was stuck by WeChat payment in the past two days.

        In order to avoid detours for children's shoes, we hereby announce to the world, which children's shoes WeChat payment has encountered a problem, even if you leave a message. Let's talk about the process of being cheated.

        1. To use WeChat payment, the premise is that the WeChat payment function (nonsense!) is activated. After activation, you can get the merchant id and merchant api key. With these two necessary things, you can call the WeChat unified payment interface. Get the WeChat prepaid prepayid. With the prepayid, you can call jsapi in the web page.

        2. The point is how to get the prepayid? It's very simple, just call the post request to the https://api.mch.weixin.qq.com/pay/unifiedorder address, it's very simple. It is really simple at first glance, but there are several pits hidden in it. I searched the Internet and found a lot of pits, so I will show the two pits I encountered.

        3. To get the peipayid, you need to pass a set of xml data. Corresponding to the java siege lion, you usually write a model, fill in the data, then convert the model to an xml string, and then send it along with the post request.

        4. In a set of xml data, there is a signature, and people who meet it for the first time will definitely be confused. How to sign this signature, you need to process all the data you want to pass to the server. Remember: it is all the data to be passed to the server (Tencent), except for the sign data. The sign is also sent to the server.

        Generally it looks like this:

               private String appid;// Public account ID
               private String mch_id;// Merchant ID
               private String device_info;// Device ID
               private String nonce_str;// Random String
               private String sign;// Signature
               private String body;// Product description
               private String detail;// product details
               private String attach;// additional data

               ... ...

          Sort these fields first, lexicographically, and directly call Arrays.sort(String[]); this is sorted, and then spliced ​​into a string, appid=123&mch_id=123... and so on, and finally After adding the commodity api key key=123. After finishing, perform md5 conversion, here, I was tricked.

          The reason is very simple, the md5 after my conversion is sometimes 29 bits instead of 32 bits, this is because when I convert the md5 binary byte stream to a string, I do not deal with the value less than 16 in the byte. That is, you should add 0 in front of the value less than 16. If you don't add it, the number of digits in the result of md5 is wrong.

         5. The next pit I encountered was also very simple, but it took me a long time. I converted the created model to xml using the following code: XStream xStream = new XStream();
        xStream.alias("xml", object.getClass());

         The conversion result is as follows:

         

 <appid>xxxxxxxxxxxxx</appid>
  <mch__id>xxxxxxxxxxxx</mch__id>
  <nonce__str>1add1a30ac87aa2db72f57a2375d8fec</nonce__str>
  <sign>C939DCA5210FEDF5C9651412C966EA01</sign>
  <body>test</body>
  <out__trade__no>1ad41a30ac87aa2db72f57a2375d8fec</out__trade__no>
  <total__fee>1</total__fee>
  <spbill__create__ip>xxx.xx.xx.xx</spbill__create__ip>
  <notify__url>xxxxxxxxxxxxxxxx</notify__url>
  <trade__type>JSAPI</trade__type>
  <openid>xxxxxxxxxxx</openid>
</xml>
     At first glance, this looks fine, but it should look like this:
     <xml><appid><![CDATA[xxxxxxxxxxx]]></appid><mch_id><![CDATA[xxxxxxxxxx]]></mch_id><nonce_str><![CDATA[1add1a30ac87aa2db72f57a2375d8fec]]></nonce_str></xml>
       That is to say: as long as it is a string, it must be wrapped with <![CDATA[ ]]>, the integer data does not need to be wrapped, there is no other type of data, hahahaha.
        It's late, it's time to go to bed, good night to all siege lions
 
       Follow-up: Many people came to me to ask about WeChat payment, but it took too long, and I can't remember many details. I hereby post the code, hoping to help you!
 
<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport"
    content="width=device-width, initial-scale=1.0,user-scalable=true">
<title>Bootstrap 模板</title>
<script src="../resource/jquery/jquery-2.1.1.min.js"></script>
<script type="text/javascript"
    src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
<script type="text/javascript">
 
 
 
    wx.config({
    debug: true, // Turn on the debug mode, the return values ​​of all the apis called will be alerted on the client side, if you want to view the incoming parameters, you can open it on the pc side, and the parameter information will be printed out through the log, only on the pc side will print.
    appId: '${config_appId}', // Required, the unique identifier of the
    official account timestamp: parseInt('${config_timestamp}'), // Required, the timestamp for generating the signature
    nonceStr: '${config_nonceStr}', // Required, generate a random string of
    signature signature: '${config_signature}',// Required, signature, see Appendix 1
    jsApiList: ['onMenuShareTimeline','chooseWXPay']
});
 
 
 
    wx.ready(function() {
     
      wx.chooseWXPay({
        timestamp: parseInt('${pay_timestamp}'), // Payment signature timestamp, note that all timestamp fields used in WeChat jssdk are lowercase. However, the latest version of the payment background uses the timeStamp field to generate signatures The name must be capitalized. The S character
        in it nonceStr: '${pay_nonceStr}', // The payment signature random string, not longer than 32 bits
        package: '${pay_package}',
        signType: 'MD5', // Signature method, the default is 'SHA1', to use the new version of payment, you need to pass in 'MD5'
        paySign: '${pay_paySign}', // Payment signature
        success: function (res) {
        // Payment is successful
            }
    });
}); wx.error
    (function(res){
        alert(res);
    });
    </script>
</head>
<body>
    <div>
        config parameter
        <p>appid:$ {config_appId}</p>
        <p>timestamp: ${config_timestamp}</p>
        <p>nonceStr: ${config_nonceStr}</p>
        <p>signature: ${config_signature}</p>
    </div>
 
 
    <div>
        Payment parameters
        <p>timestamp: ${pay_timestamp}</p>
        <p>nonceStr: ${pay_nonceStr}</p>
        <p>package: ${pay_package}</p>
        <p>signType: ${pay_signType}</p>
        <p>paySign: ${pay_paySign}</p>
    </div>
</body>
 
</html>

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=327019554&siteId=291194637