From 2a5720ddcf9f740c279b883e0ea1965daed7fefc Mon Sep 17 00:00:00 2001 From: VK <370725567@qq.com> Date: Tue, 23 Jul 2024 17:24:55 +0800 Subject: [PATCH] =?UTF-8?q?update:=20uni-pay-x=E6=94=AF=E6=8C=81=E8=8B=B9?= =?UTF-8?q?=E6=9E=9C=E8=99=9A=E6=8B=9F=E6=94=AF=E4=BB=98=EF=BC=88ios?= =?UTF-8?q?=E5=86=85=E8=B4=AD=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/uni-pay/uni-app-x.md | 602 +++++++++++++++++++++++++++++++++++++- 1 file changed, 597 insertions(+), 5 deletions(-) diff --git a/docs/uni-pay/uni-app-x.md b/docs/uni-pay/uni-app-x.md index 413797a..5408343 100644 --- a/docs/uni-pay/uni-app-x.md +++ b/docs/uni-pay/uni-app-x.md @@ -135,13 +135,13 @@ uni-pay-x的[uni_modules](https://uniapp.dcloud.net.cn/plugin/uni_modules.html) 开发者在微信和支付宝的支付后台,需要申请开通支付服务,成功后会得到各种凭据,这些凭据要配置在uni-pay的配置中。 -配置文件在 `uniCloud/cloudfunctions/common/uni-config-center/uni-pay/config.js` +### 完整支付配置示例@config-demo -![](https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni-pay-3.png) +这里是微信、支付宝全平台支付配置样例。如果只使用部分支付方式,后续有专门的分渠道章节。 -### 完整支付配置示例@config-demo +配置文件在 `uniCloud/cloudfunctions/common/uni-config-center/uni-pay/config.js` -这里是支付宝全平台支付配置样例。如果只使用部分支付方式,后续有专门的分渠道章节。 +![](https://web-ext-storage.dcloud.net.cn/unicloud/uni-pay-x/006603df-03c4-4da7-941e-275fae046bf4.png) ```js const fs = require('fs'); @@ -155,6 +155,78 @@ module.exports = { "mp-499e2a37-0c77-418a-82aa-3e5820ecb057": "https://fc-mp-499e2a37-0c77-418a-82aa-3e5820ecb057.next.bspapp.com/uni-pay-co", }, "notifyKey":"5FB2CD73C7B53918728417C50762E6D45FB2CD73C7B53918728417C50762E6D4", // 跨云函数通信时的加密密钥,建议手动改下,不要使用默认的密钥,长度保持在64位以上即可 + // 微信支付相关 + "wxpay": { + "enable": true, // 是否启用微信支付 + // 微信 - 小程序支付 + "mp": { + "appId": "", // 小程序的appid + "secret": "", // 小程序的secret + "mchId": "", // 商户id + "key": "", // v2的api key + "pfx": fs.readFileSync(__dirname + '/wxpay/apiclient_cert.p12'), // v2需要用到的证书 + "v3Key": "", // v3的api key + "appCertPath": path.join(__dirname, 'wxpay/apiclient_cert.pem'), // v3需要用到的证书 + "appPrivateKeyPath": path.join(__dirname, 'wxpay/apiclient_key.pem'), // v3需要用到的证书 + "version": 2, // 启用支付的版本 2代表v2版本 3 代表v3版本 + }, + // 微信 - APP支付 + "app": { + "appId": "", // app开放平台下的应用的appid + "secret": "", // app开放平台下的应用的secret + "mchId": "", // 商户id + "key": "", // v2的api key + "pfx": fs.readFileSync(__dirname + '/wxpay/apiclient_cert.p12'), // v2需要用到的证书 + "v3Key": "", // v3的api key + "appCertPath": path.join(__dirname, 'wxpay/apiclient_cert.pem'), // v3需要用到的证书 + "appPrivateKeyPath": path.join(__dirname, 'wxpay/apiclient_key.pem'), // v3需要用到的证书 + "version": 2, // 启用支付的版本 2代表v2版本 3 代表v3版本 + }, + // 微信 - 扫码支付 + "native": { + "appId": "", // 可以是小程序或公众号或app开放平台下的应用的任意一个appid + "secret": "", // secret + "mchId": "", // 商户id + "key": "", // v2的api key + "pfx": fs.readFileSync(__dirname + '/wxpay/apiclient_cert.p12'), // v2需要用到的证书 + "v3Key": "", // v3的api key + "appCertPath": path.join(__dirname, 'wxpay/apiclient_cert.pem'), // v3需要用到的证书 + "appPrivateKeyPath": path.join(__dirname, 'wxpay/apiclient_key.pem'), // v3需要用到的证书 + "version": 2, // 启用支付的版本 2代表v2版本 3 代表v3版本 + }, + // 微信 - 公众号支付 + "jsapi": { + "appId": "", // 公众号的appid + "secret": "", // 公众号的secret + "mchId": "", // 商户id + "key": "", // v2的api key + "pfx": fs.readFileSync(__dirname + '/wxpay/apiclient_cert.p12'), // v2需要用到的证书 + "v3Key": "", // v3的api key + "appCertPath": path.join(__dirname, 'wxpay/apiclient_cert.pem'), // v3需要用到的证书 + "appPrivateKeyPath": path.join(__dirname, 'wxpay/apiclient_key.pem'), // v3需要用到的证书 + "version": 2, // 启用支付的版本 2代表v2版本 3 代表v3版本 + }, + // 微信 - 手机外部浏览器H5支付 + "mweb": { + "appId": "", // 可以是小程序或公众号或app开放平台下的应用的任意一个appid + "secret": "", // secret + "mchId": "", // 商户id + "key": "", // v2的api key + "pfx": fs.readFileSync(__dirname + '/wxpay/apiclient_cert.p12'), // v2需要用到的证书 + "v3Key": "", // v3的api key + "appCertPath": path.join(__dirname, 'wxpay/apiclient_cert.pem'), // v3需要用到的证书 + "appPrivateKeyPath": path.join(__dirname, 'wxpay/apiclient_key.pem'), // v3需要用到的证书 + "version": 2, // 启用支付的版本 2代表v2版本 3 代表v3版本 + // 场景信息,必填 + "sceneInfo": { + "h5_info": { + "type": "Wap", // 此值固定Wap + "wap_url": "", // 你的H5首页地址,必须和你发起支付的页面的域名一致。 + "wap_name": "", // 你的H5网站名称 + } + } + }, + }, // 支付宝相关(加签方式选证书模式,加密算法选RSA2) "alipay": { "enable": true, // 是否启用支付宝支付 @@ -182,12 +254,86 @@ module.exports = { "alipayPublicCertPath": path.join(__dirname, 'alipay/alipayCertPublicKey_RSA2.crt'), // 支付宝公钥路径 "alipayRootCertPath": path.join(__dirname, 'alipay/alipayRootCert.crt'), // 支付宝根证书路径 } + }, + // ios内购相关 + "appleiap" :{ + // ios内购支付 + "app": { + "password": "", // App 专用共享密钥,App 专用共享密钥是用于接收此 App 自动续期订阅收据的唯一代码。如果您要将此 App 转让给其他开发者或不想公开主共享密钥,建议使用 App 专用共享密钥。非自动续订场景不需要此参数 + "timeout": 10000, // 请求超时时间,单位:毫秒 + "sandbox": false, // 是否是沙箱环境(本地调试ios走的是沙箱环境,故要设置为true,正式发布后,需要设置为false) + } + }, + // 微信虚拟支付 + "wxpay-virtual": { + // 微信 - 小程序支付 + "mp": { + "appId": "", // 小程序的appid + "secret": "", + "mchId": "", // 商户id + "offerId": "", // 支付应用ID + "appKey": "", // 现网AppKey(正式环境) + "sandboxAppKey": "", // 沙箱AppKey + "rate": 100, // 代币兑换比例,比如1元兑换100代币,那么这里就是100(需要开通虚拟支付的时候也设置成 1 人民币 = 100 代币) + "token": "", // 微信小程序通信的token,在开发 - 开发管理 - 消息推送 - Token(令牌) + "encodingAESKey": "", // 必须43位,微信小程序消息加密密钥,在开发 - 开发管理 - 消息推送 - EncodingAESKey(消息加解密密钥) + "sandbox": false, // 是否是沙箱环境(注意:沙箱环境异步回调可能有延迟,建议直接正式环境测试) + } } } ``` 如果你对支付配置中各参数如何获取有疑问,请点击[获取支付配置帮助](#get-config-help) +**注意** + +微信支付同时支持V2版本和V3版本 + +以微信小程序支付为例 + +**V2版本** + +```js +"mp": { + "appId": "", // 小程序的appid + "secret": "", // 小程序的secret + "mchId": "", // 商户id + "key": "", // v2的api key + "pfx": fs.readFileSync(__dirname + '/wxpay/apiclient_cert.p12'), // v2需要用到的证书 + "version": 2, // 启用支付的版本 2代表v2版本 3 代表v3版本 +}, +``` + +**V3版本** + +```js +"mp": { + "appId": "", // 小程序的appid + "secret": "", // 小程序的secret + "mchId": "", // 商户id + "v3Key": "", // v3的api key + "appCertPath": path.join(__dirname, 'wxpay/apiclient_cert.pem'), // v3需要用到的证书 + "appPrivateKeyPath": path.join(__dirname, 'wxpay/apiclient_key.pem'), // v3需要用到的证书 + "version": 3, // 启用支付的版本 2代表v2版本 3 代表v3版本 +}, +``` + +当然你也可以全部配置了,这样可以方便自由切换V2和V3 + +```js +"mp": { + "appId": "", // 小程序的appid + "secret": "", // 小程序的secret + "mchId": "", // 商户id + "key": "", // v2的api key + "pfx": fs.readFileSync(__dirname + '/wxpay/apiclient_cert.p12'), // v2需要用到的证书 + "v3Key": "", // v3的api key + "appCertPath": path.join(__dirname, 'wxpay/apiclient_cert.pem'), // v3需要用到的证书 + "appPrivateKeyPath": path.join(__dirname, 'wxpay/apiclient_key.pem'), // v3需要用到的证书 + "version": 2, // 启用支付的版本 2代表v2版本 3 代表v3版本 +}, +``` + ### 支付回调配置@config-notify 对应支付配置的节点是 `notifyUrl` @@ -230,6 +376,184 @@ module.exports = { 上面的配置样例是微信和支付宝全端配置样例。如果只使用一种支付场景,比如微信公众号里的微信支付,可以看下面章节的分渠道支付配置样例。 +#### 微信APP支付@config-wxpay-app + +对应支付配置的节点是 `wxpay.app` + +```js +const fs = require('fs'); +const path = require('path') +module.exports = { + // 统一 - 支付回调地址,格式为 "服务空间ID":"URL化地址" + "notifyUrl": { + // 测试环境服务空间-支付回调地址 + "mp-b267e273-19a7-4288-99c7-f6f27f9c5b77": "https://fc-mp-b267e273-19a7-4288-99c7-f6f27f9c5b77.next.bspapp.com/uni-pay-co", + // 线上环境服务空间-支付回调地址(如果只有一个服务空间,则只需要配置线上环境服务空间即可) + "mp-499e2a37-0c77-418a-82aa-3e5820ecb057": "https://fc-mp-499e2a37-0c77-418a-82aa-3e5820ecb057.next.bspapp.com/uni-pay-co", + }, + // 微信支付相关 + "wxpay": { + "enable": true, // 是否启用微信支付 + // 微信 - APP支付 + "app": { + "appId": "", // app开放平台下的应用的appid + "secret": "", // app开放平台下的应用的secret + "mchId": "", // 商户id + "key": "", // v2的api key + "pfx": fs.readFileSync(__dirname + '/wxpay/apiclient_cert.p12'), // v2需要用到的证书 + "v3Key": "", // v3的api key + "appCertPath": path.join(__dirname, 'wxpay/apiclient_cert.pem'), // v3需要用到的证书 + "appPrivateKeyPath": path.join(__dirname, 'wxpay/apiclient_key.pem'), // v3需要用到的证书 + "version": 2, // 启用支付的版本 2代表v2版本 3 代表v3版本 + }, + }, +} +``` + +#### 微信小程序支付@config-wxpay-mp + +对应支付配置的节点是 `wxpay.mp` + +```js +const fs = require('fs'); +const path = require('path') +module.exports = { + // 统一 - 支付回调地址,格式为 "服务空间ID":"URL化地址" + "notifyUrl": { + // 测试环境服务空间-支付回调地址 + "mp-b267e273-19a7-4288-99c7-f6f27f9c5b77": "https://fc-mp-b267e273-19a7-4288-99c7-f6f27f9c5b77.next.bspapp.com/uni-pay-co", + // 线上环境服务空间-支付回调地址(如果只有一个服务空间,则只需要配置线上环境服务空间即可) + "mp-499e2a37-0c77-418a-82aa-3e5820ecb057": "https://fc-mp-499e2a37-0c77-418a-82aa-3e5820ecb057.next.bspapp.com/uni-pay-co", + }, + // 微信支付相关 + "wxpay": { + "enable": true, // 是否启用微信支付 + // 微信 - 小程序支付 + "mp": { + "appId": "", // 小程序的appid + "secret": "", // 小程序的secret + "mchId": "", // 商户id + "key": "", // v2的api key + "pfx": fs.readFileSync(__dirname + '/wxpay/apiclient_cert.p12'), // v2需要用到的证书 + "v3Key": "", // v3的api key + "appCertPath": path.join(__dirname, 'wxpay/apiclient_cert.pem'), // v3需要用到的证书 + "appPrivateKeyPath": path.join(__dirname, 'wxpay/apiclient_key.pem'), // v3需要用到的证书 + "version": 2, // 启用支付的版本 2代表v2版本 3 代表v3版本 + }, + }, +} +``` + +#### 微信公众号支付@config-wxpay-jsapi + +对应支付配置的节点是 `wxpay.jsapi` + +```js +const fs = require('fs'); +const path = require('path') +module.exports = { + // 统一 - 支付回调地址,格式为 "服务空间ID":"URL化地址" + "notifyUrl": { + // 测试环境服务空间-支付回调地址 + "mp-b267e273-19a7-4288-99c7-f6f27f9c5b77": "https://fc-mp-b267e273-19a7-4288-99c7-f6f27f9c5b77.next.bspapp.com/uni-pay-co", + // 线上环境服务空间-支付回调地址(如果只有一个服务空间,则只需要配置线上环境服务空间即可) + "mp-499e2a37-0c77-418a-82aa-3e5820ecb057": "https://fc-mp-499e2a37-0c77-418a-82aa-3e5820ecb057.next.bspapp.com/uni-pay-co", + }, + // 微信支付相关 + "wxpay": { + "enable": true, // 是否启用微信支付 + // 微信 - 公众号支付 + "jsapi": { + "appId": "", // 公众号的appid + "secret": "", // 公众号的secret + "mchId": "", // 商户id + "key": "", // v2的api key + "pfx": fs.readFileSync(__dirname + '/wxpay/apiclient_cert.p12'), // v2需要用到的证书 + "v3Key": "", // v3的api key + "appCertPath": path.join(__dirname, 'wxpay/apiclient_cert.pem'), // v3需要用到的证书 + "appPrivateKeyPath": path.join(__dirname, 'wxpay/apiclient_key.pem'), // v3需要用到的证书 + "version": 2, // 启用支付的版本 2代表v2版本 3 代表v3版本 + }, + }, +} +``` + +#### 微信手机外部浏览器H5支付@config-wxpay-mweb + +对应支付配置的节点是 `wxpay.mweb` + +```js +const fs = require('fs'); +const path = require('path') +module.exports = { + // 统一 - 支付回调地址,格式为 "服务空间ID":"URL化地址" + "notifyUrl": { + // 测试环境服务空间-支付回调地址 + "mp-b267e273-19a7-4288-99c7-f6f27f9c5b77": "https://fc-mp-b267e273-19a7-4288-99c7-f6f27f9c5b77.next.bspapp.com/uni-pay-co", + // 线上环境服务空间-支付回调地址(如果只有一个服务空间,则只需要配置线上环境服务空间即可) + "mp-499e2a37-0c77-418a-82aa-3e5820ecb057": "https://fc-mp-499e2a37-0c77-418a-82aa-3e5820ecb057.next.bspapp.com/uni-pay-co", + }, + // 微信支付相关 + "wxpay": { + "enable": true, // 是否启用微信支付 + // 微信 - 手机外部浏览器H5支付 + "mweb": { + "appId": "", // 可以是小程序或公众号或app开放平台下的应用的任意一个appid + "secret": "", // secret + "mchId": "", // 商户id + "key": "", // v2的api key + "pfx": fs.readFileSync(__dirname + '/wxpay/apiclient_cert.p12'), // v2需要用到的证书 + "v3Key": "", // v3的api key + "appCertPath": path.join(__dirname, 'wxpay/apiclient_cert.pem'), // v3需要用到的证书 + "appPrivateKeyPath": path.join(__dirname, 'wxpay/apiclient_key.pem'), // v3需要用到的证书 + "version": 2, // 启用支付的版本 2代表v2版本 3 代表v3版本 + // 场景信息,必填 + "sceneInfo": { + "h5_info": { + "type": "Wap", // 此值固定Wap + "wap_url": "", // 你的H5首页地址,必须和你发起支付的页面的域名一致。 + "wap_name": "", // 你的H5网站名称 + } + } + }, + }, +} +``` + +#### 微信PC扫码支付@config-wxpay-native + +对应支付配置的节点是 `wxpay.native` + +```js +const fs = require('fs'); +const path = require('path') +module.exports = { + // 统一 - 支付回调地址,格式为 "服务空间ID":"URL化地址" + "notifyUrl": { + // 测试环境服务空间-支付回调地址 + "mp-b267e273-19a7-4288-99c7-f6f27f9c5b77": "https://fc-mp-b267e273-19a7-4288-99c7-f6f27f9c5b77.next.bspapp.com/uni-pay-co", + // 线上环境服务空间-支付回调地址(如果只有一个服务空间,则只需要配置线上环境服务空间即可) + "mp-499e2a37-0c77-418a-82aa-3e5820ecb057": "https://fc-mp-499e2a37-0c77-418a-82aa-3e5820ecb057.next.bspapp.com/uni-pay-co", + }, + // 微信支付相关 + "wxpay": { + "enable": true, // 是否启用微信支付 + // 微信 - 扫码支付 + "native": { + "appId": "", // 可以是小程序或公众号或app开放平台下的应用的任意一个appid + "secret": "", // secret + "mchId": "", // 商户id + "key": "", // v2的api key + "pfx": fs.readFileSync(__dirname + '/wxpay/apiclient_cert.p12'), // v2需要用到的证书 + "v3Key": "", // v3的api key + "appCertPath": path.join(__dirname, 'wxpay/apiclient_cert.pem'), // v3需要用到的证书 + "appPrivateKeyPath": path.join(__dirname, 'wxpay/apiclient_key.pem'), // v3需要用到的证书 + "version": 2, // 启用支付的版本 2代表v2版本 3 代表v3版本 + }, + }, +} +``` + #### 支付宝APP支付@config-alipay-app 对应支付配置的节点是 `alipay.app` @@ -350,6 +674,36 @@ module.exports = { } ``` +#### 苹果虚拟支付@config-appleiap-app + +对应支付配置的节点是 `appleiap.app` + +```js +const fs = require('fs'); +const path = require('path') +module.exports = { + // 统一 - 支付回调地址,格式为 "服务空间ID":"URL化地址" + "notifyUrl": { + // 测试环境服务空间-支付回调地址 + "mp-b267e273-19a7-4288-99c7-f6f27f9c5b77": "https://fc-mp-b267e273-19a7-4288-99c7-f6f27f9c5b77.next.bspapp.com/uni-pay-co", + // 线上环境服务空间-支付回调地址(如果只有一个服务空间,则只需要配置线上环境服务空间即可) + "mp-499e2a37-0c77-418a-82aa-3e5820ecb057": "https://fc-mp-499e2a37-0c77-418a-82aa-3e5820ecb057.next.bspapp.com/uni-pay-co", + }, + // 苹果虚拟支付相关 + "appleiap": { + // 苹果虚拟支付支付,参数获取地址:https://appstoreconnect.apple.com/access/integrations/api/subs + "app": { + "appId": "", // 密钥ID + "issuerId": "", // Issuer ID + "bundleId": "", // 正式包名(如果dev包名和正式包名一致,则只填bundleId即可) + "devBundleId": "", // dev包名(如果dev包名和正式包名一致,则devBundleId可不填) + "appCertPath": path.join(__dirname, 'appleiap/apiclient_cert.p8'), // 证书路径 + "sandbox": true, // 是否是沙箱环境 + } + } +} +``` + ## 集成到自己项目的教程@install 在对接自己的项目之前,建议先[跑通示例项目](#rundemo),能跑通示例项目,代表你的配置和证书一定是正确的,然后再将`uni-pay`集成到你自己的项目中。 @@ -1305,7 +1659,7 @@ await payInstance.xxx(); let providerObj = { "wxpay": "微信支付", "alipay": "支付宝支付", - "appleiap": "ios内购" + "appleiap": "苹果虚拟" } as UTSJSONObject; let providerStr = providerObj[provider] as string; return providerStr; @@ -1889,6 +2243,236 @@ await uniPayCo.getOpenid({ |-----------------|---------|---------------------------| | openid | string | openid | +### 苹果虚拟支付@appleiap + +**概述** + +苹果虚拟支付:In-App Purchase,是指苹果 App Store 的应用内购买,是苹果为 App 内购买虚拟商品或服务提供的一套交易系统。 + +适用范围:在 App 内需要付费使用的产品功能或虚拟商品/服务,如游戏道具、电子书、音乐、视频、订阅会员、App的高级功能等需要使用 IAP,而在 App 内购买实体商品(如淘宝购买手机)或者不在 App 内使用的虚拟商品(如充话费)或服务(如滴滴叫车)则不适用于 IAP。 + +简而言之,苹果规定:适用范围内的虚拟商品或服务,必须使用 IAP 进行购买支付,不允许使用支付宝、微信支付等其它第三方支付方式(包括Apple Pay),也不允许以任何方式(包括跳出App、提示文案等)引导用户通过应用外部渠道购买。 + +**示例代码** + +注意:只能使用uni-pay支付组件发起 + +```js +// 发起苹果虚拟支付 +this.$refs.pay.createOrder({ + provider: "appleiap", // 支付供应商(这里固定未appleiap,代表苹果虚拟支付) + order_no: "20221027011000101001010", // 业务系统订单号 + out_trade_no: "2022102701100010100101001", // 插件支付单号 + type: "appleiap", // 支付回调类型(可自定义,建议填写appleiap) + description: "为DCloud提供的免费软件进行赞助", // 订单描述 + // apple_virtual字段仅苹果虚拟支付生效 + apple_virtual: { + product_id: "uniappx.consumable.sponsor_1", // 产品id + goods_price: 1, // 单价(此参数的单位是元) + buy_quantity: 1, // 购买数量 + }, + custom: {}, // 自定义数据(此参数不推荐使用,因为是前端传的,此参数可能会被伪造,建议通过order_no查询自己业务订单表来获取自定义业务数据) +}); +``` + +[点击查看苹果虚拟注意事项](#tips-appleiap) + +完整苹果虚拟支付示例代码 + +```html + + + + + +``` + ## 支付统计@pay-stat `uni-pay`基于`uni统计2.0`新增了支付统计。为您赋能数字化运营。 @@ -2038,6 +2622,14 @@ APP支付除了配置uni-pay的支付配置外,还需要打包时添加支付 同时,还需要打自定义基座(包名需要和开放平台下填写的一致),且你在开放平台下的这个应用必须通过审核才可以。(比如微信开放平台下的APP应用显示通过审核才可以) +### 苹果虚拟支付@tips-appleiap + +1. 苹果虚拟支付需勾选App模块配置中的Apple应用内支付 +2. 需要打ios自定义基座 +3. 需要注册ios开发者账号,且交了年费(688元/年) +4. 需要在ios开发者平台添加内购商品,并获得商品id +5. ios沙箱测试时,需要先在ios开发者平台添加沙箱测试账号,同时你的测试手机上需要登录ios沙箱账号 + ## 全局错误码@errorcode | 错误模块 | 错误码 | 说明 | -- GitLab