前言:内购类型有四种:消耗型商品,非消耗型商品,非续期订阅,自动续期订阅. 顾名思义,从中最有难度的就是自动续期订阅的实现,开通自动续期订阅后,订阅会员的处理将会遇到如下问题:自动订阅的到期继续自动订阅的处理,订阅取消的处理,取消后又在App Store开启自动订阅的处理等一系列问题。我希望通过此篇,能提供完整的思路给需要的人,并希望读者能一起探讨成长。

1. 自动续订订阅前期准备

前期准备无非就是在App Store 建内购的选项,这部分网上有很多文章,我直接推荐看此篇 https://www.jianshu.com/p/479cf9e31104 完成前期准备及一些常理的知识了解。当然,项目中我也是直接集成IAPHelper https://github.com/saturngod/IAPHelper 进行内购API集成。

2. 自动续订服务端验证

主要参考如下解决:

http://www.cnblogs.com/zhaoqingqing/p/4597794.html

https://baijunyao.com/article/106

上面的部分解决了消耗型商品内购的功能。

但是此篇是自动订阅:所以需要增加一个参数: password: 秘钥, 就可以了, 但是官方文档说秘钥仅仅用在自动续订上面

大家叫后台加个验证,如果苹果验证返回21004的话(21004 你提供的共享密钥和账户的共享密钥不一致),就加上password字段去验证,可以成功。 秘钥去https://itunesconnect.apple.com/ 里面对应的APP里创建

image

经过验证:购买过自动续期订阅后,验证内购时(即使是消耗型商品)必须带上password字段。

3. 自动续订服务端验证问题

2中主要是手机内购成功后传receipt给服务端,然后去验证的。然后有没有想到很多需解决的问题?

3.1 订阅状态的处理

状态更新通知

第2网址中间能看到如下的介绍:

A statusUpdateNotification是用于自动续订订阅的服务器到服务器通知服务。通知指定发送通知时的订阅状态。

要在处理事件时获取最新信息,您的应用应通过App Store验证最新收据。建议您使用状态更新通知服务以及收据验证来验证用户的当前订阅状态并为其提供服务。有关收据验证的信息,请参阅“ 收据验证编程指南”。

要接收状态更新通知,请在App Store Connect中为您的应用配置订阅状态URL。App Store将通过HTTP POST将JSON对象传送到您的服务器,以获取表6-3中列出的密钥订阅事件。您的服务器负责解析,解释和响应所有statusUpdateNotification帖子。

但是状态只有如下五种:INITIAL_BUY,CANCEL,RENEWAL,INTERACTIVE_RENEWAL,DID_CHANGE_RENEWAL_PREF。缺了用户无操作自动订阅的通知??!

用户无操作自动订阅通知

If you read the description of the RENEWAL event, you will note - "Automatic renewal was successful for an expired subscription. Check Subscription Expiration Date to determine the next renewal date and time." In general, iTunes will attempt to charge the user account a day before an auto-renewing subscription is scheduled to expire. If the renewal is successful, there is no server-to server notification because the auto-renewing subscription did not enter into an expired state. However, in the few cases that iTunes is unable to renew the subscription (generally there was a connection problem with the credit card server) and the auto-renewing subscription is not renewed before the expiration_date passes, the auto-renewing subscription is technically considered “expired”. However, iTunes will still continue to attempt to renew the subscription. It iTunes is successful, then the “RENEWAL” event is sent. for this reason, the advice is presented - “Check Subscription Expiration Date to determine the next renewal date and time.”

主要处理如下:

如果您阅读了RENEWAL事件的描述,您将注意到 - “过期订阅的自动续订成功。检查订阅到期日期以确定下一个续订日期和时间。” 通常,iTunes会在计划自动续订订阅到期前一天尝试向用户帐户收费。如果续订成功,则没有服务器到服务器通知,因为自动续订订阅未进入过期状态。但是,在少数情况下,iTunes无法续订订阅(通常与信用卡服务器存在连接问题)并且在expiration_date通过之前未续订自动续订订阅,从技术上讲,自动续订订阅被视为“过期”。然而,iTunes仍将继续尝试续订订阅。iTunes成功,然后发送“RENEWAL”事件。出于这个原因,提出了建议 - “检查订阅到期日期以确定下一个续订日期和时间”。

要验证自动续订订阅In-App Purchase是否是最新的,请使用verifyReceipt服务器验证appStoreReceipt。假设in_app数组中存在自动续订订阅项,则查看latest_receipt_info记录并查找具有晚于当前日期的expires_date的订阅记录,其中一个未设置cancellation_date字段。备注:被退款订单的唯一标识是:它带有一个cancellation_date字段。

参考:https://forums.developer.apple.com/message/283579#283579

注意

in_app与latest_receipt_info

测试时发现,这两个字段的数值几乎相同,不过有几点需要注意:

(1)自动续订订阅类型,在到期后会再生成一条购买记录,这条记录会出现在last_receipt_info里,但不会出现在in_app里

(2)自动续订订阅类型可以配置试用,试用记录只有在latest_receipt_info里,is_trial_period字段才是true

(3)消耗型购买记录有可能不会出现在latest_receipt_info,因此需要检查in_app来确保校验正确

用户取消订阅

购买了一个订阅后得全额付款,只有通过联系苹果客服服务才能退款。 比如,如果用户意外买错了产品,客服中心可以取消该交易并退款。 用户不能在订阅周期中间改变注意不支付剩余的订阅。

要想确认某次交易是否已经被取消,在收据 (receipt) 中查找 Cancellation Date (取消日期)字段。 如果该字段有日期,不管该订阅的过期日期是什么,该交易都已经被取消---取消交易就是跟没有购买过一样。

根据产品类型,只能检查当前的活动交易,可能需要检查过去所有的交易。比如,杂志应用需要检查过去所有的交易来决定用户访问了那些期刊。

附下自动订阅的小票:

string(42) "https://buy.itunes.apple.com/verifyReceipt"

string(16) "{"status":21007}"

string(46) "https://sandbox.itunes.apple.com/verifyReceipt"

string(9266) "{"status":0, "environment":"Sandbox",

"receipt":{"receipt_type":"ProductionSandbox", "adam_id":0, "app_item_id":0, "bundle_id":"com.mbalib.ios.wiki", "application_version":"244", "download_id":0, "version_external_identifier":0, "receipt_creation_date":"2018-07-18 07:55:17 Etc/GMT", "receipt_creation_date_ms":"1531900517000", "receipt_creation_date_pst":"2018-07-18 00:55:17 America/Los_Angeles", "request_date":"2018-07-18 07:55:46 Etc/GMT", "request_date_ms":"1531900546430", "request_date_pst":"2018-07-18 00:55:46 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":"com.mbalib.ios.wiki_r", "transaction_id":"1000000419163890", "original_transaction_id":"1000000419163890", "purchase_date":"2018-07-18 07:55:15 Etc/GMT", "purchase_date_ms":"1531900515000", "purchase_date_pst":"2018-07-18 00:55:15 America/Los_Angeles", "original_purchase_date":"2018-07-18 07:55:17 Etc/GMT", "original_purchase_date_ms":"1531900517000", "original_purchase_date_pst":"2018-07-18 00:55:17 America/Los_Angeles", "expires_date":"2018-07-18 08:55:15 Etc/GMT", "expires_date_ms":"1531904115000", "expires_date_pst":"2018-07-18 01:55:15 America/Los_Angeles", "web_order_line_item_id":"1000000039541410", "is_trial_period":"true", "is_in_intro_offer_period":"false"}]},

"latest_receipt_info":[

{"quantity":"1", "product_id":"com.mbalib.ios.wiki_r", "transaction_id":"1000000419163890", "original_transaction_id":"1000000419163890", "purchase_date":"2018-07-18 07:55:15 Etc/GMT", "purchase_date_ms":"1531900515000", "purchase_date_pst":"2018-07-18 00:55:15 America/Los_Angeles", "original_purchase_date":"2018-07-18 07:55:17 Etc/GMT", "original_purchase_date_ms":"1531900517000", "original_purchase_date_pst":"2018-07-18 00:55:17 America/Los_Angeles", "expires_date":"2018-07-18 08:55:15 Etc/GMT", "expires_date_ms":"1531904115000", "expires_date_pst":"2018-07-18 01:55:15 America/Los_Angeles", "web_order_line_item_id":"1000000039541410", "is_trial_period":"true", "is_in_intro_offer_period":"false"}],

"latest_receipt":"MII.....",

"pending_renewal_info":[

{"auto_renew_product_id":"com.mbalib.ios.wiki_r", "original_transaction_id":"1000000419163890", "product_id":"com.mbalib.ios.wiki_r", "auto_renew_status":"1"}]}"

{"error":"\u8be5\u4ea7\u54c1\u4e0d\u5b58\u5728","errorno":13105}

添加自动订阅免费试用:

image

如果用户再同一自动订阅组,如用户自动订阅买过,免费试用标识就要隐藏掉。因为内购支付购买不会出现免费试用。

首次购买 is_trial_period = true; is_in_intro_offer_period是否是否是在试用期 ; expires_date-purchase_date 就是免费的周期

自动订阅expires_date 会苹果会自动订阅,然后App启动会- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions

在APP启动时候要增加侦听:

[[SKPaymentQueue defaultQueue] addTransactionObserver:self];

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions

{

for (SKPaymentTransaction *transaction in transactions)

{

switch (transaction.transactionState)

{

case SKPaymentTransactionStatePurchasing: // 0

break;

case SKPaymentTransactionStatePurchased: // 1

//订阅特殊处理

if(transaction.originalTransaction){

//如果是自动续费的订单originalTransaction会有内容

}else{

//普通购买,以及 第一次购买 自动订阅

}

break;

case SKPaymentTransactionStateFailed: // 2

[self failTracker:transaction];

break;

case SKPaymentTransactionStateRestored: // 3

[self restoreTransaction:transaction];

break;

default:

break;

}

}

}

[latest_receipt_info] => Array

(

[0] => Array

(

[quantity] => 1

[product_id] => com....

[transaction_id] => 1000000498609863

[original_transaction_id] => 1000000498609863

[purchase_date] => 2019-01-30 09:12:46 Etc/GMT

[purchase_date_ms] => 1548839566000

[purchase_date_pst] => 2019-01-30 01:12:46 America/Los_Angeles

[original_purchase_date] => 2019-01-30 09:12:47 Etc/GMT

[original_purchase_date_ms] => 1548839567000

[original_purchase_date_pst] => 2019-01-30 01:12:47 America/Los_Angeles

[expires_date] => 2019-01-30 09:15:46 Etc/GMT

[expires_date_ms] => 1548839746000

[expires_date_pst] => 2019-01-30 01:15:46 America/Los_Angeles

[web_order_line_item_id] => 1000000042488789

[is_trial_period] => true

[is_in_intro_offer_period] => false

)

)

让用户管理订阅

不需要编码实现订阅管理 UI ,应用程序可以打开以下 URL

参考:

php++内购续期订阅,iOS内购:自动续期订阅总结相关推荐

  1. ios内购返回html,iOS内购掉单问题处理方法

    iOS内购提供了两种模式,一种是单机(本地验证)模式,另一种是服务器端验证模式. 单机验证模式:适用于单机应用,安全性低,数据易被篡改. 服务器验证模式:应用服务器提交支付票据到苹果服务器验证,安全性 ...

  2. iOS开发,自动续期订阅的坑

    自动续期订阅相较于普通内购,需要一个共享密钥,这个共享密钥在申请内购时获得.秘钥用于向苹果服务器请求收据信息. 购买过程不再赘述. 购买成功后,自动续期订阅最大的问题在于购买成功后是否续期成功,和到期 ...

  3. iOS内购(IAP)自动续订订阅

    一.介绍 iOS 的 App 内购类型有四种: 消耗型商品:只可使用一次的产品,使用之后即失效,必须再次购买. 示例:钓鱼 App 中的鱼食. 非消耗型商品:只需购买一次,不会过期或随着使用而减少的产 ...

  4. IOS内购自动续费订阅测试

    一.IOS 内购类型 1.消耗型商品: 只可使用一次的产品,使用之后即失效,必须再次购买. 示例:抽奖券. 2.非消耗型商品: 只需购买一次,不会过期或随着使用而减少的产品. 示例:游戏 App 的赛 ...

  5. php++内购续期订阅,appstore:内购项目之自动续期订阅

    自动续期订阅指南 自动续期订阅让用户能持续地访问App中的内容.服务或高级功能.除非用户选择取消订阅,否则自动续期订阅会在到期时自动续期.设置自动续期订阅,与设置其他App内购买项目类型不同.每个自动 ...

  6. iOS内购-防越狱破解刷单

    ---------------------------2018.10.16更新--------------------------- 最近我们公司丢单率上涨,尤其是10月份比9月份来说丢单率翻了3倍, ...

  7. IOS内购经常遇到的一些问题,和一些容易混淆的点。

    Q1:内购和Apple Pay的区别? A1:内购是内购,Apple Pay是Apple Pay.我不知道有多少人第一次接触时,会把这俩概念混淆掉,这里你可以简单这么理解,虚拟的物品就是用内购,实际的 ...

  8. 应用内购:自动更新订阅教程

    原文:In-App Purchases: Auto-Renewable Subscriptions Tutorial 作者:Chris Wagner 译者:kmyhy 苹果在 WWDC 2016 前推 ...

  9. iOS 自动续期订阅 恢复购买

    恢复购买 内购有4种:消耗型项目,非消耗型,自动续期订阅,非续期订阅. 其中"非消耗型"和"自动续期订阅"需要提供恢复购买的功能,例如创建一个恢复按钮,不然审核 ...

最新文章

  1. idea基于hibernate生成的Entitle对象,会忽略外键属性
  2. Ubuntu下安装realtek的rtl8188eu网卡芯片驱动
  3. leetcode416. Partition Equal Subset Sum
  4. python设计模式1-单例模式
  5. 一夜抢空880万!中国最狠印钞机,终于开始收割年轻人了
  6. Spring官网下载dist.zip的几种方法
  7. gin mysql_golang+gin+mysql构建RESTful API
  8. 在网页HTML中嵌入QQ、MSN、旺旺、Gtalk快速对话框代码
  9. 航空三字代码表_目前最全的航空城市三字代码表
  10. 蓝丝雨零基础学习按键精灵VIP教程合集
  11. 颜色的原理,三基色原理以及HLS(色相、亮度、饱和度)原理
  12. tableau 发布
  13. dub选项中文帮助.
  14. 从指数构建原理看待A股的三千点魔咒
  15. Android原生插件开发-开发篇
  16. C++:Leetcode-滑动窗口-904.水果成篮
  17. vb.net 教程 序
  18. 网易云音乐真的是随机播放吗
  19. python 修正系统时差
  20. matlab求和待定系数,数列求和的待定系数裂项法

热门文章

  1. dp:股票系列I II III IV 含冷冻期 含手续费
  2. 小甲鱼31课泡菜课后作业反思
  3. rono在oracle的作用_Ronopterin (VAS203) 在中重度创伤性脑损伤患者中的疗效 (NOSTRA III 期试验): 一项验证性、安慰剂对照、随机、双盲、多中心研究。...
  4. 推荐一个开源的LMS系统ILIAS
  5. 解决重装win10系统找不到驱动器
  6. 【Linux命令】挂盘相关命令,包含可扩展硬盘
  7. 学校计算机教室 计划总结怎么写,学校信息技术教师的工作总结范文
  8. git 命令git 地址_5个高级Git命令来启动您的Git游戏
  9. win10修改用户名_ADAMS2020中/英版软件下载和安装教程|兼容WIN10
  10. 功率谱和功率谱密度-MATLAB