# uni.requestPayment(options)

请求支付

# requestPayment 兼容性

Web Android iOS
x 4.02 4.18

uni.requestPayment是一个统一各平台的客户端支付API,客户端均使用本API调用支付。

本API运行在各端时,会自动转换为各端的原生支付调用API。

注意支付不仅仅需要客户端的开发,还需要服务端开发。虽然客户端API统一了,但各平台的支付申请开通、配置回填仍然需要看各个平台本身的支付文档。

比如微信有App支付的申请入口和使用流程,对应到uni-app,在App端要申请微信的App支付。

如果服务端使用uniCloud,那么官方提供了uniPay云端统一支付服务,把App、微信小程序、支付宝小程序里的服务端支付开发进行了统一的封装。

前端统一的uni.requestPayment和云端统一的uniPay搭配,可以极大提升支付业务的开发效率,强烈推荐给开发者使用。uniPay的文档另见:https://doc.dcloud.net.cn/uniCloud/uni-pay/uni-app.html

# 参数

名称 类型 必填 默认值 兼容性 描述
options RequestPaymentOptions - -
名称 类型 必备 默认值 兼容性 描述
provider string -
支付服务提供商,通过 uni.getProvider 获取,目前支持支付宝支付(alipay),微信支付(wxpay)
orderInfo string -
订单数据
success (result: RequestPaymentSuccess) => void -
接口调用成功的回调函数
fail (result: IRequestPaymentFail) => void -
接口调用失败的回调函数
complete (result: any) => void -
接口调用结束的回调函数(调用成功、失败都会执行)

# RequestPaymentSuccess 的属性值

名称 类型 必备 默认值 兼容性 描述
data any -
返回数据

# IRequestPaymentFail 的属性值

名称 类型 必备 默认值 兼容性 描述
errCode number - - 错误码
合法值 兼容性 描述
700000
其它支付错误。
700600
正在处理中,支付结果未知(有可能已经支付成功),请查询商家订单列表中订单的支付状态
700601
用户中途取消。
700602
网络连接出错。
700603
支付结果未知(有可能已经支付成功),请查询商家订单列表中订单的支付状态。
700604
微信没有安装。
700605
服务供应商获取失败。
700607
支付未完成。
700608
服务商返回参数错误。
700800
没有配置对应的URL Scheme。
700801
没有配置对应的Universal Link。
701100
订单支付失败。
701110
重复请求。
errSubject string - - 统一错误主题(模块)名称
data any - - 错误信息中包含的数据
cause Error - - 源错误信息,可以包含多个错误,详见SourceError
errMsg string - - -

# orderInfo参数说明

  • 支付宝支付 App 支付请求参数字符串,主要包含商家的订单信息,key=value 形式,以 & 连接。示例
app_id=2015052600090779&biz_content=%7B%22timeout_express%22%3A%2230m%22%2C%22seller_id%22%3A%22%22%2C%22product_code%
22%3A%22QUICK_MSECURITY_PAY%22%2C%22total_amount%22%3A%220.02%22%2C%22subject%22%3A%221%22%2C%22body%22%3A%22%E6%88%
91%E6%98%AF%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE%22
%2C%22out_trade_no%22%3A%22314VYGIAGG7ZOYY%22%7D&charset=utf-8&method=alipay.trade.app.pay&sign_type=R
SA2&timestamp=2016-08-15%2012%3A12%3A15&version=1.0&sign=MsbylYkCzlfYLy9PeRwUUIg9nZPeN9SfXPNavUCroGKR5Kqvx0nEnd3eRmKxJuthNUx4ERCXe552
EV9PfwexqW%2B1wbKOdYtDIb4%2B7PL3Pc94RZL0zKaWcaY3tSL89%2FuAVUsQuFqEJd
hIukuKygrXucvejOUgTCfoUdwTi7z%2BZzQ%3D<br>

[更多详情参考支付宝官方文档]

  • 微信支付 App 支付请求参数字符串,需要打自定义基座。示例
{
 "appid":"wxd569c7238830733b",
 "noncestr":"6N47VnR42bqIm4xq",
 "package":"Sign=WXPay",
 "partnerid":"1230636401",
 "prepayid":"wx26174750316675ac54b89c224eb3250000",
 "timestamp":1711446470,
 "sign":"EE987459B9CFF6462462147130110D31"
}

[更多详情参考微信官方文档]

# 参见

# 支付provider对象描述

UniPaymentAlipayProvider(支付宝支付)继承自 UniProvider

UniPaymentWxpayProvider(微信支付)继承自 UniProvider,特有字段说明:

名称 类型 必备 默认值 描述
isWeChatInstalled boolean - 判断微信是否安装

# 支付SDK错误码

支付失败时可通过错误回调参数IRequestPaymentFail中的cause属性获取支付SDK的源错误信息,类型为SourceError,其包含 code 属性存储了支付SDK的原始错误码。

# 支付宝支付

支付宝错误码 错误信息
9000 订单支付成功
8000 正在处理中,支付结果未知(有可能已经支付成功),请查询商家订单列表中订单的支付状态
4000 订单支付失败
5000 重复请求
6001 用户中途取消
6002 网络连接出错
6004 支付结果未知(有可能已经支付成功),请查询商家订单列表中订单的支付状态
其它 其它支付错误

# 微信支付

微信支付错误码 错误信息
0 成功
-1 可能的原因:签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常原因等
-2 无需处理。发生场景:用户不支付了,点击取消,返回APP
-3 发送失败
-4 授权被拒绝
-5 不支持
-6 禁止
其它 其它支付错误

# 注意

  • App平台开发支付宝支付,无需自定义基座,真机运行可直接开发
  • App平台判断微信是否安装可以通过uni.getProvider的方式,详见uni.getProvider
  • 在4.25版本前使用微信支付,Android需要在隐私协议弹框后调用微信sdk
   uni.getProvider({
      service: "payment",
      success: (e) => {
         const provider = e.providers.find((item): boolean => {
            return item.id == 'wxpay'
         })

          // #ifdef APP-ANDROID
          if (provider != null && provider instanceof UniPaymentWxpayProvider && !((provider as UniPaymentWxpayProvider).isWeChatInstalled)) {
            console.log('WeChat 没有安装')
          } else {
             console.log('WeChat 已安装')
          }
          // #endif
          // #ifdef APP-IOS
          if (provider != null && ((provider as UniPaymentWxpayProvider).isWeChatInstalled == undefined || ((provider as UniPaymentWxpayProvider).isWeChatInstalled != null && (provider as UniPaymentWxpayProvider).isWeChatInstalled == false))) {
            console.log('WeChat 没有安装')
          } else {
            console.log('WeChat 已安装')
          }
          // #endif
      },
      fail: (e) => {
         console.log("获取支付通道失败:", e);
      }
   })

# 示例

hello uni-app x

该 API 不支持 Web,请运行 hello uni-app x 到 App 平台体验

扫码体验(手机浏览器跳转到App直达页)
<template>
  <page-head title="发起支付"></page-head>

  <template v-if="providerList.length > 0">
    <button style="margin-top: 20px;" type="primary" v-for="(item,index) in providerList" :key="index"
      @click="requestPayment(item)">{{item.name}}</button>
  </template>
</template>

<script>
  export type PayItem = { id : string, name : string, provider ?: UniProvider }
  export default {
    data() {
      return {
        btnText: "支付宝支付",
        btnType: "primary",
        orderInfo: "",
        errorCode: 0,
        errorMsg: "",
        complete: false,
        providerList: [] as PayItem[]
      }
    },
    onLoad: function () {
      let provider = uni.getProviderSync({
        service: "payment",
      } as GetProviderSyncOptions)
      console.log(provider)
      provider.providerObjects.forEach((value : UniProvider) => {
        switch (value.id) {
          case 'alipay':
            var aliPayProvider = value as UniPaymentAlipayProvider
            console.log('alipay', aliPayProvider)
            this.providerList.push({
              name: aliPayProvider.description,
              id: aliPayProvider.id,
              provider: aliPayProvider
            } as PayItem);
            break;
          case 'wxpay':
            var wxPayProvider = value as UniPaymentWxpayProvider
            console.log('wxpay', wxPayProvider)
            this.providerList.push({
              name: wxPayProvider.description,
              id: wxPayProvider.id,
              provider: wxPayProvider
            } as PayItem);
            break;
          default:
            break;
        }
      })
    },
    methods: {
      requestPayment(e : PayItem) {
        const provider = e.id
        if (provider == "alipay") {
          this.payAli(provider)
        } else if (provider == "wxpay") {
          // #ifdef APP-ANDROID
          if (e.provider != null && e.provider instanceof UniPaymentWxpayProvider && !((e.provider as UniPaymentWxpayProvider).isWeChatInstalled)) {
            uni.showToast({
              title: "微信没有安装",
              icon: 'error'
            })
          } else {
            this.payWX(provider)
          }
          // #endif
          // #ifdef APP-IOS
          if (e.provider != null && ((e.provider as UniPaymentWxpayProvider).isWeChatInstalled == undefined || ((e.provider as UniPaymentWxpayProvider).isWeChatInstalled != null && (e.provider as UniPaymentWxpayProvider).isWeChatInstalled == false))) {
            uni.showToast({
              title: "微信没有安装",
              icon: 'error'
            })
          } else {
            this.payWX(provider)
          }
          // #endif
        }
      },
      payAli(id:string) {
        uni.showLoading({
          title: "请求中..."
        })
        uni.request({
          url: 'https://demo.dcloud.net.cn/payment/alipay/?total=0.01',
          method: 'GET',
          timeout: 6000,
          success: (res) => {
            this.orderInfo = JSON.stringify(res.data);
            console.log("====" + this.orderInfo)
            uni.hideLoading()
            uni.requestPayment({
              provider: id,
              orderInfo: res.data as string,
              fail: (res) => {
                console.log(JSON.stringify(res))
                this.errorCode = res.errCode
                uni.showToast({
                  icon: 'error',
                  title: 'errorCode:' + this.errorCode
                });
              },
              success: (res) => {
                console.log(JSON.stringify(res))
                uni.showToast({
                  icon: 'success',
                  title: '支付成功'
                });
              }
            })
          },
          fail: (e) => {
            console.log(e)
            uni.hideLoading()
          },
        });
      },
      payWX(id:string) {
        uni.showLoading({
          title: "请求中..."
        })
        let url = 'https://demo.dcloud.net.cn/payment/wxpayv3.__UNI__uniappx/?total=0.01'
        const res = uni.getAppBaseInfo();
        let packageName : string | null

        // #ifdef APP-ANDROID
        packageName = res.packageName
        // #endif

        // #ifdef APP-IOS
        packageName = res.bundleId
        // #endif

        if (packageName == 'io.dcloud.hellouniappx') {//hello uniappx
          url = 'https://demo.dcloud.net.cn/payment/wxpayv3.__UNI__HelloUniAppX/?total=0.01'
        }
        uni.request({
          url: url,
          method: 'GET',
          timeout: 6000,
          header: {
            "Content-Type": "application/json"
          } as UTSJSONObject,
          success: (res) => {
            console.log(res.data)
            uni.hideLoading()
            uni.requestPayment({
              provider: id,
              orderInfo: JSON.stringify(res.data),
              fail: (res) => {
                console.log(JSON.stringify(res))
                this.errorCode = res.errCode
                uni.showToast({
                  duration: 5000,
                  icon: 'error',
                  title: 'errorCode:' + this.errorCode,
                });
              },
              success: (res) => {
                console.log(JSON.stringify(res))
                uni.showToast({
                  duration: 5000,
                  icon: 'success',
                  title: '支付成功'
                });
              }
            })
          },
          fail: (res) => {
            uni.hideLoading()
            console.log(res)
          },
        });
      },

      //自动化测试使用
      jest_pay() {
        uni.requestPayment({
          provider: "alipay",
          orderInfo: this.orderInfo,
          fail: (res : RequestPaymentFail) => {
            this.errorCode = res.errCode
            this.complete = true
          },
          success: (res : RequestPaymentSuccess) => {
            console.log(JSON.stringify(res))
            this.complete = true
          }
        } as RequestPaymentOptions)
      }
    }
  }
</script>

<style>

</style>

# 通用类型

# GeneralCallbackResult

名称 类型 必备 默认值 兼容性 描述
errMsg string - - 错误信息

# API源码和更多SDK功能

App平台,微信和支付宝的SDK,除了requestPayment API封装的功能,还有一些其他功能。如开发者需要调用这些SDK的其他API,可以使用uts直接调用(注意打包时勾选相应的模块)

可以参考uni.requestPayment的源码,也是通过uts调用这2个原生SDK:

# 自定义支付provider接入到uni API

背景:目前uni-app x引擎已经内置了支付宝支付、微信支付。但支付SDK还有很多,比如银联SDK。

以往这些SDK可以通过独立插件的方式集成到uni-app x中,但需要提供单独的API给开发者使用。

uni-app x从4.25起,开放了provider自接入机制,让三方SDK可以以provider方式被开发者集成。

开发一个UTS插件,对接uni规范化的API、错误信息描述等实现自己的支付插件,这样插件使用者就可以通过uni的标准API使用三方SDK。

举个例子,开发者想使用uni.requestPayment()的方式调用XX支付,但是内置支付api不支持,

那只需要按照下面四个步骤实现即可:

第一步,新建一个UTS插件,在interface.uts 中定义接口,继承UniPaymentProvider,代码如下

export interface UniPaymentAlipayProvider extends UniPaymentProvider{}

第二步,在app-android或者app-ios的index.uts中实现接口,代码如下

import { UniPaymentAlipayProvider } from '../interface.uts'
export class UniPaymentAlipayProviderImpl implements UniPaymentAlipayProvider{
	override id : String = "XX" // id必须有插件作者前缀,避免冲突,避免不同插件作者的插件id重名
	override description : String = "XX的描述"
	override isAppExist : boolean | null = null

	constructor(){}

	override requestPayment(options : RequestPaymentOptions) {
		//todo 具体逻辑,接收uni规范的入参,进行业务处理,返回uni规范的返回值。如遇到错误,按uni的规范返回错误码
	}
}

第三步,在manifest.json中配置

  "app": {
    "distribute": {
      /* android打包配置 */
      "modules": {
        "uni-payment":{
          "XX":{}
        }
      }
    }
  }

第四步,打包自定义基座然后运行

由于uni-app x内置的支付API也是基于这套规范实现的,所以推荐参考 uni-app x支付宝支付插件的实现源码