一、苹果内购和Apple Pay的区别
1、内购(In App Purchase)
如果您想要在 app 内解锁特性或功能 (解锁方式有:订阅、游戏内货币、游戏关卡、优质内容的访问权限或解锁完整版等),则必须使用 App 内购买项目。App 不得使用自身机制来解锁内容或功能,如许可证密钥、增强现实标记、二维码等。App 及对应元数据不得包含指引客户使用非 App 内购买项目机制进行购买的按钮、外部链接或其他行动号召用语。
以上是苹果审核条例的内购说明要求,内购就是苹果为APP内购买虚拟商品或服务提供的一套交易系统。比如各类游戏的游戏币、网易云音乐开通黑胶VIP等等,都是需要走内购流程的,如果不走内购流程,审核是过不了的,即使通过后门设置,在审核期间避开审核人员测试,后期如果被发现,是有被下架的风险的;如果购买的是淘宝或者京东买衣服啊等等,就不需要走内购。
1.1、内购的分成与结算
内购需要和苹果三七分成,意思就是苹果需要抽取30%,但实际上在某些地区与开发者分成之前先要扣除交易税,开发者的实际分成不一定是70%,不同地区的交易税标准也存在差异,从2015年10月开始,苹果对中国地区的App Store购买扣除了2%的交易税,对于中国区账号购买的IAP,开发者的实际分成在68%~69%之间。以下是官网内购价格定义的部分截图。
收费规则.png如果设置了订阅类型,苹果还有另外的优惠,苹果可以少收15%,按照苹果的规则如下:
在订阅者使用付费服务的首年内,您的收益率为 70%。当订阅者为同一订阅群组中的订阅产品累积一年的付费服务后,您的收益率将提高至 85%。同一群组中的升级订阅、降级订阅和跨级订阅不会中断付费服务的天数。转换至不同群组的订阅将重置付费服务的天数。赚取 85% 订阅价格这一规则适用于2016年6月之后生效的订阅续期。
当自动续期订阅到期时,付费服务天数将停止累积(付费订阅累计达一年后,收益率才会变为 85%)。如果用户在 60 天内重新订阅或恢复订阅,付费服务天数将从恢复当天继续累积。如果用户在 60 天内未重新订阅或恢复订阅,付费服务天数将被重置,收益率为 70%。
内购价格等级一般是不会变的,除非某些货币汇率发生很大变化,需要对货币定价进行调整,调整前苹果会发邮件进行通知。
针对IAP的交易收入,苹果一般以5周(每年1/4/7/10月)或4周(其余月份)作为一个结算周期,并在每个结算周期结束后第33天向开发者付款。
1.2、如何关闭内购
由于现在大部分用户都用指纹或者面容结算付款,用户若是在使用内购产品中,不小心点到了内购商品,导致意外付款成功,这种情况下是可以申请退款的。为了避免这类情况发生,用户可用以下方式关闭应用内内购:
- 低系统的手机,前往设置页面的【通用-访问限制-启用访问限制-关闭App内购买项目】
- 高系统的手机,前往设置页面的【通用-屏幕使用时间-内容和隐私访问限制-iTunes Store与App Store购买项目】进行相应的设置
关于用户在内购遇到的其他问题,可前往技术支持查询
1.3、审核
如果APP支持游客模式,那么内购也一定要支持内购模式,否则就容易审核被拒
2、Apple Pay
Apple Pay可以简单理解成一种支付方式,等同于用户使用银行卡进行刷卡消费,它只是用户和银行之间的桥梁,使用Apple Pay购买商品的时候,其实是通过卡包里面设置的银行卡进行消费支付。
另外Apple Pay跟支付宝、微信支付稍微有些区别,用户可以将钱放入微信和支付宝,支付的时候不需要建立跟银行的关系.
二、App 内购买项目配置流程
内购配置流程图.png注意点:
- CNAPS代码查询地址
- 如果不配置银行、税务等信息,内购是无法进行沙盒测试的
- 内购产品的ID需唯一,即使删除后也不能再重新定义
- 内购价格无法自定义,只能按照苹果的价格梯度进行选择
- 内购产品配置不完整会显示元数据丢失
三、App 内购买项目流程
内购支付流程:
官方流程图.png
按照苹果官方流程图,大致流程如下:
1、
App
向业务服务器
请求带有产品标识符的产品列表
2、业务服务器
返回对应的产品列表
3、App
向App Store
请求产品
4、App Store
返回对应的产品
5、App
向用户在应用商店展示产品
6、用户在应用商店选择一款产品
7、App
向App Store
发送购买请求
8、App Store
处理购买请求并返回交易信息
9、App
将交易凭证发送给业务服务器
10、业务服务器
记录交易凭证并核实
11、业务服务器
向App Store
发送交易凭证验证其有效性
12、App Store
解析数据,并返回数据并验证其是否有效
13、业务服务器
记录数据,并确定用户购买的产品
14、业务服务器
向用户发送购买的产品
也可以衍生出以下方案,要注意的是业务服务器返回产品的价格要和苹果后台配置的价格一致,不然价格不对应,是会遭到用户投诉的。
1、
App
向业务服务器
请求带有产品标识符的产品列表
2、业务服务器
返回对应的产品列表
3、App
向用户在应用商店展示产品
4、用户在应用商店选择一款产品
5、App
根据用户选择的产品的ID向App Store
请求产品
6、App Store
返回对应的产品
7、App
向App Store
发送购买请求
8、App Store
处理购买请求并返回交易信息
9、App
将交易凭证发送给业务服务器
10、业务服务器
记录交易凭证并核实
11、业务服务器
向App Store
发送交易凭证验证其有效性
12、App Store
解析数据,并返回数据并验证其是否有效
13、业务服务器
记录数据,并确定用户购买的产品
14、业务服务器
向用户发送购买的产品
方案流程图大致如下:
内购支付流程.png
如果是微信支付宝支付,流程就简单很多,方案如下:
微信支付宝支付流程.png
注意点
-
需使用非越狱的真机进行测试,测试前先退出自己原先Apple账号。
-
在收到购买产品回调代理后,一定要调用
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
从支付队列中移除交易。 -
二次验证
为了线上用户的正常使用和防止应用审核被拒,需要先用正式环境验证,如果验证通过,那说明是线上环境,可以正常使用;如果返回错误码21007
,就需要使用沙盒环境进行验证,沙盒环境下的弹框都带有标识【Environment : Sandbox】,只要对应的内购项目没有上线,都只能用沙盒环境进行验证。 -
防止刷单
在做内购支付验证时,如果验证通过,还要实现对bundleID、transaction_id以及productID的校验,只有这样才能防止被重复刷单。因为苹果的验证接口只会告诉你这个票据是否可以验证通过却不告诉你这个票据是否被使用过,所以只有实现了对bundleID、transaction_id以及productID的校验才可以保证这个订单是你的应用里生成并只被使用一次。
四、内购产品类型
区别 | 消耗性项目 | 非消耗性项目 | 自动续期订阅 | 非自动续期订阅 |
---|---|---|---|---|
可购买次数 | 多次 | 一次 | 多次 | 多次 |
凭证记录 | 一次 | 一直 | 一直 | 一直 |
跨设备同步 | 不能 | 系统 | 系统 | APP控制 |
恢复 | 不能 | 系统 | 系统 | APP控制 |
自动续订
自动续期订阅测试周期如下图,测试环境的订阅时长要比正式环境短很多,方便我们在沙盒测试的进行测试,另外自动续订每天做多只能续订6次
。
实际时限 | 测试时限 |
---|---|
1周 | 3分钟 |
1个月 | 5分钟 |
2个月 | 10分钟 |
3个月 | 15分钟 |
6个月 | 30分钟 |
1年 | 1小时 |
-
不同于其他产品类型(只能以单一、同等价格在全球销售),自动续期订阅可以针对地区设定价格。
-
启用针对自动续期订阅的服务器通知,服务器根据用户续订情况进行产品的发放。
-
群组里面的多个订阅产品,用户一次只能订阅这些订阅产品中的一个,用户后续也可以进行变更产品,Apple会按比例进行退还退订产品的价格,并收取新订阅产品相应的收费价格。
-
用户在同一群组中订阅累计达一年,开发者收益可上升至85%,关于断续及补续等规则可以查看相关文档。
-
不能创建免费订阅,但是可以为付费订阅提供免费试用。
-
Apple会在订阅到期前10天检查续订可行性,会在自动续期订阅到期前24小时开始尝试续订,如果续订失败,App可能还会继续尝试,连续续订多次后就不会再次尝试,从时间上最多尝试60天。
五、验证购买凭证接口
- URL
- Method
- POST
参数 | receipt-data | password | exclude-old-transactions |
---|---|---|---|
参数类型 | byte | string | boolean |
可选 | 必须 | 必须 | 可选 |
说明 | Base64编码的接收数据 | 共享或者专用秘钥 | 将此值设置为true,以便响应仅包含任何订阅的最新续订事务。仅对包含自动续订订阅的应用程序回执使用此字段 |
{
"status":0,
"environment":"Sandbox",
"receipt":{
"receipt_type":"ProductionSandbox",
"adam_id":0,
"app_item_id":0,
"bundle_id":"xxx.xxx.xxx",
"application_version":"1",
"download_id":0,
"version_external_identifier":0,
"receipt_creation_date":"2020-04-01 07:10:09 Etc/GMT",
"receipt_creation_date_ms":"1585725009000",
"receipt_creation_date_pst":"2020-04-01 00:10:09 America/Los_Angeles",
"request_date":"2020-04-01 07:10:21 Etc/GMT",
"request_date_ms":"1585725021729",
"request_date_pst":"2020-04-01 00:10:21 America/Los_Angeles",
"original_purchase_date":"2013-08-01 07:00:00 Etc/GMT",
"original_purchase_date_ms":"1375340400000",
"original_purchase_date_pst":"2013-08-01 00:00:00 America/Los_Angeles",
"original_application_version":"1.0",
"in_app":[
{
"quantity":"1",
"product_id":"test_item_1",// 消耗性项目
"transaction_id":"1000000646065186",
"original_transaction_id":"1000000646065186",
"purchase_date":"2020-04-01 00:43:43 Etc/GMT",
"purchase_date_ms":"1585701823000",
"purchase_date_pst":"2020-03-31 17:43:43 America/Los_Angeles",
"original_purchase_date":"2020-04-01 00:43:43 Etc/GMT",
"original_purchase_date_ms":"1585701823000",
"original_purchase_date_pst":"2020-03-31 17:43:43 America/Los_Angeles",
"is_trial_period":"false"
},
{
"quantity":"1",
"product_id":"test_item_2",//非消耗性
"transaction_id":"1000000646065025",
"original_transaction_id":"1000000646065025",
"purchase_date":"2020-04-01 00:41:21 Etc/GMT",
"purchase_date_ms":"1585701681000",
"purchase_date_pst":"2020-03-31 17:41:21 America/Los_Angeles",
"original_purchase_date":"2020-04-01 00:41:21 Etc/GMT",
"original_purchase_date_ms":"1585701681000",
"original_purchase_date_pst":"2020-03-31 17:41:21 America/Los_Angeles",
"is_trial_period":"false"
},
{
"quantity":"1",
"product_id":"test_item_3",// 非自动续期订阅
"transaction_id":"1000000650241590",
"original_transaction_id":"1000000650241590",
"purchase_date":"2020-04-10 02:27:13 Etc/GMT",
"purchase_date_ms":"1586485633000",
"purchase_date_pst":"2020-04-09 19:27:13 America/Los_Angeles",
"original_purchase_date":"2020-04-10 02:27:13 Etc/GMT",
"original_purchase_date_ms":"1586485633000",
"original_purchase_date_pst":"2020-04-09 19:27:13 America/Los_Angeles",
"is_trial_period":"false"
},
{
"quantity":"1",
"product_id":"test_item_4",// 自动续期订阅
"transaction_id":"1000000646065960",
"original_transaction_id":"1000000646065960",
"purchase_date":"2020-04-01 00:49:18 Etc/GMT",
"purchase_date_ms":"1585702158000",
"purchase_date_pst":"2020-03-31 17:49:18 America/Los_Angeles",
"original_purchase_date":"2020-04-01 00:49:19 Etc/GMT",
"original_purchase_date_ms":"1585702159000",
"original_purchase_date_pst":"2020-03-31 17:49:19 America/Los_Angeles",
"expires_date":"2020-04-01 00:52:18 Etc/GMT",
"expires_date_ms":"1585702338000",
"expires_date_pst":"2020-03-31 17:52:18 America/Los_Angeles",
"web_order_line_item_id":"1000000051400327",
"is_trial_period":"false",
"is_in_intro_offer_period":"false"
},
{
.......
// 省略N次自动续期交易
},
{
"quantity":"1",
"product_id":"test_item_4",
"transaction_id":"1000000646068127",
"original_transaction_id":"1000000646065960",
"purchase_date":"2020-04-01 01:04:18 Etc/GMT",
"purchase_date_ms":"1585703058000",
"purchase_date_pst":"2020-03-31 18:04:18 America/Los_Angeles",
"original_purchase_date":"2020-04-01 00:49:19 Etc/GMT",
"original_purchase_date_ms":"1585702159000",
"original_purchase_date_pst":"2020-03-31 17:49:19 America/Los_Angeles",
"expires_date":"2020-04-01 01:07:18 Etc/GMT",
"expires_date_ms":"1585703238000",
"expires_date_pst":"2020-03-31 18:07:18 America/Los_Angeles",
"web_order_line_item_id":"1000000051400432",
"is_trial_period":"false",
"is_in_intro_offer_period":"false"
}
]
},
"latest_receipt_info":[
{
"quantity":"1",
"product_id":"test_item_1",
"transaction_id":"1000000646065186",
"original_transaction_id":"1000000646065186",
"purchase_date":"2020-04-01 00:43:43 Etc/GMT",
"purchase_date_ms":"1585701823000",
"purchase_date_pst":"2020-03-31 17:43:43 America/Los_Angeles",
"original_purchase_date":"2020-04-01 00:43:43 Etc/GMT",
"original_purchase_date_ms":"1585701823000",
"original_purchase_date_pst":"2020-03-31 17:43:43 America/Los_Angeles",
"is_trial_period":"false"
},
{
"quantity":"1",
"product_id":"test_item_2",
"transaction_id":"1000000646065025",
"original_transaction_id":"1000000646065025",
"purchase_date":"2020-04-01 00:41:21 Etc/GMT",
"purchase_date_ms":"1585701681000",
"purchase_date_pst":"2020-03-31 17:41:21 America/Los_Angeles",
"original_purchase_date":"2020-04-01 00:41:21 Etc/GMT",
"original_purchase_date_ms":"1585701681000",
"original_purchase_date_pst":"2020-03-31 17:41:21 America/Los_Angeles",
"is_trial_period":"false"
},
{
"quantity":"1",
"product_id":"test_item_2",
"transaction_id":"1000000646065025",
"original_transaction_id":"1000000646065025",
"purchase_date":"2020-04-01 00:41:21 Etc/GMT",
"purchase_date_ms":"1585701681000",
"purchase_date_pst":"2020-03-31 17:41:21 America/Los_Angeles",
"original_purchase_date":"2020-04-01 00:41:21 Etc/GMT",
"original_purchase_date_ms":"1585701681000",
"original_purchase_date_pst":"2020-03-31 17:41:21 America/Los_Angeles",
"is_trial_period":"false"
},
{
"quantity":"1",
"product_id":"test_item_3",
"transaction_id":"1000000650241590",
"original_transaction_id":"1000000650241590",
"purchase_date":"2020-04-10 02:27:13 Etc/GMT",
"purchase_date_ms":"1586485633000",
"purchase_date_pst":"2020-04-09 19:27:13 America/Los_Angeles",
"original_purchase_date":"2020-04-10 02:27:13 Etc/GMT",
"original_purchase_date_ms":"1586485633000",
"original_purchase_date_pst":"2020-04-09 19:27:13 America/Los_Angeles",
"expires_date":"2020-04-01 00:52:18 Etc/GMT",
"is_trial_period":"false",
},
{
"quantity":"1",
"product_id":"test_item_4",
"transaction_id":"1000000646068127",
"original_transaction_id":"1000000646065960",
"purchase_date":"2020-04-01 01:04:18 Etc/GMT",
"purchase_date_ms":"1585703058000",
"purchase_date_pst":"2020-03-31 18:04:18 America/Los_Angeles",
"original_purchase_date":"2020-04-01 00:49:19 Etc/GMT",
"original_purchase_date_ms":"1585702159000",
"original_purchase_date_pst":"2020-03-31 17:49:19 America/Los_Angeles",
"expires_date":"2020-04-01 01:07:18 Etc/GMT",
"expires_date_ms":"1585703238000",
"expires_date_pst":"2020-03-31 18:07:18 America/Los_Angeles",
"web_order_line_item_id":"1000000051400432",
"is_trial_period":"false",
"is_in_intro_offer_period":"false",
"subscription_group_identifier":"20609507"
}
],
"latest_receipt":"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",
"pending_renewal_info":[
{
"expiration_intent":"1",
"auto_renew_product_id":"test_item_4",
"original_transaction_id":"1000000646065960",
"is_in_billing_retry_period":"0",
"product_id":"test_item_4",
"auto_renew_status":"0"
}
]
}
六、错误码
SKErrorUnknown,
SKErrorClientInvalid, // 客户端不允许发送请求
SKErrorPaymentCancelled, // 用户取消购买
SKErrorPaymentInvalid, // 购买的产品的ID无效
SKErrorPaymentNotAllowed, // 设备不允许付款
SKErrorStoreProductNotAvailable , // 后台没有该产品
SKErrorCloudServicePermissionDenied API_AVAILABLE(ios(9.3)), // 用户不允许访问云服务信息
SKErrorCloudServiceNetworkConnectionFailed API_AVAILABLE(ios(9.3)), // 设备无法连接到网络
SKErrorCloudServiceRevoked API_AVAILABLE(ios(10.3)), // 用户已取消使用此云服务的权限
SKErrorPrivacyAcknowledgementRequired API_AVAILABLE(ios(12.2), // 用户需要承认苹果的隐私政策
SKErrorUnauthorizedRequestData API_AVAILABLE(ios(12.2), // 应用程序正在尝试使用SKPayment的requestData属性,但没有相应的权限
SKErrorInvalidOfferIdentifier API_AVAILABLE(ios(12.2), // 指定的订阅发行标识无效
SKErrorInvalidSignature API_AVAILABLE(ios(12.2), // 提供的加密签名无效
SKErrorMissingOfferParams API_AVAILABLE(ios(12.2), // SKPaymentDiscount中缺少一个或多个参数
SKErrorInvalidOfferPrice API_AVAILABLE(ios(12.2), // 所选报价的价格无效(例如,低于当前基本订阅价格)
2、常见的网络错误
NSURLErrorTimedOut(-1001)
NSURLErrorCannotFindHost(-1003)
NSURLErrorCannotConnectToHost(-1004)
NSURLErrorNetworkConnectionLost(-1005)
NSURLErrorNotConnectedToInternet(-1009)
NSURLErrorUserCancelledAuthentication(-1012)
NSURLErrorSecureConnectionFailed(-1200)
21000 验证请求不是使用HTTP POST请求方法发出的
21002 凭据数据不符合格式或服务遇到临时问题
21003 订单无法被验证
21004 密钥不匹配
21005 凭据服务器当前不可用
21006 凭据是有效的,但订阅服务已经过期(iOS 6之前会这样)。当收到这个信息时,解码后的收据信息也包含在返回内容中
21007 订单信息是测试用(sandbox),但却被发送到产品环境中验证
21008 订单信息是产品环境中使用,但却被发送到测试环境中验证
21009 内部数据访问错误
21010 找不到或已删除用户帐户
参考文档
https://my.oschina.net/swustyc/blog/3021959
https://www.cnblogs.com/lxlx1798/p/10527741.html
网友评论