React Native (IOS和Android) 支付寶和微信支付整合實戰(微信支付服務端篇)
阿新 • • 發佈:2019-02-05
序言:React Native無論是在社群和應用程度上,在國內外是十分廣泛和普及的。而支付寶和微信在支付模組上都有或多或少的支援,雖然沒有完整的Demo,不過在我做過一個相關整合的專案後,在此我把相關的步驟和方法總結出來和大家分享,希望能夠幫助大家少走彎路,快速整合。
微信支付——服務端整合
一、獲取你的APPID,MCH_ID以及配置的金鑰 key
微信沒有沙箱,所以在商戶平臺上,建立你的應用後,請妥善保管這三個重要的配置內容。 和支付寶類似,需要在服務端進行生籤操作,不同的是微信稍微步驟多一點,需要先獲取prepay,並且訪問和返回均為XML格式。
Android可按照官方文件 配置應用相關資訊
二、配置和編寫服務端程式碼
由於本分享以NodeJS為主,其他語言需要實現的步驟也是一樣的,可參考官方文件 具體的操作詳情以及需要注意的點如下:
1.按照微信統一下單的API,寫好訪問引數,並且進行生籤,和支付寶一樣,引數要按ASCII遞增,生籤後的簽名值要全部轉化為大寫,獲取prepay_id和相關內容。
2.注意所有進行簽名的變數名均為小寫,而簽名的sign值最後要轉化為大寫
3.注意返回至客戶端時,注意變數名的大小寫,詳情可參考react-native-wechat的github文件
// 配置相關變數 const APPID = '' //你的微信應用APPID const MCH_ID = '' //你的商戶ID const KEY = '' //設定的金鑰key const NOTIFY_URL = 'http://192.168.1.45:3000/wechat/notify_url' //設定你的回撥地址
// 根據訂單產生prepay的簽名 var prepaySign = function (order) { var ret = { appid: APPID, body: order.body, mch_id: MCH_ID, nonce_str: order.nonce_str, notify_url: NOTIFY_URL, out_trade_no: order.out_trade_no, spbill_create_ip: order.spbill_create_ip, total_fee: order.total_fee, trade_type: 'APP' }; var string = helper.raw(ret); string = string + '&key=' + KEY; var crypto = require('crypto'); var sign = crypto.createHash('md5').update(string, 'utf8').digest('hex'); return sign.toUpperCase(); }
//根據prepay的id,產生支付的簽名
var paySign = function (prepay) {
var ret = {
appid: APPID,
noncestr: prepay.nonce_str,
package: 'Sign=WXPay',
partnerid: MCH_ID,
prepayid: prepay.prepayid,
timestamp: prepay.timestamp
};
var string = helper.raw(ret);
string = string + '&key=' + KEY;
var sign = crypto.createHash('md5').update(string, 'utf8').digest('hex');
return sign.toUpperCase();
}
// 訪問微信,根據訂單資訊,獲取prepay並且生成最後的支付訂單內容
var requestPrepay = function (order) {
return new Promise((resolve, reject) => {
var url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
var formData = "<xml>";
formData += "<appid>" + APPID + "</appid>"; //appid
formData += "<body>" + order.body + "</body>";
formData += "<mch_id>" + MCH_ID + "</mch_id>"; //商戶號
formData += "<nonce_str>" + order.nonce_str + "</nonce_str>"; //隨機字串,不長於32位。
formData += "<notify_url>" + NOTIFY_URL + "</notify_url>";
formData += "<out_trade_no>" + order.out_trade_no + "</out_trade_no>";
formData += "<spbill_create_ip>" + order.spbill_create_ip + "</spbill_create_ip>";
formData += "<total_fee>" + order.total_fee + "</total_fee>";
formData += "<trade_type>APP</trade_type>";
formData += "<sign>" + prepaySign(order) + "</sign>";
formData += "</xml>";
request({
url: url,
method: 'POST',
body: formData
}, function (err, response, body) {
if (!err && response.statusCode == 200) {
helper.getXMLNodeValue(body.toString("utf-8")).then((XML_RETURN) => {
var code = XML_RETURN.return_code[0];
var msg = XML_RETURN.return_msg[0];
if (code != 'SUCCESS' || msg != 'OK') {
deferred.reject({ message: XML_RETURN.return_msg[0] })
console.log(XML_RETURN)
return;
}
var prepay_id = XML_RETURN.prepay_id[0];
//簽名
var _paySign = paySign(Object.assign({ prepayid: prepay_id }, order));
var args = {
appId: APPID,
partnerId: MCH_ID,
prepayId: prepay_id,
nonceStr: order.nonce_str,
timeStamp: order.timestamp,
package: 'Sign=WXPay',
sign: _paySign
};
resolve(args);
})
} else {
reject(err)
console.log(body);
}
});
})
}
//產生訂單
wechat.post('/pay', function (req, res) {
requestPrepay({
body: '免費贈送IPhone X',
out_trade_no: '453234533123',
nonce_str: helper.createNonceStr(),
spbill_create_ip: '192.168.1.45', //一般可以從客戶端獲取使用者IP,
total_fee: '1', //單位為分
timestamp: helper.createTimeStamp()
}).then((data) => {
res.send(data)
})
})
//回撥方法
wechat.post('/notify_url', function (req, res) {
parser.parseString(req.body, function (err, result) {
var wechatPayResult = result.xml
console.log('wechat', wechatPayResult)
var success = wechatPayResult.return_code[0] == 'SUCCESS'
res.setHeader('content-type', 'application/xml')
res.send('<xml><return_code><![CDATA[' + success ? 'SUCCESS' : 'FAIL' + ']]></return_code><return_msg><![CDATA[' + success ? 'OK' : 'FAIL' + ']]></return_msg></xml>')
})
})
至此,微信服務端的配置已經完成了,相較於支付寶的服務端配置,稍微簡單一點,因為不需要產生公鑰私鑰,但是總體步驟是差不多的。
在這裡提醒開發者們,服務端生籤是一個非常重要的部分,如果這塊出現問題,客戶端是無法正常運作的,所以請仔細認真的核對程式碼,避免出錯,減少開發週期。
注意:以上程式碼請參考原始碼觀看,有部分方法整合至其他檔案。
鳴謝:我是一名來自盛安德的Shinetecher,感謝盛安德公司及同事們對IT技術的支援,分享和熱情,讓我有時間和動力完成此博文。
聯絡:歡迎各位朋友有任何問題和建議留言至此部落格下,或者新增本人微訊號:liyijia428 進行溝通交流學習