关于在微信公众号唤起微信支付

336 阅读2分钟

准备工作

1.设置支付目录

请确保实际支付时的请求目录与后台配置的目录一致,否则将无法成功唤起微信支付。在微信商户平台(pay.weixin.qq.com)设置您的公众号支付支付目录,设置路径:商户平台-->产品中心-->开发配置,如下图所示。公众号支付在请求支付的时候会校验请求来源是否有在商户平台做了配置,所以必须确保支付目录已经正确的被配置,否则将验证失败,请求支付不成功。

2.设置授权域名

开发公众号支付时,在统一下单接口中要求必传用户openid,而获取openid则需要您在公众平台设置获取openid的域名,只有被设置过的域名才是一个有效的获取openid的域名,否则将获取失败。

以下是大体流程及其注意事项和代码示例

  1. 前端调用后台接口,调用微信统一下单接口
  2. 实现统一下单接口,获取微信服务器返回预订单id和签名
  3. 调取微信支付接口,完成支付
  4. 跳转回调函数 ,反馈微信服务器,查询支付结果

注意 WeixinJSBridge内置对象在其他浏览器中无效,在 iframe 内必须在最顶层框架才有此对象

还要注意取消支付后的流程,这里要看服务端接口来进行优化。一般接口是一个订单可以下多个微信订单,如果不可以的话就要重新创建订单再重新走一遍流程

invoke方法简单有效,直接根据接口返回参数唤起,以下代码示例是vue3环境下的

// 微信支付检验
const handleWechatPay = () => {
  let open_id = JSON.parse(localStorage.getItem("OPENID"));
  if (!open_id) {
    return Toast({
      type: "error",
      message: "微信授权失败,请重新打开页面",
      duration: 3000,
    });
  }

  wechatPayRequest(open_id);
};

// 根据接口返回参数唤起微信支付
const wechatPayRequest = (open_id) => {
  cardTopUp({
    payWay: 1,
    channelOpenId: open_id,
    payAmount: util.div(amount.value, 100),
    orderNo: orderNo.value,
  })
    .then((res) => {
      console.log(res);
      if (res.code === "C00") {
        let { appId, timeStamp, nonceStr, signType, paySign, packageVal } =
          res.response_data;
        WeixinJSBridge.invoke(
          "getBrandWCPayRequest",
          {
            appId: appId,
            timeStamp: timeStamp,
            nonceStr: nonceStr,
            signType: signType,
            paySign: paySign,
            package: packageVal,
          },
          (res) => {
            if (res.err_msg == "get_brand_wcpay_request:ok") {
              queryPayResult();
            } else if (res.err_msg == "get_brand_wcpay_request:fail") {
              router.push({ path: "/payResError", query: { msg: res.msg } });
            }
            // get_brand_wcpay_request:cancel
          },
        );
      }
    })
    .catch((err) => {
      console.log(err);
    });
};
// 查询支付结果
const queryPayResult = () => {
  cardTopUpState({
    //参数数据
    orderNo: orderNo.value,
    payWay: 1,
  })
    .then((res) => {
      console.log("查询支付返回", res);
      if (res.code === "C00") {
        //完成支付
        router.push({
          path: "/payResSuccess",
          query: {
            amount: amount.value,
            org_name: org_name.value,
            type: "recharge",
          },
        });
      }
    })
    .catch((err) => {
      router.push({ path: "/payResError", query: { msg: err.msg } });
      console.log(err);
    });
};