经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » JavaScript » 查看文章
微信小程序支付实现流程
来源:cnblogs  作者:会飞的一棵树  时间:2021/5/17 11:44:56  对本文有异议

基本流程

用户操作流程

image

小程序流程

image

整体支付流程

image

代码实现

创建订单

创建订单,主要是前端将订单的信息提交到后端。但是在创建订单之前还有一些准备工作要做:

  1. 获取用户数据GetUserInfo
  2. 获取用户授权,获得token
  3. 创建订单

使用buttongetUserInfo 获得的用户信息,再使用wx.login(Object object)得到code(用户登录凭证),session_key,获得后就可以在后台下发token用以对用户操作进行验证。

登录流程时序:
image

bindGetUserInfo的回调方法返回的参数示例:

  1. encryptedData: "NC9d+PEDLe6SPdjskdlfjslkjdfsljflksdjfklsdjfsdqwqz"
  2. errMsg: "getUserInfo:ok"
  3. iv: "2fNiyg133zyP5X9hOHS6Og=="
  4. rawData: "{"nickName":"1024","gender":1,"language":"zh_CN","city":"","province":"","country":"Croatia","avatarUrl":"https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTIradvotK0Q7XAK7bs06ZZidHLxdlscmaZZXwQrr5S7hhNS98CB2p4kL5nWuohlQel1vm2X2kFygozA/112"}"
  5. signature: "d4d9c2cff76bd348f1d9125216b53c7493e11da4"
  1. const { encryptedData, rawData, iv, signature } = e.detail;
  2. const { code } = await login();
  3. const loginParams = { encryptedData, rawData, iv, signature, code };
  4. // 将小程序端拿到的用户信息提交到后端
  5. // 后端调用微信的auth.code2Session接口
  6. // 就能获得openid,session_key,unionid等内容
  7. // 用以预付单的创建,及安全验证
  8. const {token} = await request({ url: "/users/wxlogin", data: loginParams, method: "post" });

获取token后将其添加在请求头的Authorization字段中。然后发送请求,后端程序将订单内容保存,然后将进行预支付。

  1. // orderParams 中是订单商品信息
  2. const header = { Authorization: token }
  3. const { order_number } = await request({ url: "order/submit", method: "POST", data: orderParams, header})

wx.login()
auth.code2Session

预支付

此时小程序端将订单编号发送给后端预支付接口,然后接口将会返回必要的支付参数。

  1. // 发起预支付接口 添加content-type才能成功
  2. const { pay } = await request({ url: "/my/orders/req_unifiedorder", method: "POST", data: { order_number }, header: { "content-type": "application/x-www-form-urlencoded" } });

此时后端服务器,会先判断订单是否是待支付的状态,若是则需要将以下参数提交到
image
统一下单接口:https://api.mch.weixin.qq.com/pay/unifiedorder
参数说明:接口参数说明
请求微信下单接口成功后,则会返回prepay_id,可以进行封装后,返回后续支付要的参数。

java随机数生成:

  1. // 获取随机字符
  2. public static String getRandomNum(Integer num) {
  3. String base = "0123456789";
  4. Random random = new Random();
  5. StringBuffer sb = new StringBuffer();
  6. for (int i = 0; i < num; i++) {
  7. int number = random.nextInt(base.length());
  8. sb.append(base.charAt(number));
  9. }
  10. return sb.toString();
  11. }
  12. String randomStr = getRandomNum(18).toUpperCase();

签名生成的通用步骤如下:

第一步,设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA。

特别注意以下重要规则:

◆ 参数名ASCII码从小到大排序(字典序);
◆ 如果参数的值为空不参与签名;
◆ 参数名区分大小写;
◆ 验证调用返回或微信主动通知签名时,传送的sign参数不参与签名,将生成的签名与该sign值作校验。
◆ 微信接口可能增加字段,验证签名时必须支持增加的扩展字段
第二步,在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值signValue。 注意:密钥的长度为32个字节。

◆ key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置

Java签名工具类:

  1. public static String arraySign(Map < Object, Object > params, String paySignKey)
  2. {
  3. boolean encode = false;
  4. Set < Object > keysSet = params.keySet();
  5. Object[] keys = keysSet.toArray();
  6. Arrays.sort(keys);
  7. StringBuffer temp = new StringBuffer();
  8. boolean first = true;
  9. for(Object key: keys)
  10. {
  11. if(first)
  12. {
  13. first = false;
  14. }
  15. else
  16. {
  17. temp.append("&");
  18. }
  19. temp.append(key).append("=");
  20. Object value = params.get(key);
  21. String valueString = "";
  22. if(null != value)
  23. {
  24. valueString = value.toString();
  25. }
  26. if(encode)
  27. {
  28. try
  29. {
  30. temp.append(URLEncoder.encode(valueString, "UTF-8"));
  31. }
  32. catch(UnsupportedEncodingException e)
  33. {
  34. e.printStackTrace();
  35. }
  36. }
  37. else
  38. {
  39. temp.append(valueString);
  40. }
  41. }
  42. temp.append("&key=");
  43. temp.append(paySignKey);
  44. System.out.println(temp.toString());
  45. String packageSign = MD5.getMessageDigest(temp.toString());
  46. return packageSign;
  47. }
  48. String sign = arraySign(parame, "商户key");

发起支付

使用wx.requestPayment(OBJECT)发起支付

  1. // 发起微信支付
  2. wx.requestPayment(pay)

需要参数如下,在请求预支付接口后由服务端返回:
image

查询订单

请求后端的查询接口,进行查询:

  1. // 查询订单状态
  2. const res = await request({ url: "/my/orders/chkOrder", method: "POST", data: { order_number } });

微同商城支付逻辑分析

image

参考和补充

  1. 微信支付开发文档
  2. 微同商城Gitee
  3. 微信小程序登录换取token
  4. 微信小程序登录 + 基于token的身份验证

原文链接:http://www.cnblogs.com/flytree/p/14772303.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号