背景
前段时间项目上使用uniapp实现了一个App,安卓发布没有问题,但是IOS上架是个大问题。因为是数字藏品类的App,属于虚拟商品,只能使用应用内支付。在网上查了很多资料都没有找到很完整的教程,最后也是花了很长时间才解决上架问题。这里我将自己的开发经验和很多资料的精华部分汇总起来,给到同样遇到困难的小伙伴们。
概念
IOS内购是指苹果 App Store 的应用内购买,即In-App Purchase,简称IAP(以下本文关于内购都简称为IAP),是苹果为 App 内购买虚拟商品或服务提供的一套交易系统。为什么我们需要掌握IAP这套流程呢,因为App Store审核指南规定:
如果您想要在 app 内解锁特性或功能 (解锁方式有:订阅、游戏内货币、游戏关卡、优质内容的访问 限或解锁完整版等),则必须使用 App 内购买项目。App 不得使用自身机制来解锁内容或功能, 如许可证密钥、增强现实标记、二维码等。App 及其元数据不得包含按钮、外部链接或其他行动号 召用语,以指引用户使用非 App 内购买项目机制进行购买。
大概的意思就是对于虚拟商品,不得使用支付宝、微信、Apple Pay等第三方支付,只能使用自己的IAP支付,这里需要强调一下Apple Pay和IAP不是同一种支付方式,并且IAP会和苹果公司三七分成。
IOS证书和描述文件申请
开发前我们需要申请两套IOS证书和描述文件,一套测试的,一套正式的。uniapp官方给出了详细的申请流程:ask.dcloud.net.cn/article/152
账户准备
在App Store Connect后台填写银行账户信息,这里推荐另一篇的文章,写的还是很详细的:juejin.cn/post/704925…
沙箱测试账户和TestFlight账户准备
1、沙箱测试:
需要注意的是,沙箱测试人员的注册申请时必须使用没有注册过的邮箱的。申请完成后,在IOS或者IPAD上登录沙箱测试人员的账号,并且在设置 — App Store — 沙盒账户中也登录账户。
2、TestFlight账户 TestFlight账户需要是正式账户,通过沙箱测试后,在上架审核前最好使用正式账户进行一次付款测试。申请流程:在用户和访问添加开发者->邮件邀请成功后在TestFlight添加开发者。开发者测试的时候需要在手机上App Store下载TestFlight App,每一次更新版本都可以收到消息。
配置商品
创建流程: App内购买项目-> App内购买项目+ -> 创建。这里的产品ID是需要自行配置的,产品ID具有唯一性,为了避免与其他app的产品ID重复,建议使用本App特殊标识字符串+业务管理的商品ID。类型选择有4种,官方的解释是这样的,具体可根据自己的业务进行选择:
**消耗型项目**
提供不同类型的消耗型项目,例如游戏中用来推动进程的生命或宝石,约会 App 中用来提升个人资料曝光度的升
级,或者社交媒体 App 中的创作者数字提示。消耗型的 App 内购买项目在使用之后即失效,并可再次购买。采
用免费增值业务模式的 App 和游戏中经常提供这种项目。
**非消耗型项目**
提供非消耗型项目,解锁更多进阶功能。这些功能只需购买一次,并且不会过期。例如,照片 App 中的额外滤
镜、插图 App 中的额外画笔或游戏中的皮肤。非消耗型 App 内购买项目可以提供家人共享。
**自动续期订阅**
提供对 App 中内容、服务或进阶功能的持续访问权限。此类订阅会自动续期,除非用户选择取消。常见用例包括
提供媒体或内容库 (例如视频、音乐或文章) 访问权限、软件即服务 (例如云存储、效率或图形与设计) 以及教
育等等。自动续期订阅可以提供家人共享。
**非续期订阅**
对相关服务或内容提供有时限性的访问权限 (例如游戏中内容的季度订阅)。这种类型的订阅不会自动续期,如果
想要继续访问,用户需要在订阅结束时购买新的订阅。
在产品信息页配置好信息后,点击“存储”,存储后Status变成“准备提交”就说明产品配置成功了。这里有一点需要注意的是:配置好产品后就可以进行沙箱或者TestFlight测试了,不需要进行审核。
内购流程
uniapp内购流程主要分为4步:从服务端获取产品ID->校验苹果支付通道->校验产品ID->调用uniapp提供的支付函数,对于支付失败的情况可以根据业务需求在uni.requestPayment函数的fail中配置逻辑。
1、从服务端获取产品ID
由于苹果的产品ID是自定义的,所以最好在自己app的管理后台设置好,这样就可以实现动态上架,需要注意的是:只有苹果的产品ID审核通过后再配置,不然产品ID是无效的。我们前端可以在支付前从服务端获取到苹果产品ID,为下一步做准备。
async pay() {
let that = this
let data = {
ticket: that.payParams.ticket,
randStr: that.payParams.randStr,
captcha: that.payParams.captcha,
nftId: that.payParams.nftId,
price: that.payParams.price,
applet: false, //是否是小程序登陆
payType: that.payTypeList[that.currentPay].value,
}
if (that.isCanPay) {
//给支付按钮上锁
that.isCanPay = false
let res = await payAppGood(data)
if (res) {
//苹果支付
let applePayObj={
productId:res.data.product_id, //产品ID
outTradeNo:res.data.out_trade_no //业务需要的交易ID,这个不是必须的
}
//校验苹果支付通道
that.getAppleChannel(applePayObj)
}
}
}
2、校验苹果支付通道
getAppleChannel(productData) {
let that = this
uni.showLoading({
title: '检测支付环境...',
mask: true
})
plus.payment.getChannels((channels) => {
for (let i in channels) {
// 判断是否苹果支付
if (channels[i].id === 'appleiap') {
//这里的iapChannel需要提前在data中声明
that.iapChannel = channels[i]
//校验产品ID是否上架App Store
that.compareAppleProduce(productData)
}
}
},(err) => {
uni.hideLoading()
uni.showToast({
title: "获取支付通道失败:" + err.message,
icon: 'none'
})
})
}
3、校验产品ID
//校验苹果产品可以支付
compareAppleProduce(productData) {
let that = this
that.iapChannel.requestOrder([productData.productId], (event) => {
uni.hideLoading()
//这里使用for循环是为了适配多产品ID情况
for (let index in event) {
//需要产品id和自定义交易id
that.applePay(productData.productId,productData.outTradeNo)
}
}, (err) => {
uni.hideLoading()
uni.showToast({
title: "该商品未录入:" + err.message,
icon: 'none'
})
})
}
4、调用uniapp提供的支付函数
//苹果支付
applePay(productId,outTradeNo) {
let that = this
uni.showLoading({
title: '支付中...',
mask: true
})
uni.requestPayment({
provider: 'appleiap',
orderInfo: {
productid: productId
},
async success(res) {
let data = {
outTradeNo: outTradeNo,
transactionId:res.transactionIdentifier,
payload: res.transactionReceipt
}
//成功后的回调,根据业务自定义逻辑
let result = await applePayCallback(data)
if (result) {
//给支付按钮解锁
that.isCanPay = true
//自定义提示,可以忽略
that.payTipShow('支付成功')
}
},
fail(e) {
//给支付按钮解锁
that.isCanPay = true
//自定义提示,可以忽略
that.payTipShow('支付已取消')
},
complete() {
uni.hideLoading()
}
})
}
测试发布
在发布前记得在manifest.json文件中勾选Apple应用内支付。发布测试ipa流程:点击Hbuilder上方的发行->原生App-云打包,这里的profile文件和密钥证书是最初申请的测试IOS证书和描述文件,打包后可以将生成的ipa包上传到“蒲公英”上,手机访问链接就可以安装了,很方便。只有在苹果管理后台添加的设备才可以安装。
正式发布
在沙箱测试完没有问题后就可以进行正式发布了,正式发布打包同测试发布打包一样,只需要将测试的IOS证书和描述文件换成正式的就可以了。
上传ipa需要准备一台Mac,并且在App Store下载Transporter,将打包好的ipa拖入Transporter进行交付。
交付后需要使用TestFlight进行一次正式环境支付,如果没有问题就可以直接填写App信息提交审核了。App审核可能会遇到各种各样的问题,这里就需要开发者根据要求耐心修改,直到上架。
结语
最后小编祝大家App审核畅通无阻,有问题可以在评论区提出,大家一起解决。