zoukankan      html  css  js  c++  java
  • iOS 自动续期订阅 恢复购买

    https://blog.csdn.net/Kun__kun/article/details/115525030

    恢复购买

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

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

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

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

    事务(Transaction)

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

    1.  
      - (BOOL)application:(UIApplication *)application
    2.  
      didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    3.  
      {
    4.  
        /* ... */
    5.  
        [[SKPaymentQueue defaultQueue] addTransactionObserver:observer];
    6.  
      }

    完成事务要调用:

    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];

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

    购买后的记录依据

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

    验证收据

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

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

    获取receiptData:

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

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

    1.  
      //先对receiptData用base64编码
    2.  
      NSString *receiptBase64 = [receiptData base64EncodedStringWithOptions:0];
    3.  
      //请求参数包含两个字段:“receipt-data”和”password“,其中”password“是自动续期订阅的密钥,其他类型的内购没有这个密钥就不会加这个参数。
    4.  
      NSDictionary *params = @{@"receipt-data":receiptBase64, @"password":secretKey};
    5.  
      //将params转成jsonData
    6.  
      NSData *jsonData = [NSJSONSerialization dataWithJSONObject:params
    7.  
      options:NSJSONWritingPrettyPrinted
    8.  
      error:nil];
    9.  
      //下面就是网络请求,例如
    10.  
      NSMutableURLRequest *req = [[NSMutableURLRequest alloc] initWithURL:url];
    11.  
      [req setHTTPMethod:@"POST"];
    12.  
      [req setHTTPBody:jsonData];
    13.  
      NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:req delegate:self];
    14.  
      ...
    解析收据: 请求成功后返回的数据类似这个格式:
    
    
    
    1.  
      {"status": , //如果收据有效,则为0,其他值表示错误
    2.  
      "receipt": ,
    3.  
      "latest_receipt": ,
    4.  
      "latest_receipt_info": , //只返回包含自动更新订阅的收据。这个键的值是一个包含所有应用程序内购买交易的数组。这排除了已经被你的应用标记为完成的消耗品的交易。
    5.  
      "latest_expired_receipt_info": ,
    6.  
      "pending_renewal_info": ,
    7.  
      "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

  • 相关阅读:
    P2519 [HAOI2011]problem a
    P1084 疫情控制
    P1941 飞扬的小鸟
    NOIP填坑计划
    P2831 愤怒的小鸟
    AGC 16 D
    P3960 列队
    Python3爬虫相关软件,库的安装
    软件理论基础—— 第一章命题逻辑系统L
    软件理论基础——导论
  • 原文地址:https://www.cnblogs.com/itlover2013/p/15041510.html
Copyright © 2011-2022 走看看