微信支付三种常见方式流程梳理
1. Native 方式 — PC端
Native 方式一般是在 PC 端中使用。
先看官方提供的流程图:
根据官方的图来梳理即可:
1.1 第一步 — 商户平台内部生成订单信息并展示
这一步一般是在用户进入支付页面时完成的,所谓平台内部生成订单,实际上就是指生成:
订单信息价格…
以上这些信息是完全与微信平台无关联的,由商户平台内部完成。
1.2 第二步 — 商户平台调取微信提供的统一下单接口,微信平台生成预支付订单
这一步是在用户在支付页面中,点击微信支付按钮后进行的。
具体到研发,这一步实际上是首先由前端发送请求,后端调取微信提供的接口,进行统一下单,微信平台生成预支付订单,并向后端返回预支付交易链接 code_url。
预支付交易链接,实际上就是用户需要跳转完成支付的链接。
1.3 第三步 — 商户平台前端生成二维码
这一步由商户平台前端完成,在上一步中,前端拿到了微信提供的预支付交易链接 code_url。
接下来,由前端借助第三方工具,将 code_url 转换为二维码供用户扫描。
1.4 第四步 — 用户扫描二维码,进入支付 / 商户平台前端页面展示确认订单按钮
这里,流程分为两条线:
用户:用户扫描商户平台前端提供的二维码,进入微信支付页,完成或放弃支付,这条线中,仅有用户和微信平台的交互,商户平台并不参与。对应图中的 5~8 步。商户平台:商户平台在向用户展示二维码后,还需要提供一个确认订单已完成的按钮。同时,轮询订单的支付状态。
用户完成在微信支付页面中的操作后,可能会有两种情况:
订单未完成/支付失败 — 此时页面保持轮询订单状态,同时等待用户点击确认支付按钮,待用户点击确认支付按钮后,调取接口查询订单状态接口,确认订单支付状态。发现订单未支付后,向用户输出提示。订单已完成 — 此时页面同样持轮询订单状态,并等待用户点击确认支付按钮。当轮询到用户订单已完成时,进行页面跳转;当轮询到订单状态之前用户点击了确认支付按钮时,调取接口查询订单状态。这种情况下的最终结果就是,发现订单完成,进行下一步操作(主要是页面的跳转)
这里实际上对应的就是流程图中的 10 和 11 步。
2. H5 支付方式 — 移动端非微信浏览器
H5 方式是移动端的微信支付方式之一,其主要针对移动端在非微信浏览器中进行微信支付的情况。
同样,先看官方流程图:
同样根据官方的图来梳理:
2.1 第一步 — 商户平台内部生成订单信息并展示
这一步一般是在用户进入支付页面时完成的,所谓平台内部生成订单,实际上就是指生成:
订单信息价格…
以上这些信息是完全与微信平台无关联的,由商户平台内部完成。
这一步在三种支付方式中是相同的,因为这一步跟微信平台之间并没有关系。
2.2 第二步 — 用户点击支付按钮,商户平台生成订单
这一步是在用户点击了支付按钮后进行,由商户平台前端发起请求,后端调用微信提供的 H5 下单API,生成预支付订单,并向前端返回H5支付中间页链接 h5_url
h5_url为拉起微信支付收银台的中间页面,可通过访问该URL来拉起微信客户端,完成支付,h5_url的有效期为5分钟。
2.3 第三步 — 向 code_url 中添加参数,完成跳转
在 Native 方式中,用户要进行支付,需要扫描包含了 code_url 信息的二维码,在手机上完成支付。但在 H5 方式中,由于用户本身就处于移动端,所以不再需要二维码的参与。
但是,与 Native 方式不同的是,H5 支付完成后,需要跳转回商户平台的支付页面。因此,这时,我们需要主动向 h5_url 中添加参数 redirect_url。
redirect_url 就是用户完成支付后,跳转回去的地址。在 redirect_url 中,除了目标地址,还可以携带一些我们需要的信息,例如平台内部订单的 uuid、订单生成的时间等等。注意,redirect_url 需要进行 urlencode 处理!
接下来,商户平台主动跳转至拼接好的链接url。
2.4 第四步 — 用户进行支付操作,跳转回指定页面
用户跳转到微信支付页面后,进行支付操作,订单可能存在两种状态:
订单未完成/失败订单已完成
无论哪种状态,在用户完成操作后,都会跳转至前面指定的 redirect_url。
2.5 第五步 — 回到商户平台支付页面
在微信官方的文档中,给出了H5支付完成后,跳回商户平台后的操作标准:
由于设置 redirect_url 后,回跳指定页面的操作可能发生在:
微信支付中间页调起微信收银台后超过5秒。用户点击“取消支付”或支付完成后点击“完成”按钮。因此无法保证页面回跳时,支付流程已结束,所以商户设置的redirect_url地址不能自动执行查单操作,应让用户去点击按钮触发查单操作。
所以,在具体实现时,我们一般会在 redirect_url 中添加一项标识,用以标记此时是从 h5 支付页跳转回来的情况。然后,弹出弹框,向用户提供【确认订单状态】和【重新支付】的两个按钮,可以参考下图:
2.6 第六步 — 商户后台查询订单状态
在用户完成支付后,商户后台会接收到微信平台的通知。
所以,当用户在浏览器中点击【确认订单状态】按钮,进行订单的确认时,商户前台会调用后端提供的查询订单接口。
在商户后台,可以先查询是否接收到微信平台的通知,如果接收到了通知,则直接将订单状态返回给前端;如果还没有接收到通知,则主动调取微信平台的查询订单API,查询订单状态,然后将订单状态返回给前端。
前端接收到订单状态后:
若订单已完成,则进行下一步操作,一般是跳转页面等若订单未完成,则停留在当前页面,并提示用户订单未支付,让用户重新支付
当然,也可能用户主动点击【重新支付】按钮,此时商户平台可以根据业务需求,进行处理。
3. JSAPI 方式 — 移动端微信浏览器
当用户在微信中,打开商户平台时,会进入微信自带的浏览器中,在该情况下进行微信支付时,需要使用微信支付提供的 JSAPI 接口,在支付场景中调起微信支付模块。
官方文档中的流程图如下:
但在 JSAPI 支付方式中,实际的实现流程可能与官方的流程图不太一样,这里按实际开发中的流程来进行梳理:
3.1 第一步 — 商户平台内部生成订单信息并展示
同样的,JSAPI 支付中这一步也是必须的,主要目的仍然是展示订单的相关信息
订单信息价格…
以上这些信息是完全与微信平台无关联的,由商户平台内部完成。
3.2 第二步 — 用户发起支付,跳转链接完成微信授权
用户点击支付按钮后,商户平台前端需要携带一些信息(例如:回跳链接、标识等),平台内部调取单独微信授权模块模块完成微信授权。(注意,这里的微信授权模块是平台内部封装的)
该模块完成微信授权后,会将微信授权码 auth_code 附带在我们之前传递的回跳链接后面,然后跳转至回跳链接。
在微信支付场景下,这里的回跳链接实际上就是商户平台的支付页。
3.3 第三步 — 商户平台前端拿到授权码,跳转平台支付模块
在上一步中,商户平台前端拿到了微信授权码 auth_code。
接下来,商户平台前端需要调取后端接口,根据当前的 token 获取 ticket。然后,准备好一系列参数 postParam。
其中包括:
平台业务相关参数用户 ticket平台内部订单信息支付方式标识微信授权码…
同时,我们还需要准备好完成支付后跳转回支付页面的链接 redirect_url,该链接中需要包含以下信息:
当前页面url平台内部订单uuid平台内部业务相关参数一些标识…
接下来,我们携带着这两项数据,访问平台内部封装好的支付模块。(注意,这两项数据需要进行 urlencode 处理!)
3.4 第四步 — 平台支付模块调起微信支付
进入平台内部支付模块后,该模块会根据我们传入的数据,调取微信支付提供的 JSAPI,调起微信支付。
3.5 第五步 — 用户完成支付操作
调起微信支付后,用户进行操作,并最终向微信支付系统发起支付请求,微信支付系统验证支付授权权限后,返回支付授权,然后用户确认支付后,输入密码,提交,微信支付系统进行校验,最终完成支付操作。这里对应的就是官方流程图中的 9~14 步。
当然,这个操作过程中,也可能存在其他情况,例如:用户取消支付、用户支付失败等等。
所以,平台支付模块中会向微信支付提供处理这些情况的回调函数,当出现这些情况时,就会触发回调。在这些回调函数中,平台可以根据业务需求进行处理。
总之,待用户完成支付操作后,最终会跳转回商户平台的支付页面。
3.6 第六步 — 平台获取支付结果并通知用户
平台获取支付结果,可以分为两个并行的场景:
用户完成支付后,微信支付系统,异步地通知平台支付结果用户主动查询订单支付状态,此时商户平台调取查询订单接口,并返回通知用户
PS
在 JSAPI 支付方式中,【获取微信授权】和【微信支付】这两个平台内部模块的实现比较复杂,后续可以在微信支付实例分析中进行详细的介绍。