本文的代码已过时,请勿照抄。建议改用云支付。
本文的代码被论坛自动过滤了所有XML的标签,所以照抄是会出错的。需要代码的话,看以前的老版本:
代码前提:只需要替换两个与自己相关的参数key和mch_id
1、小程序开通微信支付成功,去公众平台(https://mp.weixin.qq.com/);
成功后可以知道自己的mch_id,即商户号。
2、去这里:商户平台(https://pay.weixin.qq.com/),获取key = API密钥,如果是退款的话,还需要下载API证书。
以下代码仅包含统一下单,以及小程序端拉起支付的代码。
小程序端:
testWxCloudPay: function () {
wx.cloud.callFunction({
name: 'getPay',
// data: {body:"body",attach:"attach",total_fee:1}, // 可传入相关参数。
success: res => {
console.log(res.result)
if (!res.result.appId) return
wx.requestPayment({
...res.result,
success: res => {
console.log(res)
}
})
}
})
},
云函数getPay:
const key = "ABC...XYZ" //换成你的商户key,32位
const mch_id = "1413092000" //换成你的商户号
//以下全部照抄即可
const cloud = require('wx-server-sdk')
const rp = require('request-promise')
const crypto = require('crypto')
cloud.init()
function getSign(args) {
let sa = []
for (let k in args) sa.push(k + '=' + args[k])
sa.push('key=' + key)
return crypto.createHash('md5').update(sa.join('&'), 'utf8').digest('hex').toUpperCase()
}
function getXml(args) {
let sa = []
for (let k in args) sa.push('<' + k + '>' + args[k] + '')
sa.push('' + getSign(args) + '')
return '' + sa.join('') + ''
}
exports.main = async(event, context) => {
const wxContext = cloud.getWXContext()
const appId = appid = wxContext.APPID
const openid = wxContext.OPENID
const attach = 'attach'
const body = 'body'
const total_fee = 1
const notify_url = "https://mysite.com/notify"
const spbill_create_ip = "118.89.40.200"
const nonceStr = nonce_str = Math.random().toString(36).substr(2, 15)
const timeStamp = parseInt(Date.now() / 1000) + ''
const out_trade_no = "otn" + nonce_str + timeStamp
const trade_type = "JSAPI"
const xmlArgs = {
appid,
openid,
attach,
body,
mch_id,
nonce_str,
notify_url,
out_trade_no,
spbill_create_ip,
total_fee,
trade_type
}
let xml = (await rp({
url: "https://api.mch.weixin.qq.com/pay/unifiedorder",
method: 'POST',
body: getXml(xmlArgs)
})).toString("utf-8")
if (xml.indexOf('prepay_id') < 0) return xml
let prepay_id = xml.split("")[0]
let payArgs = {
appId,
nonceStr,
package: ('prepay_id=' + prepay_id),
signType: 'MD5',
timeStamp
}
return {
...payArgs,
paySign: getSign(payArgs)
}
}
packge.json:
{
"name": "getPay",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "zfe",
"license": "ISC",
"dependencies": {
"wx-server-sdk": "latest",
"crypto": "^1.0.1",
"request-promise": "^4.2.2"
}
}
附:完整代码片段:如果你觉得在这上面花的时间超过一天了,就去下载代码片段吧。
getXML方法里丢了好多东西,应该是这样子:
function getXml(args) { let sa = [] for (let k in args) sa.push('<' + k + '>' + args[k] + '</' + k + '>') sa.push('<sign>' + getSign(args) + '</sign>') return '<xml>' + sa.join('') + '</xml>' }
感谢老张的代码,借助借助这套代码把QQ小程序支付用云开发搞定了
返回结果:<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[XML格式错误]]></return_msg></xml>
请问大神,如何支付成功跳转到指定页面?感谢感谢
console.log(’提交成功’,res.result)
if (!res.result.appId) return
wx.requestPayment({
...res.result,
’success’function(res){
wx.navigateTo({
url: ’/pages/l/l’
})
},
'fail'(res) {
console.log("支付失败", res)
我是这样写的,但是支付完成后没有跳转页面
let prepay_id = xml.split("")[0] 改成 let prepay_id = xml.split("<prepay_id>")[1].split("</prepay_id>")[0].split('[')[2].split(']')[0] 泪崩呀~~
老张,这套能不能实现分账指令嘞?
请问如果用HMAC-SHA256加密的话,应该怎么写,都需要改哪里?
沒sign怎可? 根本不行...
简直是太TM靠谱了. 感谢