FORMA

支付中转页面升级实践

背景

本次需求是支付链路升级:在兼容原有支付能力的基础上,新增不同版本的支付方案(如原生微信支付、小程序拉起支付)。

升级动因主要有两点:

  • 旧链路能力单一,面对不同支付场景时扩展性不足;
  • 新商家小程序上线后,支付入口和参数形态更加多样,需要统一中转层承接。

另外,第三方支付链路涉及签名与加解密,复杂逻辑统一下沉后端实现,前端以接口返回结果为准,减少前端安全风险与维护成本。


整体思路

构建一个统一的 H5 支付中转页面,负责:

  • 统一接收并兼容不同来源的支付参数;
  • 兼容扫码场景下的 query 解析差异;
  • 按支付版本动态分流到不同支付方式;
  • 在异常场景下提供兜底回退(默认原生微信支付)。

流程示意图:

效果


关键实现细节

1) H5 页面拉起小程序

在微信 H5 中拉起小程序可使用开放标签 wx-open-launch-weapp

html
<wx-open-launch-weapp
  id="launch-btn"
  appid="wx12345678"
  path="pages/home/index?user=123&action=abc"
>
  <script type="text/wxtag-template">
    <style>
      .btn {
        padding: 12px;
      }
    </style>
    <button class="btn">打开小程序</button>
  </script>
</wx-open-launch-weapp>
<script>
  const btn = document.getElementById("launch-btn");
  btn.addEventListener("launch", () => console.log("success"));
  btn.addEventListener("error", (e) => console.log("fail", e.detail));
</script>

接入前提:开放标签可用前,必须先完成 wx.config 校验:

javascript
wx.config({
  debug: true,
  appId: "",
  timestamp: 0,
  nonceStr: "",
  signature: "",
  jsApiList: [],
  openTagList: [], // 例如 ["wx-open-launch-weapp"]
});

wx.ready(function () {
  // config 校验成功后,开放标签能力才可用
});

wx.error(function (res) {
  // 签名过期或参数错误时可在此上报并重拉签名
});

注意事项:

  • 只有 config 成功后,开放标签才会正常渲染与点击;
  • text/wxtag-template 内样式需写在模板内部,不可完全依赖页面外部样式。

2) 支付参数兼容与解析

由于不同入口参数形态不统一(普通 query 与拼接 param 并存),中转页需要先做解析归一:

javascript
getUrlQuery() {
  const { param = "" } = this.$route.query || {};
  const hasParam = Object.keys(this.$route.query).includes("param");
  return hasParam ? handlerQueryParams(param) : this.$route.query;
}

// 示例:
// http://xxx.com/payPage?param=businessType:9;payId:1668909350495006721;totalAmt:100000
export function handlerQueryParams(url) {
  const splitArr = url.split(";").filter((item) => item !== "");
  const query = {};
  splitArr.forEach((item) => {
    const index = item.indexOf(":");
    if (index !== -1) {
      const key = item.substring(0, index);
      const val = item.substring(index + 1);
      query[key] = val;
    }
  });
  return query;
}

3) 多版本支付分流

根据后端返回版本号(如 V1/V2/V3)决定支付方式:

javascript
// 需要跳转小程序支付
isPayWeapp() {
  return ["V2", "V3"].includes(this.version);
},

// 需要原生微信支付
// 接口异常或未知版本时建议兜底到原生支付
isPayWx() {
  return ["V1"].includes(this.version);
}

原生微信支付示例:

javascript
wxJsBridge(
  {
    appId: wxJsBridgeJson.appId,
    timeStamp: wxJsBridgeJson.timeStamp,
    nonceStr: wxJsBridgeJson.nonceStr,
    package: wxJsBridgeJson.package,
    signType: wxJsBridgeJson.signType,
    paySign: wxJsBridgeJson.sign,
  },
  () => {}
);

结论

通过“统一中转页 + 参数归一 + 版本分流 + 后端加解密下沉”,可以在不破坏旧能力的前提下平滑引入新支付方案,并显著降低多入口支付链路的维护复杂度。

相关文章