關於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,這時候你得注意你得網絡請求隊列,不要最後一個訂單請求覆蓋了 前幾個。(能夠用信號量處理下,比較簡單)併發
服務器在校驗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/
重點都不是上面的,重點是測試,如何測試?尤爲自動續費怎麼測?
先看下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://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
關於驗證:
關於預防刷:
http://blog.csdn.net/skylin19840101/article/details/71757055