Nodejs code scanning payment and nodejs payment
Preface
This article mainly records the problems I encountered during the code scanning payment process and provides some reference for you. I hope it will help you.
Development Environment
Preparations
Public Account-appid
Merchant ID-mch_id
Key value (a 32-bit password required by the signature algorithm, which can be generated using md5) (key setting path: merchant platform (pay.weixin.qq.com) --> account settings --> API security --> key settings)
Scan the QR code to pay for the order
The following uses Mode 2 because it is relatively simple:
Let MD5 = require ('md5'), xml2js = require ('xml2js'), url = "https://api.mch.weixin.qq.com/pay/unifiedorder", // The request address appid = 'public id ', mch_id = 'Merchant ID '; policy_url = 'callback address', out_trade_no = 'order number set by yourself ', // There will be your own order number, and our system needs to set your own order number total_amount = 'order amount ', // note that the unit is body = 'commodity simple description ', trade_type = 'native ', // transaction type, JSAPI -- public account payment, NATIVE -- NATIVE scan code payment, APP -- app payment nonce_str = moment (). format ('yyyymmddhhmmsssss '), // random string stringA = 'appid =$ {public id} & body =$ {body} & mch_id =$ {merchant id} & nonce_str =$ {nonce_str} & notify_url =$ {notify_url} & out_trade_no =$ {out_trade_no} & spbill_create_ip =$ {ctx. request. ip} & total_detail =$ {total_detail} & trade_type =$ {trade_type} ', stringSignTemp = stringA + "& key = xxxxxxxxxxxxxxx", // note: key is the key sign = MD5 (stringSignTemp) set for the merchant platform ). toUpperCase (); // Note: MD5 Signature Method
The above are some of the parameters we need
The signature generation algorithm See Official: https://pay.weixin.qq.com/wiki/doc/api/native.php? Chapter = 4_3
Spbill_create_ip is the terminal IP Address
Below we splice all the parameters into xml
Const formData = "<xml>"; formData + = "<appid>" + appid + "</appid> "; // appid formData + = "<body>" + body + "</body> "; // formData + = "<mch_id>" + mch_id + "</mch_id> "; // merchant ID formData + = "<nonce_str>" + nonce_str + "</nonce_str>"; // random string, not longer than 32-bit formData + = "<policy_url>" + policy_url + "</policy_url> "; // after the payment is successful, the server notifies the address formData + = "<out_trade_no>" + out_trade_no + "</out_trade_no> "; // Order Number formData + =" <total_fee> "+ total_fee +" </total_fee> "; // The amount formData + =" <spbill_create_ip> "+ ctx. request. ip + "</spbill_create_ip>"; // ip formData + = "<trade_type> NATIVE </trade_type>"; // NATIVE returns code_url, JSAPI does not return formData + = "<sign>" + sign + "</sign>"; formData + = "</xml> "; // The request method const resultData = yield ctx in egg is used here. curl (url, {method: 'post', content: formData, headers: {'C Ontent-type ': 'text/html',},}); // convert xml to the json format xml2js. parseString (resultData. data, function (err, json) {if (err) {new Error ("xml parsing Error")} else {var result = formMessage (json. xml); // convert to a normal json data console. log (result) // print the returned result}) var formMessage = function (result) {var message ={}; if (typeof result = 'object ') {var keys = Object. keys (result); for (var I = 0; I <keys. length; I ++) {v Ar item = result [keys [I]; var key = keys [I]; if (! (Item instanceof Array) | item. length = 0) {continue;} if (item. length = 1) {var val = item [0]; if (typeof val = 'object') {message [key] = formMessage (val );} else {message [key] = (val | ''). trim () ;}} else {message [key] = []; for (var j = 0, k = item. length; j <k; j ++) {message [key]. push (formMessage (itemp [j]) ;}}} return message ;}
The egg request method is used above. The native node can use the request
var request = require('request'); request({ url: url, method: "POST", body: formData }, function(error, response, body) { if (!error && response.statusCode == 200) { } });
If the request is successful, an xml file will be returned, and then we will parse it into json format. There will be a code_url and out_trade_no, and we need to return the two to the front end, then, scan the QR code to complete the payment.
Monitor whether the payment is successful
After the above operations are completed, we need to know whether the user has completed the payment, because the user will stay on this page, we need to notify the user that the payment is successful after the user has paid.
First, we will generate a QR code when the user initiates the payment so that the user can complete the QR code payment. What we need to do is to open a timer and send a request at intervals. At this time, we need to write an interface for querying orders in the node background. Before that, we got out_trade_no, which is the order number in our system. We sent this data to the interface for querying orders in the background, then, the query interface address that will be requested by the backend after receiving the token.
Callback address
This is a very important part. Most of the operations can be completed on the page, but in some special cases, for example, if the user's computer cannot send the request through a network disconnection, but the mobile phone has paid, this will cause us to fail to record the user's payment information. The callback address is very important at this time.
Set the callback address
Merchant center-> product center-> Development Configuration-> scan code payment
What we need to do afterwards is that the backend uses post to receive the asynchronous callback information sent, which is also in xml format. Note that if xml cannot be received, empty data may be obtained.
Note that, while saving the user's payment information, we must first check whether the order is paid to avoid repeated operations and may insert multiple records.
Summary
There are still some payment traps. If this is your first exploration, the following lists the points that need attention.
- The signature algorithm must be correctly written, otherwise it will not succeed. It must be spliced correctly.
- The returned data is in xml format. We need to convert the data to json through the plug-in to facilitate data acquisition.
- The returned code_url generates a QR code for the front-end, and then requires a timer to check whether the order has been paid, and finally notifies the user of the result.
- The callback address is very important. We need to post the returned callback information and save the information. However, before saving the user's payment information, we need to know whether the order has been saved, to avoid repeated addition. In addition, xml data is returned, and the backend must be able to receive the data. Normally, the data cannot be received and additional settings are required.