iOS 自動訂閱開發


一、代碼邏輯

關於iOS 訂閱、自動訂閱 本身功能開發很簡單。跟正常的購買沒什么大的差異。唯一需要特殊處理(自動訂閱)的是,

在APP啟動時候要增加偵聽:

        [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; 

因為自動訂閱,除了第一次購買行為是用戶主動觸發的。后續續費都是Apple自動完成的,一般在要過期的前24小時開始,蘋果會嘗試扣費,扣費成功的話 會在APP下次啟動的時候主動推送給APP。所以,APP啟動的時候一定要添加上面的那句話。

另外就是處理續費了:

- (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;
        }
    }
}            

  上述代碼片段對 transaction.originalTransaction 進行了判斷,如果有內容一定為訂閱類型的。為什么在這加個判斷處理,是因為續費 是發生在APP啟動的時候,這時候你登錄流程等可能還沒有走完,因為有的游戲在跟服務器進行 校驗的時候會傳一些userid等信息,或是加密的信息,視情況而定,是否要區分處理。

      注意點:就是在沙箱環境測試時候,APP啟動可能得到5次的 - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions ;訂單處理,算是要並發處理case SKPaymentTransactionStatePurchased: 這種case,這時候你得注意你得網絡請求隊列,不要最后一個訂單請求覆蓋了 前幾個。(可以用信號量處理下,比較簡單)

二、服務器驗證receipt

服務器在校驗receipt時候也就有一個坑:

1、那就是創建自動訂閱的時候需要新建一個共享秘鑰,就是一串字母。

2、服務器在向蘋果服務器校驗receipt時候,不僅需要傳receipt,還需要傳秘鑰。

{
    “receipt-data” : “(actual receipt bytes here)”
    “password” : “(shared secret bytes here)”
}

3、介紹下receipt結構

 receipt通過base64解碼可得:

{
	"signature" = "dfreree...."; //也是base64 
	"purchase-info" = "ewoJIm9x....."; //也是base64,這個里面存放詳細時間,流水號等
	"environment" = "Sandbox";
	"pod" = "100";
	"signing-status" = "0";
}

"purchase-info"可以再次base64解碼可得:

{
	"original-purchase-date-pst" = "2017-08-29 23:52:45 America/Los_Angeles";
	"purchase-date-ms" = "1504144439749";
	"unique-identifier" = "a063c2c321dd885642a5cddd9160e0ad8291d978";
	"original-transaction-id" = "1000000328915948";
	"expires-date" = "1504144739749";
	"transaction-id" = "1000000329310742";
	"original-purchase-date-ms" = "1504075965000";
	"web-order-line-item-id" = "1000000036091900";
	"bvrs" = "1";
	"unique-vendor-identifier" = "B78549AC-58D4-4750-8E6F-F4CCE6138A5A";
	"expires-date-formatted-pst" = "2017-08-30 18:58:59 America/Los_Angeles";
	"item-id" = "1276511095";
	"expires-date-formatted" = "2017-08-31 01:58:59 Etc/GMT";
	"product-id" = "lcm.denachina.pickle.38.1month";
	"purchase-date" = "2017-08-31 01:53:59 Etc/GMT";
	"original-purchase-date" = "2017-08-30 06:52:45 Etc/GMT";
	"bid" = "com.denachina.pickle";
	"purchase-date-pst" = "2017-08-30 18:53:59 America/Los_Angeles";
	"quantity" = "1";
}

  你想要的東西,都可以獲取到。客戶端可以做這些事情,但是沒有多大必要,還是服務器處理得好。(對於無服務器APP只能客戶端處理了)

      附上一個在線base64解碼的:http://base64.xpcha.com/

 

三、自動續費測試

重點都不是上面的,重點是測試,如何測試?尤其自動續費怎么測?

先看下Apple原文檔:

When testing auto-renewable subscriptions in the test environment, keep in mind that the duration times are compressed. Additionally, test subscriptions only auto-renew a maximum of six times. Table 3-1 lists the compressed duration times.

Actual duration

Test duration

1 week

3 minutes

1 month

5 minutes

2 months

10 minutes

3 months

15 minutes

6 months

30 minutes

1 year

1 hour

意思就是,沙箱環境 自動續費時間縮短了,一周 對應 三分鍾,一月 對應 五分鍾。。。

購買完一個一周 類型訂閱,就不要在APP不退出的情況等待了,必須3分鍾 或是 10分鍾后重新登錄,Apple才會主動告知你結果,也就是第一點提到的。

 

測試中會遇到幾個問題:

1.沙箱環境自動續費是一定會自動續費的嗎?

答案:不一定的,有時候會,有時候不會。所以要多測測,多建幾個測試賬號。

2.是否需要實現restoreCompletedTransactions ?

答案:視需求吧。有少量文章說2014年起蘋果審核嚴格了,必須要有一個按鈕實現restoreCompletedTransactions。另外,我聽百度一位同學說,愛奇藝2015年因為這個被拒過。但是,目前來看很多使用了訂閱的應用或是游戲,並沒有這個功能。

我是感覺,看需求了。訂閱 是跟着 userid 唯一呢? 還是跟着apple id 呢?在國內,一般都是前者。

四、討論

1.自動訂閱歸屬的問題:

a.  蘋果設計自動訂閱的初衷是 ,訂閱一個服務, 這個服務需要跟着 Apple ID走。說白了,就是你A設備 用了Apple賬號100001購買了,你換了B設備 用Apple賬號100001登錄app store,你同樣能享受到服務。國外的一些音樂類型、雜志報刊等用的比較多,游戲類的少,蘋果自己的Apple music也有自動訂閱(首創)。

b.  目前國內的一些應用或是游戲,希望的是自動訂閱 關聯的是 APP的 user id ,而不是Apple ID。說白了,就是你購買了一個自動訂閱服務,我不管你哪個apple id 支付的, 但是只能我一個 APP的 唯一用戶可以享受服務。這時候就需要APP自身做處理了,就是記住首次購買的transaction-id,並且綁定某個用戶。以后自動續費的話,都會有original-transaction-id,這個id 是第一次購買的transaction-id,根據這個服務器可以聯系初始購買的服務。有點描述偏了,當transaction-id綁定了用戶,再次收到其它用戶transaction-id請求時候,視情況處理了。(你也可以根據unique-vendor-identifier處理)

2.同一個Apple ID購買完的自動訂閱,可以再次點擊購買嗎(有效期內)?

答案:不可以,蘋果自身會攔截,會出現這么個提示窗,如下圖:

但是,sandbox測試環境,在第三大點的對應表格對應時間內,apple會攔截的,過了這個時間蘋果是不會攔截的。

3.夠買了自動訂閱3個月的,可以換購 1年的  或是 1個月的嗎?

答案:可以,蘋果文檔有提到,視為升級訂閱套餐  或是 降級訂閱套餐。

4.關於掉單的問題

答案:一定要在服務器校驗完票據后,客戶端收到服務器的反饋結果后再:

[[SKPaymentQueue defaultQueue] finishTransaction: transaction];

5.關於普通消費商品,如何防止黑卡、掉單、外幣等?

我有時間會再寫一篇。

五、了解更多

https://developer.apple.com/library/content/documentation/LanguagesUtilities/Conceptual/iTunesConnectInAppPurchase_Guide/Chapters/CreatingInAppPurchaseProducts.html#//apple_ref/doc/uid/TP40013727-CH3-SW10

https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/Subscriptions.html

https://stackoverflow.com/questions/8033673/ios-sandbox-environment-auto-renewal-subscription

http://www.jianshu.com/p/28fc3cc8c49f

http://www.cnblogs.com/zidong0822/p/4701839.html

http://blog.csdn.net/xiaoyuanzhiying/article/details/46708043

http://www.jianshu.com/p/e9e4dc3dc9ee

https://www.raywenderlich.com/154737/app-purchases-auto-renewable-subscriptions-tutorial

http://www.360doc.com/content/14/1118/16/12282510_426165722.shtml

關於驗證:

https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html

https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ReceiptFields.html#//apple_ref/doc/uid/TP40010573-CH106-SW20

關於預防刷:

http://blog.csdn.net/skylin19840101/article/details/71757055


免責聲明!

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



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