uni-app App平台下调用H5支付

uni-app App 环境下调用 H5 支付

💡 这里调用 H5,主要是业务层面的原因,建议优先使用 SDK 调用微信支付宝的 App 进行支付,体验要好得多。

支付宝

后台返回的是表单数据,在浏览器环境中,一般都是通过插入表单,然后提交的方式进行支付

const div = document.createElement('divform');
div.innerHTML = res.data.data;
document.body.appendChild(div);
document.forms[0].submit();

在 APP 下,缺少相应的环境(DOM,BOM),显然不能使用这种方式。

这时候,可以使用 uniapp 的 web-view 组件来实现。

基本步骤如下:

  1. 先在页面中写入 web-view 组件,默认不渲染,不显示,因为 web-view 会自动铺满页面(nvue 除外)。 webview 组件文档

  2. 从后台获取到表单数据,然后正则匹配,拿到需要的数据,对数据进行拼接,获取完整的支付 URL

    这里主要进行的操作就是将 input 表单中的 biz_content 和它的值作为参数拼接到 URL 上,需要先从 HTML 实体转义成正常字符,然后再进行 URL 编码,最后拼接为完成的 URL。

    💡 注:需要根据后端返回的表单数据做不同的处理,方法是通用的,就是将表单提交的形式,改 URL 跳转的形式。 基本流程:

    1. 将后台返回的表单提交,获取到表单提交的 URL。
    2. 将表单的各个参数拼接成这个 URL

伪代码实现:

<template>
  <view class="alipay-example">
    <!-- #ifdef APP-PLUS -->
    <!-- APP下用WebView跳转实现唤醒支付 -->
    <web-view :src="webViewUrl" v-if="webViewUrl !== ''"></web-view>
    <!-- #endif -->
  </view>
</template>

<script>
export default {
  name: 'alipayExample',
  data() {
    return {
      webViewUrl: ''
    };
  },
  methods: {
    alipay() {
      this.$x
        .post('后端API地址', {
          // POST 发送的数据
          foo: "bar"
        })
        .then(res => {
          if (res.data.status !== 1) {
            this.$showMsg(res.data.msg);
            return;
          }
          
          // #ifdef H5
          const div = document.createElement('divform');
          div.innerHTML = res.data.data;
          document.body.appendChild(div);
          document.forms[0].submit();
          // #endif
          
          // #ifdef APP-PLUS
          let formData = res.data.data;
          let alipayUrl = 从表单中获取数据然后进行拼接,返回得到的URL(formData);
          this.webViewUrl = alipayUrl;
          // #endif
        });
    }
  }
};
</script>

<style scoped></style>

微信

微信端和支付宝的方法类似,但是微信支付页面会对 Headers 头的 Referer 字段进行验证,验证请求来源是不是商户申请 H5 时提交的授权域名。 【微信支付】H5 支付开发文档

如果验证不通过,会提示:商家参数格式有误,请联系商家解决

这也是在本地,前端开发调试微信支付提示错误,在服务器上就没有问题的原因。

web-view 这个组件不支持自定义 Referer 字段,这里需要使用 uni-app 在 APP 环境下的 API,创建一个 WebView 窗口来实现。 API 文档:WebView

WebviewObject plus.webview.create( url, id, styles, extras );

从后台获取到微信支付的 URL 之后,实现的伪代码如下:

// #ifdef APP-PLUS
// Referer的值为商户申请H5时提交的授权域名
let payView = plus.webview.create(res.data.data.h5PayUrl, 'payView', { additionalHttpHeaders: { Referer: this.http.web } });
// WebView窗口页面加载完成事件
payView.onloaded = () => {
  payView.show();
  setTimeout(() => {
    payView.close();
    uni.switchTab({
      url: '../my/my'
    });
  }, 2000);
};
// #endif

iOS 下微信支付完成后跳转到 Safari 浏览器而不是 App

💡 思路和流程

微信 H5 支付的链接地址里,有 redirect_url 这个参数,这个是支付结束(完成支付或者是取消支付)后跳转的地址。

把这个参数的值修改为,App 注册的 Scheme,这样就可以跳转回 App。

同时还需要注意,redirect_url 参数有校验,需要使用在微信支付后台添加的白名单中的域名才可以。