简体中文
请求支付
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 | 是 | - | - | |||||||||||||||||||||||||||||||||||||
|
名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 |
---|---|---|---|---|---|
data | any | 否 | - | 返回数据 |
名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 | ||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
errCode | number | 是 | - | - | 错误码 | ||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||
errSubject | string | 是 | - | - | 统一错误主题(模块)名称 | ||||||||||||||||||||||||||||||||||||||||||
data | any | 否 | - | - | 错误信息中包含的数据 | ||||||||||||||||||||||||||||||||||||||||||
cause | Error | 否 | - | - | 源错误信息,可以包含多个错误,详见SourceError | ||||||||||||||||||||||||||||||||||||||||||
errMsg | string | 是 | - | - | - |
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×tamp=2016-08-15%2012%3A12%3A15&version=1.0&sign=MsbylYkCzlfYLy9PeRwUUIg9nZPeN9SfXPNavUCroGKR5Kqvx0nEnd3eRmKxJuthNUx4ERCXe552
EV9PfwexqW%2B1wbKOdYtDIb4%2B7PL3Pc94RZL0zKaWcaY3tSL89%2FuAVUsQuFqEJd
hIukuKygrXucvejOUgTCfoUdwTi7z%2BZzQ%3D<br>
[更多详情参考支付宝官方文档]
{
"appid":"wxd569c7238830733b",
"noncestr":"6N47VnR42bqIm4xq",
"package":"Sign=WXPay",
"partnerid":"1230636401",
"prepayid":"wx26174750316675ac54b89c224eb3250000",
"timestamp":1711446470,
"sign":"EE987459B9CFF6462462147130110D31"
}
[更多详情参考微信官方文档]
UniPaymentAlipayProvider(支付宝支付)继承自 UniProvider
UniPaymentWxpayProvider(微信支付)继承自 UniProvider,特有字段说明:
名称 | 类型 | 必备 | 默认值 | 描述 |
---|---|---|---|---|
isWeChatInstalled | boolean | 是 | - | 判断微信是否安装 |
支付失败时可通过错误回调参数IRequestPaymentFail
中的cause
属性获取支付SDK的源错误信息,类型为SourceError,其包含 code 属性存储了支付SDK的原始错误码。
支付宝错误码 | 错误信息 |
---|---|
9000 | 订单支付成功 |
8000 | 正在处理中,支付结果未知(有可能已经支付成功),请查询商家订单列表中订单的支付状态 |
4000 | 订单支付失败 |
5000 | 重复请求 |
6001 | 用户中途取消 |
6002 | 网络连接出错 |
6004 | 支付结果未知(有可能已经支付成功),请查询商家订单列表中订单的支付状态 |
其它 | 其它支付错误 |
微信支付错误码 | 错误信息 |
---|---|
0 | 成功 |
-1 | 可能的原因:签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常原因等 |
-2 | 无需处理。发生场景:用户不支付了,点击取消,返回APP |
-3 | 发送失败 |
-4 | 授权被拒绝 |
-5 | 不支持 |
-6 | 禁止 |
其它 | 其它支付错误 |
uni.getProvider
的方式,详见uni.getProvider 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);
}
})
uni-payment
节点,详见 https://doc.dcloud.net.cn/uni-app-x/collocation/manifest-modules.html#uni-payment模块配置该 API 不支持 Web,请运行 hello uni-app x 到 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>
名称 | 类型 | 必备 | 默认值 | 兼容性 | 描述 |
---|---|---|---|---|---|
errMsg | string | 是 | - | - | 错误信息 |
App平台,微信和支付宝的SDK,除了requestPayment API封装的功能,还有一些其他功能。如开发者需要调用这些SDK的其他API,可以使用uts直接调用(注意打包时勾选相应的模块)
可以参考uni.requestPayment的源码,也是通过uts调用这2个原生SDK:
背景:目前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支付宝支付插件的实现源码