必看!前端角度梳理微信付出(小步伐、H5、JSAPI)流程解密 ...

莱莱  金牌会员 | 2024-6-19 22:28:11 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 676|帖子 676|积分 2028

因业务须要,开辟微信付出功能,涉及三种付出方式:


  • JSAPI 付出:微信内网页付出,须要开通微信服务号
  • 小步伐付出:在小步伐中付出,须要开通小步伐
  • H5 付出:在手机浏览器(出微信内网爷)中网页付出
使用微信付出的前提必开通微信商户号,要使用到那种的付出方式要前需在商户平台开通(要考核)。
付出的钱终极都会到商户号里(一样平常由公司财政开通)。
开辟微信付出的过程中大大小小坑还是踩了不少,终于做完了,整理下开辟流程。
参考:


  • 微信付出-接入指引
  • 微信付出-开辟文档
小步伐付出

开辟流程


  • 小步伐端请求创建订单接口,后端统一下单获取 orderId 并返回
  • 小步伐端获取通过wx.login()获取code
  • 小步伐端拿这code和orderId请求后端接口,获取付出所需数据
  • 获取付出所需数据之后,小步伐端调用wx.requestPayment()接口,直接调用起付出页面
  • 判定是否付出成功后的逻辑
伪代码

  1. async function wxPay(goodId) {
  2.   // 1. 创建订单 获取orderId
  3.   let orderId = await ajax("POST", "/api/OrderProgram/CreateTheOrder", {
  4.     goodId, // 商品id
  5.   });
  6.   // 2. 获得 code
  7.   let code = await wxlogin(); // 基于pr封装的wx.login()方法
  8.   // 3. 获取支付的数据
  9.   let payData = await ajax("POST", "/api/OrderProgram/WxXcxPay", {
  10.     orderId,
  11.     code,
  12.   });
  13.   // 4. 发起支付
  14.   let res = await payment(payData); // 基于pr封装的wx.requestPayment()方法
  15.   // 5. 判断是否支付成功
  16.   let payResult = res.errMsg;
  17.   if (payResult == "requestPayment:ok") {
  18.     console.log("支付成功");
  19.   } else if (payResult == "requestPayment:fail cancel") {
  20.     console.log("用户取消支付");
  21.   } else {
  22.     console.log("支付失败");
  23.   }
  24. }
复制代码
留意事项


  • 申请微信小步伐账号
    申请成功可拿到 AppID(小步伐 id)和 AppSecret(小步伐密钥)
    申请类型为企业性子,否则无法接入微信付出
  • 微信小步伐认证
    通过认证的小步伐才气接入微信付出和绑定商户平台
  • 申请商户平台账号
    须要第一步申请的 AppID
    申请成功可拿到 MchID(商户 id)和 MchKey(商户密钥)
  • 信小步伐关联商户号
    微信和商户都认证成功后,在微信后台微信付出菜单中进行关联
  • 接入微信付出
    在微信后台微信付出菜单中进行接入
参考



  • 小步伐付出文档
  • 小步伐开辟文档
H5 付出

开辟流程


  • 前端端请求创建订单接口,后端统一下单获取 orderId 并返回
  • 前端带着 orderId 请求付出接口,获得 mweb_url,
  • 然后跳转 mweb_url 会跳转微信自动调用微信付出
  • 付出后返回付出页,判定是否付出成功(需发送请求后端查询)
    4.1 革新页面,获取最新的付出(订单)状态。
    4.2 设置一个的按钮"我已付出",让用户点击自动查询状态。
伪代码

  1. async function wxH5Pay(goodId) {
  2.   // 1. 创建订单 获取orderId
  3.   let orderId = await ajax("POST", "/api/OrderProgram/CreateTheOrder", {
  4.     goodId, // 商品id
  5.   });
  6.   // 2. 获取支付跳转的URL
  7.   let mweb_url = await ajax("POST", "/api/OrderProgram/WxH5Pay", { orderId });
  8.   // 3. 跳转URL去微信支付
  9.   if (mweb_url) {
  10.     location.href = mweb_url;
  11.   } else {
  12.     console.log("回调地址出错");
  13.   }
  14.   // 4. 支付后返回支付页,判断是否支付成功
  15.   // 4.1 刷新页面,获取最新的订单(商品)状态。
  16.   // 4.2 设置一个"我已支付"的按钮,让用户点击之后查询状态。
  17. }
复制代码
留意事项



  • 在商户平台设置正确的付出域名
  • 调试须要在线上,假如嫌麻烦可以使用内网穿透(Ngrok 或花生壳)
  • 需对redirect_url进行urlencode处置惩罚
  • H5 付出不能直接在微信客户端内调起,请在外部浏览器调起。
参考



  • 微信付出-H5 付出-开辟步骤
JSAPI 付出(微信内网页付出)

开辟流程



  • 商品页

  • 前端商品页创建订单,在后端统一下单后获取 orderId
  • 前端带着 orderId 跳转到付出页,


  • 付出页

  • 获取 code

    • 第一次进入页面,判定是否路径中有 code
    • 没有 code,请求数据跳转授权页面,code 会通过回调地址一起返回返来
    • 拿到 code,发送给后端,后端解析到 openid,生存好。

  • 点击确定付出按钮,触发 wxPay() 方法

    • 发送 orderId 给后端,获取 wxData
    • wxData 中包含 wx.config 和 wx.chooseWXPay 两个接口的数据。
    • 先调用 wx.config()然后在调用 wx.chooseWXPay(),假如一切正常,付出页面就会弹出。

  • 付出状态通事后端去查询
伪代码



  • 商品页
  1. // 1. 创建订单 获取orderId
  2. let orderId = await ajax("POST", "/api/OrderProgram/CreateTheOrder", {
  3.   goodId, // 商品id
  4. });
  5. // 2. 携带id 跳转到支付页
  6. this.$router.push({ name: "wx_pay_page", params: { orderId: id } });
复制代码


  • 入口文件(main.js)
  1. // main.js 引入 js-sdk
  2. import wx from "weixin-js-sdk";
复制代码


  • 付出页 HTML
  1. <template>
  2.   <div>
  3.     <button @click="wxPay">点击支付</button>
  4.   </div>
  5. </template>
复制代码
付出页 JS
  1. // Vue
  2. data(){
  3.     return {
  4.         orderId: this.$route.params.orderId, // 订单id
  5.         url: '',// 获取code的url
  6.         wxData: null,// js-sdk接口所需的数据
  7.     }
  8. },
  9. mounted(){
  10.     // 判断是否有code
  11.     this.getCode()
  12. }
  13. methods: {
  14.     getCode() {
  15.         var code = this.getUrlPram("code");
  16.         if (code != null) {
  17.             this.code = code;
  18.             // 拿到 code 发给 后端
  19.             this.sendCode(code);
  20.         } else {
  21.             // 去拿code
  22.             this.getUrl();
  23.         }
  24.     },
  25.     getUrl() {
  26.         // 请求后端拿到url所需数据,然后跳转页面在通过回调地址返回,获取code.
  27.         this.axios
  28.             .post("/api/OrderProgram/GetOpenidAndAccessToken", {
  29.                 orderId: this.orderId,
  30.             })
  31.             .then((data) => {
  32.                 this.url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${data.appId}&redirect_uri=${data.redirect_uri}&response_type=${data.response_type}&scope=${data.scope}&state=${data.state}`;
  33.                 window.location.href = this.url;
  34.             })
  35.             .catch((err) => {
  36.                 console.log(err);
  37.             });
  38.     },
  39.     sendCode(code) {
  40.         // 发送code给后端 后端解析出openid
  41.         this.axios
  42.             .post("/api/OrderProgram/GetOpenidAndAccessTokenFromCode", {
  43.                 code: code,
  44.             })
  45.             .then((res) => {
  46.                 console.log(res);
  47.             })
  48.             .catch((err) => {
  49.                 console.log(err);
  50.             });
  51.     },
  52.     wxPay: async function() {
  53.         // 发送orderid,获取wx.chooseWXPay和wx.config所需的参数
  54.         this.wxData = await this.axios.post(
  55.             "/api/OrderProgram/WxJSAPIPay",
  56.             { orderId: this.orderId }
  57.         );
  58.         let wxConfigData = this.wxData.wxConfigData // 获取wx.chooseWXPay()所需数据
  59.         let wxPayData = this.wxData.wxPayData;// 获取wx.config()所需数据
  60.         this.$wx.config({
  61.             debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
  62.             appId: wxConfigData.appId, // 必填,公众号的唯一标识
  63.             timestamp: wxConfigData.timeStamp, // 必填,生成签名的时间戳
  64.             nonceStr: wxConfigData.nonceStr, // 必填,生成签名的随机串
  65.             signature: wxConfigData.paySign, // 必填,签名
  66.             jsApiList: [
  67.                 "chooseWXPay",
  68.             ],
  69.         });
  70.         // 执行支付
  71.         this.$wx.chooseWXPay({
  72.             timestamp: wxPayData.timeStamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
  73.             nonceStr: wxPayData.nonceStr, // 支付签名随机串,不长于 32 位
  74.             package: wxPayData.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=\*\*\*)
  75.             signType: wxPayData.signType, // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
  76.             paySign: wxPayData.paySign, // 支付签名
  77.             success: (res) => {
  78.                 this.$toast("支付成功");
  79.             },
  80.             fail: (err) => {
  81.                 this.$toast("支付失败");
  82.             },
  83.         });
  84.     },
  85. }
复制代码
同时支持 H5 付出和 JSAPI 付出

  1. // 在创建订单之后,就判断环境使用哪种方法支付。
  2. if (isWx()) {
  3.   this.WXPay(orderId); // 带着orderId跳转到支付页逻辑
  4. } else {
  5.   this.H5Pay(orderId); // 执行上面H5支付中的创建订单之后的逻辑
  6. }
  7. // 判断是否是微信浏览器
  8. function isWx() {
  9.   let uAgent = navigator.userAgent.toLowerCase();
  10.   reutrn(/micromessenger/.test(uAgent)) ? true : false;
  11. }
复制代码
留意事项



  • 开通微信商户号 - 设置付出目录(假如是 Vue 这类 SPA 页面,到根目录即可,也就是#号之前的地址)

  • 开通微信公众号(服务号) - 设置安全域名、设置授权域名

  • 收集参数:appId 和 AppSecret
  • 添加 Web 开辟工具开辟者(须要开辟者同时开辟者关注开辟的微信公众号和微信公众账号安全助手)参考文档



  • 设置回调域名(例如:www.xx.com/pay,最后获取的 code 会拼在此回调地址后返回,返回后如www.xx.com/pay?code=xxxx)参考 1

  • 获取 code

    • 参考获取 code 文档
    • 在微信客户端网页打开授权地址,跳转之后,在返回的回调地址之后拿到 code:

  1. https://open.weixin.qq.com/connect/oauth2/authorize
  2. ?appid=你的appid
  3. &redirect_uri=你的回调地址(拿到code后返回)
  4. &response_type=code(返回类型,默认code)
  5. &scope=snsapi_base(授权范围,静默授权拿到openid)
  6. &state=STATE(自定义状态,非必填)
  7. #wechat_redirect(重定向使用必须携带)
复制代码
redirect_uri参数要和你在微信公众号里设置的回调域名一致(例如:www.xx.com/pay),须要留意的是这 url 须要urlEncode。
请求这个地址之后,code 会以你设置的redirect_uri地址里的参数带返来,拿到之后传给后端就行了。


  • 前端引入 js-skd

    • 使用script引入js-sdk
    • 下载使用 npm 包weixin-js-sdk

  • 获取 wx.config 的参数

  • 获取 wx.chooseWXPay 所需的参数

参考



  • 微信付出-JSAPI
  • 微信公众号-网页授权
  • JS-SDK 开辟文档
  • 小步伐、H5 登录授权、分享、付出流程
  • wx.config 接口注入时signature参数须要留意,坑比力多
  • 我的 JS-SDK 使用总结
总结

整个流程走下来,给我的体验是:小步伐付出最方便(因为配置少),其次是 H5,JSAPI 付出最麻烦(文章一多半都在写它)
在微信付出功能开辟过程中,其实最麻烦的不是开辟流程,而是他的各种配置和授权流程,为了拿到所需的参数而来回折腾。
开辟过程中的一些参数是经常用到的,如 appid、openid、orderId
付出流程大径相同,先获取到用户的 openid,知道你是谁,然后统一下单拿到 orderId 再行止理不同平台的付出方式
开辟时候用到的相关文档,一定要仔细阅读二遍以上为止!!
遇到问题不要死刚,多百度多 Google,说禁绝你遇到的问题已经有无数的人遇到过并且已经有成熟的解决方案了。
前端和后端要多沟通,有什么问题(难点)随时反馈,须要什么参数好好说,遇到观点不一致的时候万万要留意控制住情绪,切莫撕逼(.——.)。
因为本人水平有限,对后端流程懂得不多,只能从前端的角度来梳理整个付出流程。
以上,盼望对你有所帮助。
欢迎关注,微信公众号:九旬


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

莱莱

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表