iOS 自動訂閱開發

1、代碼邏輯

關於iOS 訂閱、自動訂閱 自己功能開發很簡單。跟正常的購買沒什麼大的差別。惟一須要特殊處理(自動訂閱)的是,html

在APP啓動時候要增長偵聽:ios

        [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; 

由於自動訂閱,除了第一次購買行爲是用戶主動觸發的。後續續費都是Apple自動完成的,通常在要過時的前24小時開始,蘋果會嘗試扣費,扣費成功的話 會在APP下次啓動的時候主動推送給APP。因此,APP啓動的時候必定要添加上面的那句話。web

另外就是處理續費了:服務器

- (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,這時候你得注意你得網絡請求隊列,不要最後一個訂單請求覆蓋了 前幾個。(能夠用信號量處理下,比較簡單)併發

2、服務器驗證receipt

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

一、那就是建立自動訂閱的時候須要新建一個共享祕鑰,就是一串字母。ide

二、服務器在向蘋果服務器校驗receipt時候,不只須要傳receipt,還須要傳祕鑰。測試

{
    「receipt-data」 : 「(actual receipt bytes here)」
    「password」 : 「(shared secret bytes here)」
}

三、介紹下receipt結構ui

 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/

 

3、自動續費測試

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

先看下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 呢?在國內,通常都是前者。

4、討論

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.關於普通消費商品,如何防止黑卡、掉單、外幣等?

我有時間會再寫一篇。

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

相關文章
相關標籤/搜索