微信小程序:用户点击跳转付款码界面

最近工作中遇到一个需求是用户点击活动领取的微信代金券后跳转到微信付款码界面,于是乎,一顿翻文档,说实话,微信小程序的文档翻起来真的…一言难尽。
很快找到了一个wx.requestPayment(Object object),可是仔细一看,这个接口是发起支付的,会弹出付款界面,就是让你输入密码那个,继续找,无果,转战百度,果然搜到了,原来这并不是一个开放的接口,而是需要单独去向微信申请的,并且也没有公开文档。也对,毕竟是跳到付款码界面,比较敏感 。
好申请完成后,开始开发!

前置条件

API介绍

wx.openOfflinePayView(OBJECT)

参数类型必填实例值说明
appIdStringwxd678efh567hg6787公众平台 appid,需与 mch_id 有绑定关系
timeStampString1631604636时间戳;商户生成从 1970 年 1 月 1 日 00: 00:00 至今的秒数,即当前的时间
nonceStrStringnjqn50kxbl随机字符串;商户生成的随机字符串;取 值范围:长度为 32 个字符以下。
packageStringmch_id=1289343489mch_id=****,微信支付商户号,需与 appid 有绑定关系
signTypeStringMD5签名类型,目前支持 MD5、 HMAC-SHA256。该字段需参与签名。
paySignString97A991A68892C3A0668E4DE80F24F782签名结果,该方法需要加入签名的参数为 appId、timeStamp、nonceStr、package、 key、signType,请注意这里的参数有大 小写,签名的时候不要转为小写
successFunctionsuccessHandler调用成功回调
failFunctionfailHandler调用失败回调
completeFunctioncomplatehandler调用完成回调

签名字符串示例

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){} 
 }
)

代码

官方签名规则及签名生成算法

签名生成

  1. 设所有发送或者接收到的数据为集合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)
}
  1. 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秘钥
  • 最后记得将加密后的结果转为大写
  1. 调用API
  wx.openOfflinePayView({
        ...params,
        paySign,
        success(res){
          console.log('成功',res)
        },
        fail(err){
          console.log('失败',err)
        },
        complete(e){
          console.log('结束',e)
        }
      })

在这里插入图片描述

如果你觉得文章对你有帮助,可以关注我的个人公众号 ,感谢你的支持!!
在这里插入图片描述

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
以下是微信小程序登录注册并跳转到主页界面的代详细实现: 1. 在 app.json 文件中配置主页路径和页面列表 ```json { "pages": [ "pages/index/index", "pages/login/login", "pages/register/register" ], "window": { "navigationBarTitleText": "微信小程序登录注册示例" }, "tabBar": { "list": [ { "pagePath": "pages/index/index", "text": "首页" } ] } } ``` 2. 在登录界面 login.js 中实现登录逻辑 ```javascript Page({ data: { username: '', password: '' }, handleUsernameInput(e) { this.setData({ username: e.detail.value }) }, handlePasswordInput(e) { this.setData({ password: e.detail.value }) }, handleLogin() { // 判断用户名和密是否为空 if (this.data.username.trim() === '' || this.data.password.trim() === '') { wx.showToast({ title: '用户名和密不能为空', icon: 'none' }) return } // 发送登录请求 wx.request({ url: 'http://localhost:3000/login', method: 'POST', data: { username: this.data.username, password: this.data.password }, success: res => { // 登录成功,保存用户信息到本地存储 wx.setStorageSync('userInfo', res.data) // 跳转到主页 wx.switchTab({ url: '/pages/index/index' }) }, fail: err => { wx.showToast({ title: '登录失败,请检查用户名和密', icon: 'none' }) } }) } }) ``` 3. 在注册界面 register.js 中实现注册逻辑 ```javascript Page({ data: { username: '', password: '', confirmPassword: '' }, handleUsernameInput(e) { this.setData({ username: e.detail.value }) }, handlePasswordInput(e) { this.setData({ password: e.detail.value }) }, handleConfirmPasswordInput(e) { this.setData({ confirmPassword: e.detail.value }) }, handleRegister() { // 判断用户名和密是否为空 if (this.data.username.trim() === '' || this.data.password.trim() === '') { wx.showToast({ title: '用户名和密不能为空', icon: 'none' }) return } // 判断两次输入的密是否一致 if (this.data.password !== this.data.confirmPassword) { wx.showToast({ title: '两次输入的密不一致', icon: 'none' }) return } // 发送注册请求 wx.request({ url: 'http://localhost:3000/register', method: 'POST', data: { username: this.data.username, password: this.data.password }, success: res => { // 注册成功,保存用户信息到本地存储 wx.setStorageSync('userInfo', res.data) // 跳转到主页 wx.switchTab({ url: '/pages/index/index' }) }, fail: err => { wx.showToast({ title: '注册失败,请检查用户名和密', icon: 'none' }) } }) } }) ``` 4. 在主页界面 index.js 中实现获取用户信息和退出登录逻辑 ```javascript Page({ data: { userInfo: null }, onLoad() { // 获取用户信息 const userInfo = wx.getStorageSync('userInfo') if (userInfo) { this.setData({ userInfo }) } }, handleLogout() { // 清空本地存储的用户信息 wx.clearStorageSync('userInfo') // 跳转到登录界面 wx.redirectTo({ url: '/pages/login/login' }) } }) ``` 5. 在主页界面 index.wxml 中实现展示用户信息和退出登录按钮 ```html <view class="container"> <view wx:if="{{userInfo}}" class="user-info"> <image src="{{userInfo.avatarUrl}}" class="avatar"></image> <view class="nickname">{{userInfo.nickName}}</view> </view> <view wx:else class="login-tip">请先登录</view> <button wx:if="{{userInfo}}" class="logout-btn" bindtap="handleLogout">退出登录</button> </view> ``` 6. 在 app.js 中配置全局请求头和登录态检查 ```javascript App({ onLaunch() { // 设置全局请求头 wx.request.defaults.header = { 'Content-Type': 'application/json' } // 检查登录态 const userInfo = wx.getStorageSync('userInfo') if (!userInfo) { wx.redirectTo({ url: '/pages/login/login' }) } } }) ``` 通过以上步骤,我们就实现了微信小程序登录注册并跳转到主页界面的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值