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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM