微信内H5网页调起微信支付

3,984 阅读2分钟

首先,官方文档里介绍了不同场景下的微信支付对应的API,这里,我要实现的最终效果是,在微信内聊天窗口打开网页链接,进行支付操作,所以我用到的是JSAPI支付

1. 接入准备

在开始开发之前,我们需要进行一些准备工作。

  1. 微信公众平台提交微信支付申请(提供营业执照、银行账户等)
  2. 微信官方审核通过后,会给你发送一个邮件 (从邮件可得到商户号、微信商户平台的账号和密码)
  3. 在线签署微信支付服务协议
  4. 将商户号和公众号关联 (绑定商户号和appid才能使用)

2. 开发准备

  1. 在微信商户平台设置JSAPI支付支付目录

JSAPI支付在请求支付的时候会校验请求来源是否有在商户平台做了配置,所以必须确保支付目录已经正确的被配置,否则将验证失败,请求支付不成功。

  1. 公众平台 - 设置授权回调域名 (用于获取openid)

3. 开发过程

步骤简单来说就是:

  1. 获取签名等参数 (后台获取签名等参数,传给前端)
  2. 调起微信支付,用户进行支付
  3. 获得支付成功(或失败)的结果

其实大部分工作都是在后台完成的,这里我只能写一下前端的操作了。

首先,写个小按钮(特意用了微信绿)。

点击按钮时,调用这个方法:

const isWX = /MicroMessenger/i.test(navigator.userAgent);
const appId = '公众号appId';
payment() {
    if (!isWX) {
        console.error('not weixin');
        return;
    }
    if (typeof window.WeixinJSBridge === 'undefined') {
        if (document.addEventListener) {
            document.addEventListener('WeixinJSBridgeReady', this.onBridgeReady);
        }
    } else {
        this.onBridgeReady();
    }
}

WeixinJSBridge是微信浏览器的内置对象,调起支付就是依赖于这个对象。

async onBridgeReady() {
    if (!window.WeixinJSBridge) return;
    const data = await this.getData();
    if (data) {
        const { timeStamp, nonceStr, packageStr, signType, paySign } = data;
        const params = {
            appId,
            timeStamp,
            nonceStr,
            package: packageStr,
            signType,
            paySign,
        };
        window.WeixinJSBridge.invoke(  // 调起支付
            'getBrandWCPayRequest',
            params,
            res => this.handlePayCallback(res),
        );
    } else {
        console.log('no data');
    }
}

async getData() {
    const params = {
        openid: localStorage.getItem('openId'),
        payNumber: Date.now().toString(),
    };
    const res = await wxPay(params);
    return res.data;
}

这一步,前端把openid(如何获取的另写吧)和订单号(自定义生成)发给后台,后台把getBrandWCPayRequest所需的参数(timeStamp, nonceStr, packageStr, signType, paySign)返回给我。到这里,便成功调起了微信支付,可以进行支付了。

对了,支付的金额0.01元是后台写死的。。。

接下来,就是处理支付的状态(支付成功、支付取消或支付失败)

handlePayCallback(res) {
    if (res.err_msg === 'get_brand_wcpay_request:ok') {
        this.setState({ payStatus: 'success' });
    } else if (res.err_msg === 'get_brand_wcpay_request:cancel') {
        this.setState({ payStatus: 'cancel' });
    } else {
        this.setState({ payStatus: 'failed' });
    }
}

登录微信平台,也可以看到每个订单的详情,到这里,一个微信支付小demo就完成了。

注意:如果是微信小程序内嵌webview网页,是不能用这个方法的,应该属于小程序支付场景。