微信公众号网页如何接入微信支付?

日期:2022-06-09

作者:科技微讯

关于微信支付

微信支付针对多种接入场景,提供了多种接入方式

JSAPI 支付:在微信内部打开网页完成支付,公众号就用这种方式,PC 网页和线下也可以用这种方式,但需要用户打开相机扫描二维码,该二维码指向一个网页,扫码后在微信内部打开网页完成支付。

APP 支付:在其他手机 app 中集成微信支付模块,付款时会唤起微信支付页面完成支付。

小程序支付:因为苹果稅,微信不允许 iOS 端的小程序使用微信支付购买虚拟商品(例如在小程序购买会员、积分、课程、直播打赏等),Android 端小程序不受影响,如果是购买实物商品,iOS 端小程序也可以使用微信支付。

H5 支付:点击外部浏览器某个页面的某个元素(例如支付按钮),唤起微信 app 完成支付,和 JSAPI 对比,JSAPI 是在微信打开网页完成支付,H5 是在微信之外的浏览器打开网页,点击支付按钮后直接跳转到微信支付模块完成交易,和 Native 对比,Native 是扫一扫触发,而不是点击外部浏览器的某个按钮触发。

Native 支付:扫一扫,不是打开网页,扫一扫后直接拉起微信支付模块完成交易,这应该是我们最常用的支付方式,个人商家的微信收款码就是这种。

付款码支付:商户扫消费者的二维码,而前面几种都是消费者“扫”商户。

刷脸支付:消费者站在商户的刷脸机器前完成交易,一些便利店支持这种方式。

在公众号场景下,网页当然都是直接用微信的内部浏览器打开,所以用 JSAPI 接入微信支付就好了。如果一个页面主要用外部浏览器打开,则用 H5 的方式接入微信支付。

公众号网页开发

公众号网页开发也可以使用云开发,但公众号没有自己的云开发,需要小程序使用“环境共享”的方式把开发环境共享给公众号。

在微信公众号网页中实现微信支付,肯定要先获得用户的个人 id,即 openid。使用公众号的 js-sdk 的网页授权功能即可获得用户个人信息,但有点麻烦。如果开通了云开发,建议通过云开发的 Web SDK 获取用户个人信息。

云开发 Web SDK 主要用途是访问并操作云开发中的云资源的,包括云数据库、云函数等。要在公众号网页中访问这些资源,通常需要让访问这个网页的用户登录到云开发。云开发 Web SDK 的 startLogin 接口可以方便地完成用户登录,登录完成后,使用 Web SDK 的 checkLogin 接口判断用户是否已经成功登录,如果成功登录,再调用 init 方法。

init 会自动调用一个固定命名的 cloudbase_auth 云函数(使用 Web SDK 之前,必须在云开发中创建一个名为 cloudbase_auth 的云函数),该云函数返回协议字段来确认允许访问、访问时长以及可自定义安全规则,开发者也可以顺便把用户的 openid 等个人信息通过 cloudbase_auth 返回给前端。

其实 Web SDK 可以在未登录状态下使用云开发的大部分资源(云函数、云数据库等),即不需要 startLogin 和 checkLogin,直接 init 后,就可以在前端网页访问云开发资源,前提是需要在云开发开启未登录用户访问权限。未登录状态下,init 触发的 cloudbase_auth 函数照样可以获得用户的 openid。

公众号网页可以用 html、js、css 进行原生开发,我个人用 vite.js 的 react 模版,开发完成后,打包出来的文件可以上传到云开发的静态网站进行部署。部署在静态网站的页面有一些专属好处,例如可以在网页中免鉴权直接打开小程序。

公众号网页接入微信支付

通过上述方法拿到用户的 openid,公众号网页再把该 openid 传给后端,后端使用微信支付 jsapi 的下单接口获得 prepay_id、签名等数据后,返回给公众号前端,前端拿到数据后,有 2 种方式可以拉起微信支付。

  • wx.chooseWXPay(options)
  • WeixinJSBridge.invoke('getBrandWCPayRequest',options, callback)

如果采用第一种方式,则需要先使用微信公众号的 js-sdk 的 wx.config() 接口获取 chooseWXPay 接口的使用权限。wx.config() 接收的参数包括一个签名数据,开发者可以使用 js-sdk 计算签名,也可以直接使用云开发的 Web SDK 的 getJSSDKSignature 接口直接获取签名,这样开发者就不需要关注如何计算签名、如何保证签名不过时等。

第二种方式则简单得多,在微信内部浏览器打开的网页会自动带上 WeixinJSBridge 对象,该对象有一个 invoke 方法,可以直接调用 getBrandWCPayRequest 这个接口,即不需要像第一种方法那样,又要签名,签完名之后还要申请 chooseWXPay 接口的使用权限。WeixinJSBridge 可以调用多个接口,除了 getBrandWCPayRequest,还有 getUserConfig、imagePreview 等等。

在小程序的技术发展史上,微信解释了 js-sdk 和 WeixinJSBridge 的关系:

实际上,微信官方是没有对外暴露过 WeixinJSBridge.invoke 这种调用方法,此类 API 最初是提供给腾讯内部一些业务使用,很多外部开发者发现了之后,依葫芦画瓢地使用了,逐渐成为微信中网页的事实标准。2015 年初,微信发布了一整套网页开发工具包,称之为 JS-SDK,开放了拍摄、录音、语音识别、二维码、地图、支付、分享、卡券等几十个 API。给所有的 Web 开发者打开了一扇全新的窗户,让所有开发者都可以使用到微信的原生能力,去完成一些之前做不到或者难以做到的事情。

在微信支付 api v3 的开发文档中,微信官方给出了使用 WeixinJSBridge 在前端唤起微信支付界面的代码示例,微信官方表示:

  • WeixinJSBridge 这个对象仅存在于在微信内部打开的网页,所以在使用 WeixinJSBridge.invoke 前需要先判断 window 对象是否有 WeixinJSBridge;
  • 使用 js-sdk 和使用 WeixinJSBridge 发起微信支付,支付成功后返回的值不同:唤起支付返回的 res 对象驼峰式是 JSSDK 返回的格式,而 err_msg 是 WeixinJSBridge 返回的格式,如商户使用不同的方式,此处响应的字符大小写、格式需注意。

尽管连官方文档都使用 WeixinJSBridge 举例子,但并不建议开发者在生产环境中使用 WeixinJSBridge 唤起微信支付。因为有人发现 WeixinJSBridge 在安卓端表现不稳定,唤起微信支付可能失效,保险起见,还是建议使用公众号 js-sdk 的 chooseWXPay 拉起微信支付。

总结

公众号网页接入微信支付,你需要使用以下开发资源:

  • 公众号的 js-sdk;
  • 微信支付的 jsapi;
  • 云开发的 Web SDK(可以不用,但用它更方便);

整体流程:

  • 网页通过 js-sdk 的授权机制,或 Web SDK 的 init 方法获取用户的 openid 等个人信息,网页通过网络请求把 openid 传入后端,后端使用微信支付 jsapi 的下单接口计算签名、获取 prepay_id 等数据,然后把这些数据返回前端;
  • 前端使用 js-sdk 计算签名,或使用 Web SDK 的 getJSSDKSignature 直接获取签名,然后根据签名获取 chooseWXPay 接口的使用权限;
  • 前面两个步骤可以同时执行,因为它们不互相依赖,前面两个步骤都完成后(即前端获得了支付签名、prepay_id 等数据,并获得了 chooseWXPay 接口的使用权限),就来到了最后一个步骤:把从后端拿到的数据传入 chooseWXPay 接口,即可拉起微信支付界面;
  • 用户输入密码,完成支付后,开发者还需要处理一系列的逻辑,以确保支付真的成功了。