恢复购买

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

//调起苹果内购恢复接口
[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];

“消耗型项目”和“非续期订阅”苹果不会提供恢复的接口,不要调用上述方法去恢复,否则有可能被拒。 “非续期订阅”也是“跨设备同步”的,所以原则上来说也需要提供恢复购买的功能,但需要依靠app自建的账户体系恢复,不能用上述苹果提供的接口。

恢复购买将为用户完成的每个事务创建一个新事务,基本上是为事务队列观察者重新播放历史记录。

事务(Transaction)

内购事务的观察者应尽早设置好,例如在程序启动后马上设置:

- (BOOL)application:(UIApplication *)applicationdidFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{/* ... */[[SKPaymentQueue defaultQueue] addTransactionObserver:observer];
}

完成事务要调用:

[[SKPaymentQueue defaultQueue] finishTransaction:transaction];

完成事务会告诉StoreKit你已经完成了购买所需的一切。未完成的事务将一直留在队列中,直到它们完成为止,每次启动应用程序时都会调用事务队列观察者,以便应用程序能够继续去完成未被完成的事务。你的应用需要完成每一笔交易,不管交易成功还是失败。 需要注意:在你完成一个事务之后,不应该再对这次交易做任何操作,例如交付产品或者验证交易是否有效等。如果还有工作要做,那证明你还没有准备好完成这个事务。应在所有必要的工作完成后,再调用完成事务的方法。

购买后的记录依据

对于iOS 7及以后的非消耗品和自动续期订阅,使用app收据作为你的持久记录。 对于iOS 7之前版本的非消耗品和自动续期订阅,请使用用户默认系统或iCloud保存持久记录。 对于非续期的订阅,请使用iCloud或你自己的服务器来保存持久记录。 对于消耗品,应用程序更新其内部状态以反映购买情况,但不需要保存持久记录,因为消耗品不会跨设备恢复或同步。

验证收据

应用程序收据包含用户购买的记录,由苹果公司以密码签署。 对于消耗型项目,信息在付款时添加到收据中,并保留在收据中,直到你完成交易。在你完成交易之后,该信息将在下一次更新收据时被删除——例如,下一次用户进行购买时。 所有其他类型的购买信息在付款时被添加到收据中,并无限期地保留在收据中。

收据的验证应该在服务端去做,这样更加安全。 自动续期订阅验证收据时必须要带上密钥。

获取receiptData:

// Load the receipt from the app bundle.
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
if (!receiptData) { /* No local receipt -- handle the error. */ }
/* ... Send the receipt data to your server ... */

测试环境url:https://sandbox.itunes.apple.com/verifyReceipt 正式环境url:https://buy.itunes.apple.com/verifyReceipt 获取收据数据:

//先对receiptData用base64编码
NSString *receiptBase64 = [receiptData base64EncodedStringWithOptions:0];
//请求参数包含两个字段:“receipt-data”和”password“,其中”password“是自动续期订阅的密钥,其他类型的内购没有这个密钥就不会加这个参数。
NSDictionary *params = @{@"receipt-data":receiptBase64, @"password":secretKey};
//将params转成jsonData
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params
options:NSJSONWritingPrettyPrinted
error:nil];
//下面就是网络请求,例如
NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:url];
[req setHTTPMethod:@"POST"];
[req setHTTPBody:jsonData];
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];
...
解析收据: 请求成功后返回的数据类似这个格式:
{"status": , //如果收据有效,则为0,其他值表示错误"receipt": , "latest_receipt": ,"latest_receipt_info": , //只返回包含自动更新订阅的收据。这个键的值是一个包含所有应用程序内购买交易的数组。这排除了已经被你的应用标记为完成的消耗品的交易。"latest_expired_receipt_info": ,"pending_renewal_info": ,"is-retryable": ,}
对于收据中每个字段的说明,参考苹果官方文档: https://developer.apple.com/library/archive/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html#//apple_ref/doc/uid/TP40010573-CH104-SW1

这里说明一下自动续期订阅的验证问题: latest_receipt_info中包含所有订阅的交易信息,这是一个数组,里面每个元素代表一次订阅交易,元素中有expires_date_ms的字段表示订阅的过期时间,purchase_date_ms表示订阅的购买时间,product_id表示订阅的产品id,is_trial_period表示是否是免费试用。 需要注意,latest_receipt_info中的元素没有特定的排序,我们应该先将latest_receipt_info中的元素按expires_date_ms升序排序,然后获取最后一个元素,这个元素就是最新的交易信息。 另外,收据的json解析有可能会出错,要注意错误处理。

订阅后联系苹果退款

订阅在购买时全额支付。用户只有联系苹果客服才能获得退款。例如,如果用户不小心购买了错误的产品,可以取消订阅,并发出全额或部分退款。 要检查购买是否已经被“Apple客户支持”取消,请在收据中查找cancel Date字段。如果字段包含日期,无论订阅的过期日期如何,购买都已取消。

自动续期订阅的免费试用(促销价)

假如订阅设定了促销价,例如免费试用,SKProduct对象的introductoryPrice属性会有值,这个属性包含了促销价的信息,开发者应该根据这个属性去显示促销的相关UI。

“非续期订阅”不同于”自动续期订阅“的地方

非续期订阅与自动续期订阅在几个关键方面有所不同。这些差异使你的应用程序具有灵活性,可以根据你的需要实现正确的行为,对于“非续期订阅”: 你的应用程序负责计算订阅有效的时间段,并确定需要向用户提供哪些内容。 你的应用程序负责检测订阅即将过期,并通过再次购买产品提示用户更新订阅。 你的应用程序负责在用户的所有设备提供订阅,并让用户恢复过去的购买。例如,大多数订阅由服务器提供,你的服务器需要一些机制来识别用户,并将订阅购买与购买它们的用户关联起来。

测试

在沙盒环境中自动续期订阅时限会缩短,便于测试:

实际时间 测试时间
1周 3分钟
1个月 5分钟
3个月 15分钟
1年 1小时

测试订阅每天最多仅能自动续期 6 次。

审核

审核人员会用沙盒账号测试内购,所以在审核的时候,收据验证要用测试环境的url去验证,不然会因为验证失败而被拒绝。 推荐的做法是,验证收据时,如果status==21007,就用测试环境的url再次验证,如果status==21008,就用正式环境的url再次验证。

自动续期订阅需要做一个自动续期会员说明,这个说明放在app的内购页面中,并且在AppStoreConnect中的描述中也要写一次,不然也会被拒绝,怎么写,可以参考优酷,爱奇艺app的描述。

相关资料连接

https://help.apple.com/app-store-connect/#/devb57be10e7

https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Introduction.html#//apple_ref/doc/uid/TP40008267-CH1-SW1

https://developer.apple.com/library/archive/releasenotes/General/ValidateAppStoreReceipt/Introduction.html#//apple_ref/doc/uid/TP40010573-CH105-SW1

转载: 作者:dengshunlai

iOS 自动续期订阅 恢复购买相关推荐

  1. iOS 自动续期订阅,订阅升级降级、订阅时间、退收费处理

    自动续期订阅群组设置概述 设置自动续期订阅与设置其他 App 内购买项目类型不同.每个自动续期订阅产品需创建为订阅群组的一部分并为其分配等级.您对订阅群组的设置将决 定顾客如何订阅您的内容或服务.如何 ...

  2. php++内购续期订阅,iOS内购:自动续期订阅总结

    前言:内购类型有四种:消耗型商品,非消耗型商品,非续期订阅,自动续期订阅. 顾名思义,从中最有难度的就是自动续期订阅的实现,开通自动续期订阅后,订阅会员的处理将会遇到如下问题:自动订阅的到期继续自动订 ...

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

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

  4. iOS内购:自动续期订阅总结

    前言:内购类型有四种:消耗型商品,非消耗型商品,非续期订阅,自动续期订阅. 顾名思义,从中最有难度的就是自动续期订阅的实现,开通自动续期订阅后,订阅会员的处理将会遇到如下问题:自动订阅的到期继续自动订 ...

  5. ios自动订阅服务器,iOS IAP - 自动续期订阅

    自动续期订阅是苹果推出的一项苹果内购服务,当用户在App Store订阅了某项服务后,App Store会在订阅时间快到期之前,自动扣费并帮用户续订该服务. 自动续期订阅的优势 创建自动续期订阅 1. ...

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

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

  7. ios自动订阅服务器,任何(早期)iOS自动续订订阅体验

    我让它在沙盒中运行,几乎上线了...... 应该使用服务器来验证收据 . 在服务器上,您可以使用收据数据记录设备udid,因为收据始终是新生成的,并且它可以在多个设备上运行,因为收据总是新生成的 . ...

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

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

  9. php++内购续期订阅,关于自动订阅(auto renewal)

    关于内购项目的基本配置,在此就不啰嗦了,需要注意的是我们配置内购项目的时候,选择类型为"自动续期订阅"即可.具体的内购项目的配置在这里 本篇文章主要记录代码实现自动续期订阅与普通内 ...

最新文章

  1. Vivado中两种RTL原理图的查看方法和区别
  2. 3. Leetcode 16. 最接近的三数之和 (数组-双向双指针)
  3. 2009年3月全国计算机等级考试二级vfp笔试,2009年3月全国计算机等级考试二级VFP笔试试题及答案.doc...
  4. 如何理解JavaScript中给变量赋值,是引用还是复制
  5. diff 命令用法--如何打补丁【原创--学习笔记】
  6. 怎样开图纸便宜_一步一步教你如何看懂工程图纸,值得收藏!
  7. shell判断文件与字符串
  8. thinkphp --- 写入日志
  9. navicat如何创建视图
  10. IDEA炫酷主题推荐!非常好看!
  11. 女研究生做“思维导图”与男友吵架!网友:吵架届的“内卷之王”....
  12. 作为史上最疯狂的科学家,特斯拉提出过哪些惊世骇俗的设想
  13. jarvisoj_typo
  14. 美团酒店:如何收割新一代90后住宿需求? | 一点财经
  15. Allegro模块布局和布局复用
  16. RHEL 7 安装oracle rac 11.2.0.4执行root.sh报错ohasd failed to start
  17. 3GPP TS 23501-g51 中英文对照 | 5.2.2 Network selection
  18. 图形绘制canvas
  19. VB学习过程(二)VB的语法基础和常用的内部函数
  20. 服务器磁盘满了 处理过程

热门文章

  1. 对strstr函数的理解.
  2. 在线图片上传 POST文件
  3. uni-app开发微信小程序使用腾讯地图选点和城市选择器插件
  4. 古人航海怎么定位?带你领略古人的智慧
  5. 前端Vue H5生成带二维码的分享海报,实现长按保存到手机相册
  6. 关于生命和人工智能的一些遐想
  7. jQuery - Chaining
  8. GTA5内置html菜单源码,《GTA5》稀有车收集教程 二十七:全配件载具合集
  9. 1.1-PCL点云及其可视化
  10. android 中限制 eidttext输入emjoy表情