提交 208af26d 编写于 作者: DCloud_iOS_WZT's avatar DCloud_iOS_WZT

支付文档优化

上级 f8907605
#### 注意事项
1.应苹果审核规范要求,应用中虚拟物品交易必须使用Apple应用内支付,实物才可使用第三方支付(支付宝、微信等)
2.使用沙盒环境测试时每次调用支付接口需要换一个新的测试账号或商品,同一个账号多次购买同一个商品可能会没有回调
#### 相关文档
使用前必读:[App内购买配置流程](https://help.apple.com/app-store-connect/#/devb57be10e7)
调试需要创建自定义基座.参考[自定义调试基座](https://ask.dcloud.net.cn/article/35115)
服务端防刷单参考[IAP支付防止刷单](https://www.jianshu.com/p/5cf686e92924)
#### 参考建议
1.提前绑定支付方式可以有效避免丢单情况,示例:
* 应苹果审核规范要求,应用中虚拟物品交易必须使用Apple应用内支付,实物才可使用第三方支付(支付宝、微信等)
* 使用沙盒环境测试时每次调用支付接口需要换一个新的测试账号或商品,同一个账号多次购买同一个商品可能会没有回调
* [App内购买配置流程](https://help.apple.com/app-store-connect/#/devb57be10e7)
* 服务端防刷单参考[IAP支付防止刷单](https://www.jianshu.com/p/5cf686e92924)
* 调试需要创建[自定义调试基座](https://ask.dcloud.net.cn/article/35115)
* 提前绑定支付方式可以有效避免丢单情况,示例:
`plus.runtime.openURL("https://apps.apple.com/account/billing"); //跳转AppStore绑定支付方式`
2.在每个接口调用前后添加打点日志收集,以便快速定位问题
* 建议在每个接口调用前后添加打点日志收集,以便快速定位问题
#### 丢单问题说明
通过和用户联调我们发现在调用支付接口后,如果用户未绑定支付方式此时会触发支付失败回调方法,实际上用户可以跳转 AppStrore 绑卡然后继续支付,之前的逻辑在回调失败方法中框架会关闭订单,用户付完钱在回到App中也不会触发成功回调,这样就造成了丢单,解决方法就是在调用支付接口时添加optimize: true参数,并标记 restoreFlag = true;,支付成功回调中清除标记 restoreFlag = false; 然后在支付失败回调中框架就不会关闭订单了,并在页面显示的时候通过标记判断是否需要调用 restoreComplateRequest 方法,如果用户跳转App Store绑定支付方式付款成功后回到 App 就可以通过 restoreComplateRequest 方法恢复之前支付的订单信息,解决丢单的问题;
#### 开发流程
#### 配置
在manifest.json文件“App模块配置”项的“Payment(支付)”下,勾选“Apple应用内支付”项
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/iap_setup_manifest_info.png)
###### 获取支付渠道
#### 获取支付渠道
``` js
var iap = null;
plus.payment.getChannels(function(channels) {
......@@ -35,7 +31,7 @@ plus.payment.getChannels(function(channels) {
});
```
###### 获取订单信息
#### 获取订单信息
``` js
// ids 为在苹果开发者后台配置的应用内购项目的标识集合
var ids = ['商品1', '商品2'];
......@@ -49,7 +45,7 @@ iap.requestOrder(ids, function(e) {
});
```
###### 发起支付
#### 应用内发起支付
* uni-app项目示例
``` js
var restoreFlag = true;
......@@ -74,7 +70,7 @@ uni.requestPayment({
}
})
```
* 5+项目示例
* 5+App项目示例
``` js
// restoreFlag 标记,用于判断在页面显示的时候是否需要调用 restoreComplateRequest 方法
var restoreFlag = true; // 调用支付接口时标记 restoreFlag = true , 实际应用请将标记存储在 storage 中
......@@ -91,7 +87,7 @@ plus.payment.request(iap, {
});
```
###### 恢复购买
#### 恢复购买
``` js
function restoreComplateRequest() {
iap.restoreComplateRequest({}, function(results) {
......@@ -99,12 +95,12 @@ function restoreComplateRequest() {
});
}
```
此方法可获取
restoreComplateRequest作用描述:
* 已购的非消耗性商品以及订阅商品
* 丢单的商品(所有类型)
注意事项:**丢单的消耗类型商品**在支付完成后,**首次**调用该接口可返回支付凭证
###### 丢单检测
#### 丢单检测
* uni-app 在页面 onShow 方法中调用 restoreComplateRequest
``` js
onShow() {
......@@ -113,7 +109,7 @@ onShow() {
}
}
```
* 5+app 在 resume 回调中调用 restoreComplateRequest
* 5+App 在 resume 回调中调用 restoreComplateRequest
``` js
document.addEventListener('resume',function(){
if(restoreFlag) {
......
## 申请开通支付宝支付
登录[支付宝开放平台](https://open.alipay.com/)
[创建应用](https://opendocs.alipay.com/open/200/105310)
[添加功能](https://opendocs.alipay.com/open/200/105310#%E6%B7%BB%E5%8A%A0%E5%BA%94%E7%94%A8%E5%8A%9F%E8%83%BD)
[开发设置](https://opendocs.alipay.com/open/200/105310#%E9%85%8D%E7%BD%AE%E5%BA%94%E7%94%A8%E7%8E%AF%E5%A2%83)
#### 开通
* 登录[支付宝开放平台](https://open.alipay.com/)
* [创建应用](https://opendocs.alipay.com/open/200/105310)
* [添加功能](https://opendocs.alipay.com/open/200/105310#%E6%B7%BB%E5%8A%A0%E5%BA%94%E7%94%A8%E5%8A%9F%E8%83%BD)
* [开发设置](https://opendocs.alipay.com/open/200/105310#%E9%85%8D%E7%BD%AE%E5%BA%94%E7%94%A8%E7%8E%AF%E5%A2%83)
更多信息详见[支付宝官方文档](https://opendocs.alipay.com/open/204/105297/)
## 使用支付宝支付
#### 配置
在manifest.json文件“App模块配置”项的“Payment(支付)”下,勾选“支付宝支付”项
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/alipay_setup_manifest_info.png)
#### 服务器生成订单
通过服务器生成支付订单,参考:
[生成支付订单示例(PHP)](https://github.com/dcloudio/H5P.Server/tree/master/payment/alipayrsa2)
[老版本"移动快捷支付"示例代码(PHP)](https://github.com/dcloudio/H5P.Server/tree/master/payment/alipay)
[生成支付订单示例(C#)](http://ask.dcloud.net.cn/article/197)
#### 应用内发起支付
应用中调用支付功能(支付参数如下)
| 参数名称 | 参数说明 | 必须 |
......@@ -47,27 +49,27 @@ uni.getProvider({
}
});
```
* 5+项目示例
* 5+App项目示例
``` js
//获取支付渠道
var alipaySev = null;
plus.payment.getChannels(function(channels) {
for (var i in channels) {
var channel = channels[i];
if (channel.id === 'alipay') {
alipaySev = channel;
}
}
}, function(e) {
console.log("获取支付渠道失败:" + e.message);
});
//发起支付
var statement = orderInfo; //此处为服务器返回的订单信息字符串
plus.payment.request(alipaySev, statement, function(result) {
var rawdata = JSON.parse(result.rawdata);
console.log("支付成功");
}, function(e) {
console.log("支付失败:" + e.message);
});
//获取支付渠道
var alipaySev = null;
plus.payment.getChannels(function(channels) {
for (var i in channels) {
var channel = channels[i];
if (channel.id === 'alipay') {
alipaySev = channel;
}
}
}, function(e) {
console.log("获取支付渠道失败:" + e.message);
});
//发起支付
var statement = orderInfo; //此处为服务器返回的订单信息字符串
plus.payment.request(alipaySev, statement, function(result) {
var rawdata = JSON.parse(result.rawdata);
console.log("支付成功");
}, function(e) {
console.log("支付失败:" + e.message);
});
```
## 申请开通Paypal
* [登录/注册](https://www.paypal.com/c2/signin)
* 打开[paypal开发者中心](https://developer.paypal.com/developer/applications)
如图,依次选择My Apps & Credentials -> Live(如果创建沙箱环境点击Sandbox) -> Create App
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_develop_center.png)
* 输入App Name,点击Create App
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_create_app.png)
* 创建完成后,点击AppName
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_setup_app_info.png)
* 查看Client ID 以及 Secret
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_get_clientid.png)
* 添加return URL并保存(必须使用小写字母)
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_add_returnurl.png)
* 勾选Accept payments 并点击Advanced options选择详情配置(点击保存后生效)
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_accept_payments.png)
* 勾选Log in with PayPal 并点击Advanced options选择详情配置(点击保存后生效)
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_log_in.png)
## 申请开通Paypal
[登录/注册](https://www.paypal.com/c2/signin)
打开[paypal开发者中心](https://developer.paypal.com/developer/applications)
如图,依次选择My Apps & Credentials -> Live(如果创建沙箱环境点击Sandbox) -> Create App
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_develop_center.png)
输入App Name,点击Create App
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_create_app.png)
创建完成后,点击AppName
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_setup_app_info.png)
查看Client ID 以及 Secret
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_get_clientid.png)
添加return URL并保存(必须使用小写字母)
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_add_returnurl.png)
勾选Accept payments 并点击Advanced options选择详情配置(点击保存后生效)
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_accept_payments.png)
勾选Log in with PayPal 并点击Advanced options选择详情配置(点击保存后生效)
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_log_in.png)
------
## 使用Paypal支付
#### 开通
[paypal开通文档](https://uniapp.dcloud.io/app-payment-paypal-open)
#### 配置
在manifest.json文件“App模块配置”项的“Payment(支付)”下,勾选“paypal支付”项并配置相关参数
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/paypal_setup_manifest_info.png)
配置说明:returnURL必须为paypal开发者中心配置的returnURL,否则无法调起支付
#### 服务器生成订单
通过服务器生成支付订单并获取orderId(服务器获取订单信息详见[paypal API](https://developer.paypal.com/docs/api/orders/v2/))
#### 应用内发起支付
应用中调用支付功能(支付参数如下)
| 参数名称 | 参数说明 | 必须 |
......@@ -73,35 +48,36 @@ uni.getProvider({
}
});
```
* 5+项目示例
* 5+App项目示例
``` js
//获取支付渠道
var paypalSev = null;
plus.payment.getChannels(function(channels) {
for (var i in channels) {
var channel = channels[i];
if (channel.id === 'paypal') {
paypalSev = channel;
}
}
}, function(e) {
console.log("获取支付渠道失败:" + e.message);
});
//发起支付
var statement = {
"clientId": clientId, //客户端id
"orderId": orderId,//订单id
"userAction":"continue",// paynow/continue
"currency":"USD",//币种
"environment":"sandbox",//运行环境 sandbox/live
};
plus.payment.request(this.paypalSev, statement, function(result) {
var rawdata = JSON.parse(result.rawdata);
console.log("orderId:" + rawdata.orderId);
}, function(e) {
console.log("支付失败:" + e.message);
});
//获取支付渠道
var paypalSev = null;
plus.payment.getChannels(function(channels) {
for (var i in channels) {
var channel = channels[i];
if (channel.id === 'paypal') {
paypalSev = channel;
}
}
}, function(e) {
console.log("获取支付渠道失败:" + e.message);
});
//发起支付
var statement = {
"clientId": clientId, //客户端id
"orderId": orderId,//订单id
"userAction":"continue",// paynow/continue
"currency":"USD",//币种
"environment":"sandbox",//运行环境 sandbox/live
};
plus.payment.request(this.paypalSev, statement, function(result) {
var rawdata = JSON.parse(result.rawdata);
console.log("orderId:" + rawdata.orderId);
}, function(e) {
console.log("支付失败:" + e.message);
});
```
#### 服务器授权
应用发起支付完成后,返回订单id,服务器捕获或授权订单[详见paypal API](https://developer.paypal.com/docs/api/orders/v2/)
## 申请开通Stripe
* [登录/注册](https://dashboard.stripe.com/login)
* 进入主页后,点击顶部继续按钮
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/stripe_home_page.png)
* 完善公司信息
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/stripe_company_info.png)
* 完善信息后,回到首页即可在右侧查看密钥
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/stripe_get_publishkey.png)
## 申请开通Stripe
[登录/注册](https://dashboard.stripe.com/login)
#### 开通
[stripe开通文档](https://uniapp.dcloud.io/app-payment-stripe-open)
进入主页后,点击顶部继续按钮
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/stripe_home_page.png)
完善公司信息
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/stripe_company_info.png)
完善信息后,回到首页即可在右侧查看密钥
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/stripe_get_publishkey.png)
------
## 使用Stripe支付
#### 配置
在manifest.json文件“App模块配置”项的“Payment(支付)”下,勾选“stripe支付”项并添加配置
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/stripe_setup_manifest_info.png)
配置说明:returnURL(只需配置iOS),格式为'your-app://stripe'(示例 hbuilder://stripe),'your-app'为应用的自定义scheme,参考:[配置一个自定义页面内跳转协议 (URL Scheme)](https://ask.dcloud.net.cn/article/64)
服务器生成支付订单[参考stripeAPI](https://stripe.com/docs/payments/accept-a-payment)
``` js
配置说明:returnURL(只需配置iOS),格式为'your-app://stripe'(示例 hbuilder://stripe),'your-app'为应用的自定义scheme,参考:[配置一个自定义页面内跳转协议 (URL Scheme)](https://ask.dcloud.net.cn/article/64) #### 服务器生成订单
服务器生成支付订单[参考stripeAPI](https://stripe.com/docs/payments/accept-a-payment)
``` js
uni.request({
url: 'https://stripe-mobile-payment-sheet.glitch.me/checkout',//仅为示例
method: "POST",
......@@ -29,7 +19,9 @@
var ephemeralKey = res.data.ephemeralKey;
}
})
```
```
#### 应用内发起支付
应用中调用支付功能(支付参数如下)
| 参数名称 | 参数说明 | 必须 |
......@@ -79,8 +71,8 @@
});
```
* 5+项目示例
``` js
* 5+App项目示例
``` js
//获取渠道
var stripeSev = null;
plus.payment.getChannels(function(channels) {
......@@ -107,5 +99,5 @@
}, function(e) {
console.log("支付失败:" + e.message);
});
```
```
......
## 申请开通微信支付
登录[微信开放平台](https://open.weixin.qq.com/),申请移动应用并开通支付功能,申请应用后可以获取 AppID
应用接入[微信商户平台](https://pay.weixin.qq.com/index.php/core/home/login?return_url=%2F),选择 App 支付
开通支付功能后可获取支付业务服务器配置数据:PARTNER(财付通商户号)、PARTNER_KEY(财付通密钥)、PAYSIGNKEY(支付签名密钥)
#### 开通
* 登录[微信开放平台](https://open.weixin.qq.com/),申请移动应用并开通支付功能,申请应用后可以获取 AppID
* 应用接入[微信商户平台](https://pay.weixin.qq.com/index.php/core/home/login?return_url=%2F),选择 App 支付
* 开通支付功能后可获取支付业务服务器配置数据:PARTNER(财付通商户号)、PARTNER_KEY(财付通密钥)、PAYSIGNKEY(支付签名密钥)
更多信息详见[移动应用开发](https://open.weixin.qq.com/cgi-bin/frame?t=home/app_tmpl&lang=zh_CN)
## 使用微信支付
#### 配置
在manifest.json文件“App模块配置”项的“Payment(支付)”下,勾选“微信支付”项
![](https://partner-dcloud-native.oss-cn-hangzhou.aliyuncs.com/images/uniapp/payment/wxpay_setup_manifest_info.png)
#### 服务器生成订单
通过服务器生成支付订单,参考:[微信支付示例(PHP)](https://github.com/dcloudio/H5P.Server/tree/master/payment/wxpayv3)
#### 应用内发起支付
应用中调用支付功能(支付参数如下)
| 参数名称 | 参数说明 | 必须 |
......@@ -53,35 +55,35 @@ uni.getProvider({
});
```
* 5+项目示例
* 5+App项目示例
``` js
//获取支付渠道
var wxpaySev = null;
plus.payment.getChannels(function(channels) {
for (var i in channels) {
var channel = channels[i];
if (channel.id === 'wxpay') {
wxpaySev = channel;
}
}
}, function(e) {
console.log("获取支付渠道失败:" + e.message);
});
//发起支付
var statement = {
"appid": "wx499********7c70e", // 微信开放平台 - 应用 - AppId,注意和微信小程序、公众号 AppId 可能不一致
"noncestr": "c5sEwbaNPiXAF3iv", // 随机字符串
"package": "Sign=WXPay", // 固定值
"partnerid": "148*****52", // 微信支付商户号
"prepayid": "wx202254********************fbe90000", // 统一下单订单号
"timestamp": 1597935292, // 时间戳(单位:秒)
"sign": "A842B45937F6EFF60DEC7A2EAA52D5A0" // 签名,这里用的 MD5 签名
};
plus.payment.request(wxpaySev, statement, function(result) {
var rawdata = JSON.parse(result.rawdata);
console.log("支付成功");
}, function(e) {
console.log("支付失败:" + e.message);
});
//获取支付渠道
var wxpaySev = null;
plus.payment.getChannels(function(channels) {
for (var i in channels) {
var channel = channels[i];
if (channel.id === 'wxpay') {
wxpaySev = channel;
}
}
}, function(e) {
console.log("获取支付渠道失败:" + e.message);
});
//发起支付
var statement = {
"appid": "wx499********7c70e", // 微信开放平台 - 应用 - AppId,注意和微信小程序、公众号 AppId 可能不一致
"noncestr": "c5sEwbaNPiXAF3iv", // 随机字符串
"package": "Sign=WXPay", // 固定值
"partnerid": "148*****52", // 微信支付商户号
"prepayid": "wx202254********************fbe90000", // 统一下单订单号
"timestamp": 1597935292, // 时间戳(单位:秒)
"sign": "A842B45937F6EFF60DEC7A2EAA52D5A0" // 签名,这里用的 MD5 签名
};
plus.payment.request(wxpaySev, statement, function(result) {
var rawdata = JSON.parse(result.rawdata);
console.log("支付成功");
}, function(e) {
console.log("支付失败:" + e.message);
});
```
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册