微信小程序:用户点击跳转付款码界面
最近工作中遇到一个需求是用户点击活动领取的微信代金券后跳转到微信付款码界面,于是乎,一顿翻文档,说实话,微信小程序的文档翻起来真的…一言难尽。
很快找到了一个wx.requestPayment(Object object)
,可是仔细一看,这个接口是发起支付的,会弹出付款界面,就是让你输入密码那个,继续找,无果,转战百度,果然搜到了,原来这并不是一个开放的接口,而是需要单独去向微信申请的,并且也没有公开文档。也对,毕竟是跳到付款码界面,比较敏感 。
好申请完成后,开始开发!
前置条件
- 小程序必须接入微信支付
- 拥有微信支付商户平台
- 关联小程序和商户
API介绍
wx.openOfflinePayView(OBJECT)
参数 | 类型 | 必填 | 实例值 | 说明 |
---|---|---|---|---|
appId | String | 是 | wxd678efh567hg6787 | 公众平台 appid,需与 mch_id 有绑定关系 |
timeStamp | String | 是 | 1631604636 | 时间戳;商户生成从 1970 年 1 月 1 日 00: 00:00 至今的秒数,即当前的时间 |
nonceStr | String | 是 | njqn50kxbl | 随机字符串;商户生成的随机字符串;取 值范围:长度为 32 个字符以下。 |
package | String | 是 | mch_id=1289343489 | mch_id=****,微信支付商户号,需与 appid 有绑定关系 |
signType | String | 是 | MD5 | 签名类型,目前支持 MD5、 HMAC-SHA256。该字段需参与签名。 |
paySign | String | 是 | 97A991A68892C3A0668E4DE80F24F782 | 签名结果,该方法需要加入签名的参数为 appId、timeStamp、nonceStr、package、 key、signType,请注意这里的参数有大 小写,签名的时候不要转为小写 |
success | Function | 否 | successHandler | 调用成功回调 |
fail | Function | 否 | failHandler | 调用失败回调 |
complete | Function | 否 | complatehandler | 调用完成回调 |
签名字符串示例
appId=wxa66666d6d5c4bf4b&nonceStr=y6683ha9i6a&package=mch_id=164888850&signType=MD5&timeStamp=1631605839&key=apiKey12355yesuis
最终请求示例
wx.openOfflinePayView(
{
'appId': 'wxa66666d6d5c4bf4b',
'timeStamp': '1631605839',
'nonceStr': 'y6683ha9i6a',
'package': 'mch_id=164888850',
'signType': 'MD5',
'paySign': '64355B5427BAF57459BA2A3214AF1883EBB2B519F4789B7D616CC8B8F2CE8ED5',
'success':function(res){},
'fail':function(res){},
'complete':function(res){}
}
)
代码
签名生成
- 设所有发送或者接收到的数据为
集合M
,将集合M
内非空参数值的参数按照参数名ASCII
码从小到大排序(字典序
),使用URL键值对的格式(即key1=value1&key2=value2…
)拼接成字符串stringA
。
注意以下规则:
- 参数名
ASCII
码从小到大排序(字典序); - 如果参数的值为空不参与签名;
- 参数名区分大小写;
- 验证调用返回或微信主动通知签名时,传送的
sign参数
不参与签名,将生成的签名与该sign值作校验。 - 微信接口可能增加字段,验证签名时必须支持增加的扩展字段
- 加密参数排序拼接方法
obj2str(args) => {
//获取参数对象的参数名集合
var keys = Object.keys(args)
//参数名ASCII码从小到大排序(字典序)
keys = keys.sort()
// 用于接收排序并过滤空值后的属性及值
var newArgs = {}
// 遍历赋值存储
keys.forEach(function (key) {
if (args[key] != "" && args[key] != 'undefined') { //如果参数的值为空不参与签名;
newArgs[key] = args[key] //参数名区分大小写;
}
})
//用于接收拼接的字符串
var string = ''
for (var k in newArgs) {
string += '&' + k + '=' + newArgs[k]
}
// 截取字符串,只取第一个&符号后面的值
string = string.substr(1)
// 返回字符串,用于下一步加密
return string
}
- 生成随机数方法
用于保证签名不可预测。推荐生成随机数算法如下:调用随机数函数生成,将得到的值转换为字符串
creatNonceStr(radix=36){
// 将0-1随机小数,转换为radix进制,去掉0.,保留余下部分(这里可以自由发挥)
return Math.random().toString(radix).substr(2, 15)
}
- 在
stringA
最后拼接上key
得到stringSignTemp
字符串,并对stringSignTemp
进行MD5
运算,再将得到的字符串所有字符转换为大写
,得到sign值signValue
。 注意:密钥的长度为32个字节。
我这里使用的是MD5加密,是从网上找的现成的,引入小程序直接使用
key设置路径:微信商户平台(pay.weixin.qq.com)–>账户设置–>API安全–>密钥设置
let params = {
appId: 'wxa66666d6d5c4bf4b',
timeStamp: parseInt(new Date().getTime() / 1000) + '',
nonceStr: this.creatNonceStr(),
package: 'mch_id=164888850',
signType: 'MD5', ,
}
// 商户后台api Key
let mchKey = 'apiKey12355yesuis'
// 在拼接的参数后追加上api key
let objStr = this.obj2str(params)+`&key=${mchKey}`
// 进行MD5加密并转为大写
let paySign = md5.hex_md5(objStr).toUpperCase()
注意:
package
的值是mch_id=商户号
,我第一次就没看清文档写错了key
是将appId、timeStamp、nonceStr、package、 key、signType
排序拼接后追加在最后的key
用的是商户后台的API秘钥
而不是APIv3秘钥
- 最后记得将加密后的结果转为大写
- 调用API
wx.openOfflinePayView({
...params,
paySign,
success(res){
console.log('成功',res)
},
fail(err){
console.log('失败',err)
},
complete(e){
console.log('结束',e)
}
})
如果你觉得文章对你有帮助,可以关注我的个人公众号 ,感谢你的支持!!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~