微信小程序支付流程

小程序微信支付的流程图:

1. 登录微信公众平台, 开通微信支付功能

这是准备工作的第一步, 确保小程序对应的支付功能已经开启

2. 登录微信商户平台

该步骤需要获取两个参数, 一个是商户号, 一个是支付秘钥, 如下图所示


注意秘钥自己要保护好,相当于支付密码,每次签名都需要该参数, 该参数只能设置的时候看得见,其余的时候是没法看得见.所以要记好了!

3. 准备完毕,上代码

微信小程序的商户系统一般是以接口的形式开发的,小程序通过调用与后端约定好的接口进行参数的传递以及数据的接收。在小程序支付这块,还需要跟微信服务器进行交互。过程大致是这样的:

一、小程序调用wx.login() 获取code,传递给商户服务器用来获取用户的openID

我们知道在微信平台中,同一个公众号的openID都是不同的,它是用户身份识别的id,也就是说,我们通过openID来区分不同的用户,这个有微信开发基础的应该都很熟悉。为了知道谁在支付,我们需要先获取当前用户的openid,那么openID应该怎么获取呢?看下图:

小程序调用wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。
开发者服务器以code换取 用户唯一标识openid 和 会话密钥session_key。

看不懂吗?不急,听我慢慢解释,这个业务流程大致就是首先你得先在小程序的代码中调用wx.login()来向微信获取到code,拿到了之后把code通过request传给商户服务器,再由商户服务器通过骚操作来跟微信服务器要session_key和openID。

代码如下(小程序端):

    getToken: function () {//调用登录接口wx.login({success: function (res) {var code = res.code;wx.request({url: 商户服务器接口地址, data: {code: code},method: 'POST', success: function (res) { wx.setStorageSync('token', res.data.token); //存在小程序缓存中},fail: function (res) {console.log(res.data);}})}})}

调用这几行代码就可以向跟微信服务器要code,并且将code传到商户服务器中,记住这里最好使用post发送请求,安全性的东西我应该不用讲了,因为避免其他人滥用接口,于是我们使用token来进行验证。并将商户服务器返回的token存在小程序缓存中。

那么服务器端应该怎么做呢?

我门通过小程序提交的code,和小程序的APPID以及APPSECRET和拼接下列的url,并用curl进行get请求。
https://api.weixin.qq.com/sns/jscode2session?appid=APPID&secret=SECRET&js_code=JSCODE&grant_type=authorization_code
返回的数据是一个json对象,我门通过使用json_decode(JSON,true)解析为数组,数据包括用户的openID以及session_key,获取到了后我们应该将openID存入数据库中,它代表着用户的身份,那么令牌应该怎么生成呢。

二、token的生成以及缓存

我们根据一个用户表将id和openid联系起来,对应openID的id则是用户的uid,我们可以这么封装

    //要缓存的数据数组$cacheValue = $result;   //包含openID和session_key$cacheValue['uid'] =$uid;   //用户id$cacheValue['scope'] =ScopeEnum::User;   //用户权限级别

缓存的方式我们可以选择redis,memcache, 文件缓存等等,采用键值对(key-value)的方式进行存储,记得设置好过期时间。这里的key我们用token来赋值,token可以通过这样的方式进行生成:

    //获取32位随机字符串$str = getRandChar(32);   //自定义方法生成32位随机串//三组字符串进行md5加密$timeStamp =$_SERVER['REQUEST_TIME_FLOAT'];//salt$salt = config('secure.token_salt'); //随机字符串//返回tokenreturn md5($str.$timeStamp.$salt);

这种算法基本保障了token的唯一性。因为值是我们获取到的openID和session_key所在的数组,所以需要将数组转成json才能存进去。以后的代码当我们需要openID或者uid等时可以直接通过取缓存的方式来取。

三、调用统一下单接口,获取prepay_id,再次签名(后端完成,不详解)

  1. 点击‘提交订单’按钮,创建订单,清空购物车,完成支付
<van-submit-barprice="{{ allGoodsAndYunPrice*100 }}"suffix-label="+{{totalScoreToPay}} 积分"button-text="提交订单"bind:submit="goCreateOrder"
/>
  1. 创建订单,清空购物车,调用支付函数
const wxpay = require('../../utils/pay.js')'
//去创建订单
goCreateOrder(){//检测实名认证状态//创建订单
this.createOrder(true)
}
//创建订单
createOrder(){var that = this;
var loginToken = wx.getStorageSync('token') // 用户登录 token
var remark = this.data.remark; // 备注信息
let postData = { //创建订单需要的参数token: loginToken,//tokengoodsJsonStr: that.data.goodsJsonStr, //购买的商品数据列表remark: remark,//备注信息peisongType: that.data.peisongType// // 配送方式 kd,zq 分别表示快递/到店自取};//调用创建订单接口,传递此次订单相关数据
WXAPI.orderCreate(postData).then(function (res) {that.data.pageIsEnd = true if (res.code != 0) {that.data.pageIsEnd = falsewx.showModal({title: '错误',content: res.msg,showCancel: false})return;}if ("buyNow" != that.data.orderType) { //订单类型,购物车下单或立即支付下单,默认是购物车,// 清空购物车数据WXAPI.shippingCarInfoRemoveAll(loginToken)}that.setData({totalScoreToPay: res.data.score, //积分isNeedLogistics: res.data.isNeedLogistics, 是否需要物流信息allGoodsAndYunPrice: res.data.amountReal,//总价=总商品价+总运费yunPrice: res.data.amountLogistics,//运费hasNoCoupons,//没有优惠券coupons,//优惠券couponAmount: res.data.couponAmount //优惠金额});that.data.pageIsEnd = falsereturn;}//创建订单后的操作that.processAfterCreateOrder(res)})//创建订单后的操作  async processAfterCreateOrder(res) {// 直接弹出支付,取消支付的话,去订单列表const balance = this.data.balanceif (balance || res.data.amountReal*1 == 0) {// 有余额const money = (res.data.amountReal * 1 - balance*1).toFixed(2)if (money <= 0) {// 余额足够wx.showModal({title: '请确认支付',content: `您当前可用余额¥${balance},使用余额支付¥${res.data.amountReal}?`,confirmText: "确认支付",cancelText: "暂不付款",success: res2 => {if (res2.confirm) {// 使用余额支付,传token,和订单idWXAPI.orderPay(wx.getStorageSync('token'), res.data.id).then(res3 => {if (res3.code != 0) {wx.showToast({title: res3.msg,icon: 'none'})return}wx.redirectTo({url: "/pages/order-list/index"})})} else {wx.redirectTo({url: "/pages/order-list/index"})}}})} else {// 余额不够wx.showModal({title: '请确认支付',content: `您当前可用余额¥${balance},仍需支付¥${money}`,confirmText: "确认支付",cancelText: "暂不付款",success: res2 => {if (res2.confirm) {// 使用余额支付wxpay.wxpay('order', money, res.data.id, "/pages/order-list/index");} else {wx.redirectTo({url: "/pages/order-list/index"})}}})}} else {// 没余额wxpay.wxpay('order', res.data.amountReal, res.data.id, "/pages/order-list/index");}},
//查看用户资产async userAmount() {const res = await WXAPI.userAmount(wx.getStorageSync('token'))if (res.code == 0) {this.setData({balance: res.data.balance})}},
}

四、小程序获取五个参数后,鉴权调起支付

const WXAPI = require('apifm-wxapi')/*** type: order 支付订单 recharge 充值 paybill 优惠买单* data: 扩展数据对象,用于保存参数*/
function wxpay(type, money, orderId, redirectUrl, data) {WXAPI.wxpay(postData).then(function (res) {if (res.code == 0) {// 发起支付wx.requestPayment({timeStamp: res.data.timeStamp, //时间戳nonceStr: res.data.nonceStr,,//随机字符串package: res.data.package,//订单详情扩展字符串signType: res.data.signType//签名方式paySign: res.data.paySign,//签名fail: function (aaa) {console.error(aaa)wx.showToast({title: '支付失败:' + aaa})},success: function () {// 提示支付成功wx.showToast({title: '支付成功'})wx.redirectTo({url: redirectUrl});}})} else {wx.showModal({title: '出错了',content: JSON.stringify(res),showCancel: false})}})
}module.exports = {wxpay: wxpay
}

五、支付回调

小程序:微信小程序支付流程相关推荐

  1. 微信小程序—微信小程序端支付代码

    只有微信小程序端的代码,如下 Page({data: {},onLoad: function (options) {// 页面初始化 options为页面跳转所带来的参数var that = this ...

  2. 生鲜小程序 微信小程序怎么制作 临沂修齐网络专业制作微信小程序

    生鲜小程序 微信小程序怎么制作 临沂修齐网络专业制作微信小程序 生鲜小程序开发功能介绍: 1.产品展示:通过扫码或者搜索小程序,用户可以看到不同品种的新鲜蔬菜.水果以及肉类. 2.定时收货:买家可以预 ...

  3. 小程序源码:修复图片音频全新升级带特效喝酒神器小游戏微信小程序

    这是一款全新升级带特效喝酒神器小游戏微信小程序源码 小编发现很多喝酒神器小程序都不带特效和音效的 感觉差了那么一点意思而且感觉也不炫酷 所以小编今天给大家带来一款带特效,音效炫酷的喝酒神器 该款神器由 ...

  4. 微信小程序----微信小程序浏览pdf文件

    微信小程序----微信小程序浏览pdf文件 说明:通过wx.downloadFile,wx.openDocumen来实现打开pdf文件.只需在js操作即可. HTTP.Config.Request(' ...

  5. 小程序源码:炫酷手持滚动弹幕生成小工具微信小程序-多玩法安装简单

    这是一款滚动弹幕生成微信小程序源码 让弹幕文字在手机屏幕上跑起来,LED弹幕 手机弹幕,告白神奇,等 支持多种模板,每一种模板都支持自定义颜色等等 字体跳动,字体表白等等 另外用户也可以支持自定义文字 ...

  6. 小程序 | 微信小程序实现商品分类列表

    小程序 | 微信小程序实现商品分类列表 一.效果展示 二.代码实现 <!-- wxml --> <view class="container"> <! ...

  7. 微信小程序:娱乐小工具微信小程序源码下载支持多种流量主

    这应该是属于娱乐小工具呢还是属于工具箱类型就看你们怎么分辨了 当然啦说是娱乐也可以,里面功能应该也属于娱乐性 如果说是工具类型也可以,里面也属于工具吧 该程序由几个小功能组合而成如有: 网易云音乐下载 ...

  8. 抛硬币小游戏微信小程序源码

    简介: 抛硬币小游戏微信小程序源码 日常生活中遇到选择?抛个硬币看看天意吧! 有了这个小程序,起不起床拋一下,叫不叫外卖拋一下,打不打扫房间拋一下,让生活充满乐趣~ 人生决定不了的决定就让上天来决定吧 ...

  9. 小程序 | 微信小程序中使用位置API打开地图

    小程序 | 微信小程序中使用位置API打开地图 一.效果展示 二.代码实现 使用微信内置地图查看位置,调用wx.openLocationAPI,具体内容可以查看微信官方文档. // js let In ...

  10. 小程序 | 微信小程序实现循环嵌套数据选择

    小程序 | 微信小程序实现循环嵌套数据选择 一.效果展示 二.代码实现 在.wxml文件中,有时从后台传来的数据可能会出现数组嵌套数组的情况,需要利用wx:for嵌套实现数据的展示.这时,外层循环正常 ...

最新文章

  1. ViewGroup1——自定义布局
  2. 【Android】把Linux GCC安插在Android手机上
  3. [蓝桥杯][2013年第四届真题]危险系数(暴力+dfs)
  4. 2018陕西省赛K题[watermelon_planting]
  5. 取数函数设置向导返回值说明
  6. 移植memtester到android平台
  7. web服务器集群(多台web服务器)后session如何同步和共享
  8. html5表单与Jquery Ajax结合使用
  9. Java从0开始之Java环境搭建
  10. Atitit 提升效率 界面gui方面的前后端分离与cbb体系建设 规范推荐标准
  11. arcgis重分类工具详解——结合遥感影像中植被剔除实例
  12. 几种线性回归方法的简介
  13. css规则中区块block,听晴空讲Drupal主题——第六章 主题中的CSS(10)
  14. Eclipse中去掉代码中的警告Warn
  15. vivado error:Multiple declarations of unsigned included via multiple use clauses
  16. pythontkinter图片_Python tkinter实现图片标注功能(完整代码)
  17. 微信小程序开发语言和“前端三件套”的异同点
  18. Bigder:53/100 真香免费网站!在线练习SQL\Python\Shell像游戏通关一样刷题
  19. 写给大忙人的模电复习资料(001)
  20. 微信小程序之picker选择器获取值得两种方法

热门文章

  1. 怎么用计算机打出cpdd,网络语cpdd是什么梗啥意思 cpdd出处来源哪里常见用法介绍...
  2. Java基于Socket实现聊天、群聊、敏感词汇过滤功能
  3. TFT-LCD LVGL官方例程的应用
  4. 黑群晖樱花sakura内网穿刺
  5. ajax必填项验证,jQuery验证 - 通过MVC2中的ajax动态添加必填字段
  6. Web服务與.NET Remotin的選擇
  7. 对Largest函数的测试
  8. 记一次修改sga大小之后出现的一系列报错
  9. 怎样用计算机计算节点导纳矩阵,电力网节点导纳矩阵计算例题与程序
  10. matlab实验报告井字棋,一字棋实验报告