iOS干货good

内购(IAP)详解

2020-04-06  本文已影响0人  哲逗年

一、苹果内购和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、如何关闭内购

由于现在大部分用户都用指纹或者面容结算付款,用户若是在使用内购产品中,不小心点到了内购商品,导致意外付款成功,这种情况下是可以申请退款的。为了避免这类情况发生,用户可用以下方式关闭应用内内购:

关于用户在内购遇到的其他问题,可前往技术支持查询

1.3、审核

如果APP支持游客模式,那么内购也一定要支持内购模式,否则就容易审核被拒

2、Apple Pay

Apple Pay可以简单理解成一种支付方式,等同于用户使用银行卡进行刷卡消费,它只是用户和银行之间的桥梁,使用Apple Pay购买商品的时候,其实是通过卡包里面设置的银行卡进行消费支付。
另外Apple Pay跟支付宝、微信支付稍微有些区别,用户可以将钱放入微信和支付宝,支付的时候不需要建立跟银行的关系.

二、App 内购买项目配置流程

内购配置流程图.png

注意点:

三、App 内购买项目流程

官方开发文档

内购支付流程:


官方流程图.png

按照苹果官方流程图,大致流程如下:

1、App业务服务器请求带有产品标识符的产品列表
2、业务服务器返回对应的产品列表
3、AppApp Store请求产品
4、App Store返回对应的产品
5、App向用户在应用商店展示产品
6、用户在应用商店选择一款产品
7、AppApp 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、AppApp Store发送购买请求
8、App Store处理购买请求并返回交易信息
9、App将交易凭证发送给业务服务器
10、业务服务器记录交易凭证并核实
11、业务服务器App Store发送交易凭证验证其有效性
12、App Store解析数据,并返回数据并验证其是否有效
13、业务服务器记录数据,并确定用户购买的产品
14、业务服务器向用户发送购买的产品

方案流程图大致如下:


内购支付流程.png

如果是微信支付宝支付,流程就简单很多,方案如下:


微信支付宝支付流程.png

注意点

四、内购产品类型

区别 消耗性项目 非消耗性项目 自动续期订阅 非自动续期订阅
可购买次数 多次 一次 多次 多次
凭证记录 一次 一直 一直 一直
跨设备同步 不能 系统 系统 APP控制
恢复 不能 系统 系统 APP控制

自动续订

自动续期订阅测试周期如下图,测试环境的订阅时长要比正式环境短很多,方便我们在沙盒测试的进行测试,另外自动续订每天做多只能续订6次

实际时限 测试时限
1周 3分钟
1个月 5分钟
2个月 10分钟
3个月 15分钟
6个月 30分钟
1年 1小时

五、验证购买凭证接口

验证购买凭证接口请求参数

参数 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"
        }
    ]
}

六、错误码

1、购买产品返回的错误码

  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)

3、验证接口返回的错误码

 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

上一篇下一篇

猜你喜欢

热点阅读