微信小程序 支付簡(jiǎn)單實(shí)例及注意事項(xiàng)
微信小程序 支付
微信小程序的支付和微信公眾號(hào)的支付是類似的,對(duì)比起來(lái)還比公眾號(hào)支付簡(jiǎn)單了一些,我們只需要調(diào)用微信的統(tǒng)一下單接口獲取prepay_id之后我們?cè)谡{(diào)用微信的支付即可。
今天我們來(lái)封裝一般node的支付接口?。。?/p>
首先調(diào)用統(tǒng)一下單接口我們需要知道一些信息
var bookingNo = 'davdian' + this.createNonceStr() + this.createTimeStamp()
var deferred = Q.defer()
var appid = config.appId
var nonce_str = this.createNonceStr()
var timeStamp = this.createTimeStamp()
var url = "https://api.mch.weixin.qq.com/pay/unifiedorder"
var formData = "<xml>"
formData += "<appid>" + appid + "</appid>" //appid
formData += "<attach>" + attach + "</attach>" //附加數(shù)據(jù)
formData += "<body>" + body + "</body>"
formData += "<mch_id>" + mch_id + "</mch_id>" //商戶號(hào)
formData += "<nonce_str>" + nonce_str + "</nonce_str>" //隨機(jī)字符串,不長(zhǎng)于32位。
formData += "<notify_url>" + notify_url + "</notify_url>"
formData += "<openid>" + openid + "</openid>"
formData += "<out_trade_no>" + bookingNo + "</out_trade_no>"
formData += "<spbill_create_ip>61.50.221.43</spbill_create_ip>"
formData += "<total_fee>" + total_fee + "</total_fee>"
formData += "<trade_type>JSAPI</trade_type>"
formData += "<sign>" + this.paysignjsapi(appid, attach, body, mch_id, nonce_str, notify_url, openid, bookingNo, '61.50.221.43', total_fee, 'JSAPI') + "</sign>"
formData += "</xml>"
var self = this
request({
url: url,
method: 'POST',
body: formData
}, function(err, response, body) {
if (!err && response.statusCode == 200) {
var prepay_id = self.getXMLNodeValue('prepay_id', body.toString("utf-8"))
var tmp = prepay_id.split('[')
var tmp1 = tmp[2].split(']')
//簽名
var _paySignjs = self.paysignjs(appid, nonce_str, 'prepay_id=' + tmp1[0], 'MD5', timeStamp)
var args = {
appId: appid,
timeStamp: timeStamp,
nonceStr: nonce_str,
signType: "MD5",
package: tmp1[0],
paySign: _paySignjs
}
deferred.resolve(args)
} else {
console.log(body)
}
})
return deferred.promise
這個(gè)是一個(gè)統(tǒng)一下單接口的代碼,我們需要appid小程序公眾號(hào)id,mch_id商戶號(hào)id,openid小程序的唯一標(biāo)實(shí),key支付用的密碼,剩下的參數(shù)都是訂單的信息和價(jià)格之類的,本人require進(jìn)q模塊使用promise,這個(gè)因人而異,可以根據(jù)自己需要來(lái)。我們需要請(qǐng)求https://api.mch.weixin.qq.com/pay/unifiedorder接口
注意:這里我們傳遞的formdata是一個(gè)xml而不是json
然后我們需要簽名方法,這里我們需要封裝兩個(gè)方法,一個(gè)是簽名方法調(diào)用統(tǒng)一下單接口會(huì)用到,另一個(gè)是調(diào)用小程序支付用到
統(tǒng)一下單接口sign:
var ret = {
appid: appid,
attach: attach,
body: body,
mch_id: mch_id,
nonce_str: nonce_str,
notify_url: notify_url,
openid: openid,
out_trade_no: out_trade_no,
spbill_create_ip: spbill_create_ip,
total_fee: total_fee,
trade_type: trade_type
}
var string = this.raw(ret)
string = string + '&key=' + key
var crypto = require('crypto')
var sign = crypto.createHash('md5').update(string, 'utf8').digest('hex')
return sign.toUpperCase()
支付sign:
var ret = {
appId: appid,
nonceStr: nonceStr,
package: package,
signType: signType,
timeStamp: timeStamp
}
var string = this.raw(ret)
string = string + '&key=' + key
var sign = crypto.createHash('md5').update(string, 'utf8').digest('hex')
return sign.toUpperCase()
注意加密的時(shí)候我們獲取的是string而不是一個(gè)json,所以我們需要吧json轉(zhuǎn)換成string,代碼如下:
var keys = Object.keys(args)
keys = keys.sort()
var newArgs = {}
keys.forEach(function(key) {
newArgs[key] = args[key]
})
var string = ''
for (var k in newArgs) {
string += '&' + k + '=' + newArgs[k]
}
string = string.substr(1)
return string
統(tǒng)一下單接口返回的是帶有prepay_id的xml,所以我們需要一個(gè)方法進(jìn)行解析,代碼如下:
var tmp = xml.split("<" + node_name + ">")
var _tmp = tmp[1].split("</" + node_name + ">")
return _tmp[0]
最后我們只需要把這些連接到一起就是可以獲取所有微信支付所需參數(shù),代碼如下:
//微信小程序支付封裝,暫支持md5加密,不支持sha1
/**
***create order by jianchep 2016/11/22
**/
var config = require('../config/weapp.js')
var Q = require("q")
var request = require("request")
var crypto = require('crypto')
var ejs = require('ejs')
var fs = require('fs')
var key = config.key
module.exports = {
// 獲取prepay_id
getXMLNodeValue: function(node_name, xml) {
var tmp = xml.split("<" + node_name + ">")
var _tmp = tmp[1].split("</" + node_name + ">")
return _tmp[0]
},
// object-->string
raw: function(args) {
var keys = Object.keys(args)
keys = keys.sort()
var newArgs = {}
keys.forEach(function(key) {
newArgs[key] = args[key]
})
var string = ''
for (var k in newArgs) {
string += '&' + k + '=' + newArgs[k]
}
string = string.substr(1)
return string
},
// 隨機(jī)字符串產(chǎn)生函數(shù)
createNonceStr: function() {
return Math.random().toString(36).substr(2, 15)
},
// 時(shí)間戳產(chǎn)生函數(shù)
createTimeStamp: function() {
return parseInt(new Date().getTime() / 1000) + ''
},
// 支付md5加密獲取sign
paysignjs: function(appid, nonceStr, package, signType, timeStamp) {
var ret = {
appId: appid,
nonceStr: nonceStr,
package: package,
signType: signType,
timeStamp: timeStamp
}
var string = this.raw(ret)
string = string + '&key=' + key
var sign = crypto.createHash('md5').update(string, 'utf8').digest('hex')
return sign.toUpperCase()
},
// 統(tǒng)一下單接口加密獲取sign
paysignjsapi: function(appid, attach, body, mch_id, nonce_str, notify_url, openid, out_trade_no, spbill_create_ip, total_fee, trade_type) {
var ret = {
appid: appid,
attach: attach,
body: body,
mch_id: mch_id,
nonce_str: nonce_str,
notify_url: notify_url,
openid: openid,
out_trade_no: out_trade_no,
spbill_create_ip: spbill_create_ip,
total_fee: total_fee,
trade_type: trade_type
}
var string = this.raw(ret)
string = string + '&key=' + key
var crypto = require('crypto')
var sign = crypto.createHash('md5').update(string, 'utf8').digest('hex')
return sign.toUpperCase()
},
// 下單接口
order: function(attach, body, mch_id, openid, total_fee, notify_url) {
var bookingNo = 'davdian' + this.createNonceStr() + this.createTimeStamp()
var deferred = Q.defer()
var appid = config.appId
var nonce_str = this.createNonceStr()
var timeStamp = this.createTimeStamp()
var url = "https://api.mch.weixin.qq.com/pay/unifiedorder"
var formData = "<xml>"
formData += "<appid>" + appid + "</appid>" //appid
formData += "<attach>" + attach + "</attach>" //附加數(shù)據(jù)
formData += "<body>" + body + "</body>"
formData += "<mch_id>" + mch_id + "</mch_id>" //商戶號(hào)
formData += "<nonce_str>" + nonce_str + "</nonce_str>" //隨機(jī)字符串,不長(zhǎng)于32位。
formData += "<notify_url>" + notify_url + "</notify_url>"
formData += "<openid>" + openid + "</openid>"
formData += "<out_trade_no>" + bookingNo + "</out_trade_no>"
formData += "<spbill_create_ip>61.50.221.43</spbill_create_ip>"
formData += "<total_fee>" + total_fee + "</total_fee>"
formData += "<trade_type>JSAPI</trade_type>"
formData += "<sign>" + this.paysignjsapi(appid, attach, body, mch_id, nonce_str, notify_url, openid, bookingNo, '61.50.221.43', total_fee, 'JSAPI') + "</sign>"
formData += "</xml>"
var self = this
request({
url: url,
method: 'POST',
body: formData
}, function(err, response, body) {
if (!err && response.statusCode == 200) {
var prepay_id = self.getXMLNodeValue('prepay_id', body.toString("utf-8"))
var tmp = prepay_id.split('[')
var tmp1 = tmp[2].split(']')
//簽名
var _paySignjs = self.paysignjs(appid, nonce_str, 'prepay_id=' + tmp1[0], 'MD5', timeStamp)
var args = {
appId: appid,
timeStamp: timeStamp,
nonceStr: nonce_str,
signType: "MD5",
package: tmp1[0],
paySign: _paySignjs
}
deferred.resolve(args)
} else {
console.log(body)
}
})
return deferred.promise
}
}
之后我們封裝下單接口:
unifiedorder: function (req, res) {
var body = "測(cè)試支付"
var openid = "openid"
var total_fee = 1
var notify_url = "http://localhost/notify"
var mch_id = config.shopId
var attach = "測(cè)試"
wxpay.order(attach, body, mch_id, openid, total_fee, notify_url)
.then(function(data){
console.log('data--->', data, 123123)
res.json(data)
})
},
然后我們只需要在小程序里面調(diào)用這個(gè)接口,就會(huì)獲取到所有的支付需要信息,再掉微信支付即可。
這里說(shuō)幾個(gè)小程序支付的坑:
1.統(tǒng)一下單接口是xml(這個(gè)不只是小程序,公眾號(hào)也是),返回值也是xml格式需要自己獲取prepay_id,
2.簽名算法要帶上key,最后要轉(zhuǎn)換成大些
3.微信支付的sign算法也要帶上appid(這個(gè)不科學(xué),深坑)
4.簽名算法一定不要用json拼接key
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站 的支持!
相關(guān)文章
JavaScript的模塊化開(kāi)發(fā)框架Sea.js上手指南
Sea.js的目的是追求簡(jiǎn)單的代碼書(shū)寫(xiě)和組織方式,Sea.js并沒(méi)有過(guò)多功能而是主要對(duì)前端程序的部署結(jié)構(gòu)作出約束,下面我們就來(lái)看一下JavaScript的模塊化開(kāi)發(fā)框架Sea.js上手指南:2016-05-05
JS中 querySelector 與 getElementById 方法區(qū)別
這篇文章主要介紹了JavaScript中 querySelector 與 getElementById 方法與區(qū)別,圍繞querySelector 與 getElementById 的相關(guān)資料展開(kāi)文章內(nèi)容,需要的朋友可以參考一下2021-10-10
微信小程序 網(wǎng)絡(luò)API 上傳、下載詳解
這篇文章主要介紹了微信小程序 網(wǎng)絡(luò)API 上傳、下載詳解的相關(guān)資料,需要的朋友可以參考下2016-11-11
JS實(shí)現(xiàn)大數(shù)相加大數(shù)相乘示例詳解
這篇文章主要為大家介紹了JS實(shí)現(xiàn)大數(shù)相加大數(shù)相乘示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08

