uni-app实现苹果内购支付功能
背景
Appstore审核报PGPay SDK不允许上架的问题
数字类产品(比如购买会员等不需要配送实物的商品),Apple规定必须使用苹果IAP应用内支付,给Apple分成30%。打包的时候不要勾选微信或支付宝等其他支付方式。如果你提交的包里包含了微信支付宝等支付的sdk,即使没使用,Appstore也会认为你有隐藏方式,以后会绕过iap,不给Apple分成,因此拒绝你的App上线。云打包时,manifest里选上支付模块,但sdk配置里去掉微信支付和支付宝支付。很多开发者的Android版是包含微信和支付宝支付的,此时注意分开判断。
苹果支付流程
1.
2.
3.支付完成后
4.服务端将凭证发送到苹果服务验证
5.验证成功发放商品
苹果支付与微信和支付宝支付的不同点
1.微信和支付宝支付支付成功后,会将支付结果发送给你的服务器;而苹果支付支付成功后需要你自己把支付结果从app发送给自己的服务器,所以苹果支付容易出现丢单情况,比如支付途中强行关闭app,这时依然会支付成功,但是你的服务器收不到任何通知。
2.使用微信和支付宝支付你必须在自己的服务器上先生成一个订单,支付成功后微信和支付宝会把该订单的单号和支付结果一起通知给你;苹果支付不关心你服务器上的订单,在最后的验证结果中只会告诉你用户购买了哪个产品,不会告诉你是你服务器上的哪个订单。
3.微信和支付宝可以支付任意额度金额,但是苹果支付的金额是提前设定好的,无法随意更改。
4.苹果支付是可以在苹果那里直接申请退款的,不需要经过开发者的同意,但是会向你的服务器发送退款通知,请注意这点。
准备部分
a.签署《付费应用程序协议》
1.请在首页上,点按“协议、税务和银行业务”。
2.在“协议”部分找到《付费应用程序协议》,然后点按“查看并同意条款”。
3.请确保对话框中您的法律实体信息正确,然后点按“添加”。此处所输入的信息应该与“帐户持有人”注册“Apple 开发 者计划”时所提供的信息一致。
4.阅读并接受条款,然后点按“同意”。您还可以下载协议的副本。 重要事项:一旦请求此合同,您就不能撤销此操作,也不能回到针对免费 App 的《开发者计划许可协议》。
b.在 App Store Connect 中配置 App 内购买项目
1. 从“我的 App”中,选择您的 App。
2. 在侧边栏的“App 内购买项目”下方,点按“管理”。
3. 若要添加 App 内购买项目,请前往“App 内购买项目”,并点按添加按钮(+)。
4. 选择“消耗型项目”、“非消耗型项目”或“非续期订阅”,并点按“创建”。有关自动续期订阅的信息,请参见创建 自动续期订阅。
5. 添加参考名称、产品 ID 和本地化显示名称。
6. 点按“存储”或“提交以供审核”。
产品类型解释: 消耗型项目是一种使用一次之后即失效的项目。用户可以多次购买这类项目。 非消耗型项目是一种用户只需购买一次的项目。这类项目不会过期。 服务或内容的自动续期订阅是一种用户购买一次之后,只要用户不选择取消,就会一直自动续期的项目。 服务或内容的非续期订阅有特定访问时限,不会自动续期。用户可以再次购买这类项目。
c.增加测试账号
测试账号可以测试苹果支付
1.选择“用户与访问”
2.选择沙箱测试员
3.添加测试员 注:
- 1、邮箱必须是没有注册或者说关联过appstore的邮箱。
- 2、密码必须有一个是大写字母有一个是小写字母(苹果规定的,理解)。
- 3、内购屏幕截图规格必须是312*290,且最低分辨率是72ppi。
- 4、内购的价格是苹果规定的不能自定义(坑啊)。
uni-app代码开发
首先我们需要勾选苹果支付,在manifest.json中,选择App模块配置->Payment(支付)。
然后打包需要选择打基座包来测试。
前端代码实现
先在头部定义商品id 全部商品id (在苹果商店申请的真实商品id)
let iapChannel = null;
var productId = 'lvbi_a';
var productIds = ['lvbi_a'];进入页面就判断
//1.获取支付渠道
plus.payment.getChannels((channels) => {
for (var i in channels) {
var channel = channels[i];
//苹果支付
if (channel.id === 'appleiap') {
iapChannel = channel;
this.requestOrder(); //关键
}
}
if (!iapChannel) {
that.errorMsg()
}
}, (error) => {
that.errorMsg()
});requestOrder() {
iapChannel.requestOrder(productIds,(orderList) => { //必须调用此方法才能进行 iap 支付
uni.hideLoading();
}, (e) => {
uni.hideLoading();
this.errorMsg()
});
}, 调接口获取真实的商品id
// 获取页面内容
getAppleProducts() {
AppleProducts({
openid:this.openid,
token:this.tpken
}).then(res =>{
if(res.code == 1){
this.data = res.data;
this.price = this.data.products[0];
productId = this.data.products[0].product_id;
productIds = this.data.products_ids;
}
})
},确定支付
topupprice() {
let that = this;
uni.showLoading({});
uni.requestPayment({
provider: 'appleiap',
orderInfo: {
productid: productId
},
success: (e) => {
uni.hideLoading();
var statement = {
productid: productId
}
// 支付成功查询订单
plus.payment.request(iapChannel, statement, function(res){
paysuccers({
data:{
openid:that.openid,
token:that.token,
receipt_data:JSON.stringify(res)
}
}).then(tow =>{
uni.hideLoading();
if(tow.code == 1){
uni.showToast({
title:tow.msg,
icon:'none'
})
}else{
uni.showToast({
title:tow.msg,
icon:'none'
})
}
})
}, function(){
});
},
fail: (e) => {
uni.hideLoading();
uni.showModal({
content: "支付失败,原因为: " + e.errMsg,
showCancel: false
})
}
})
},本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!