2011年9月21日 星期三

In App Purchase的實作心得分享

其實IAP的一些概念跟使用方法已經有嘎李羊的詳細介紹了,在此貼上連結,但就不再重複分享了
1. iOS In App Purchase 學習筆記 (1)
2. iOS In App Purchase 學習筆記 (2)
3. iOS In App Purchase 學習筆記 (3) : 如何從App Store取得商品資訊

我這邊就補充一下我最近研究IAP的心得,我就分別以三個類型Consumable, Non-consumable, Auto-renewable subscription來分別分享
Consumable
1. 可以透過此來購買Credit(虛擬貨幣),但是必須要在你的app中消費掉,不能拿來購買app以外的商品或是實體商品。
2. 通常實作的方法是交易成功後,程式自己增加購買的點數,這邊的邏輯StoreKit並不會負責幫你做credit增加的部份。
3. 雖然Consumable product可以設定quantity,來一次購買多量的商品,但是我建議還是不要這麼做。你可以用陳列多個商品來達到一次買多量credit的目的。例如:
10credits $0.99
25credits $1.99
50credits $2.99
4. 如果要讓多個device share你的credit好像沒有比較好的方法,因為我們無法取得apple id,所以不知道怎麼share。
而如果把credit存在server,那會不會違背policy這我就不敢說了。

Non-consumble
1. 買了之後就永久有效。即使app移除了再裝回來,或是在別的device裝app,只要用同個apple id就可以restore。
2. 有關restore相關的文章請看 Restoring Transactions
建議在你的app中如果有支援Non-consumable的app,要提供restore的功能,讓使用者有辦法恢復購買。
當然用原本的buy的方法也可以restore,但是比較不user friendly。
3. 交易成功後,記得要把買成功的狀態儲存起來,而app也要對應的打開對應的功能給end-user。

Auto renewable subscription
1. 有點類似Non-consumable product,但是是有時效性的服務。當訂閱週期到了,app store會自動展期,除非使用者取消自動展期。
2. 在itunes connect上面我們可以設定多種duration
3. 使用者可以透過[設定]這個app中的 Store -> Apple ID: -? -> 檢視Apple ID -> Manage Subscriptions 來取消訂閱或是更改週期
4. 比較多人可能會遇到的問題是我要怎麼知道subscription已經因為使用者取消註冊而過期失效了呢?
方法是App中可以透過http post去詢問subscription狀態,
你需要的是記住最後一次交易的receipt (-[SKPaymentTransaction transactionReceipt]),
或是透過restoreTransaction來取得transaction object,再透過其中的receipt來詢問 。
相關的文件在這 Verifying an Auto-renewable Subscription Receipt
下面是如果成功的話會回傳的結果,status = 0 代表成功。
而last_receipt_info可能會跟receipt不一樣,因為有可能server會自動renew subscription。

{
 "latest_receipt_info" =     {
        bid = "com.smartq.MyStore";
        bvrs = "1.0";
        "expires_date" = 1316424354739;
        "expires_date_formatted" = "2011-09-19 09:25:54 Etc/GMT";
        "item_id" = 465588051;
        "original_purchase_date" = "2011-09-19 08:34:24 Etc/GMT";
        "original_transaction_id" = 1000000008159291;
        "product_id" = "com.smartq.mystore.sub1m";
        "purchase_date" = "2011-09-19 09:20:54 Etc/GMT";
        quantity = 1;
        "transaction_id" = 1000000008162671;
    };
    receipt =     {
        bid = "com.smartq.MyStore";
        bvrs = "1.0";
        "expires_date" = 1316424354739;
        "expires_date_formatted" = "2011-09-19 09:25:54 Etc/GMT";
        "item_id" = 465588051;
        "original_purchase_date" = "2011-09-19 08:34:24 Etc/GMT";
        "original_transaction_id" = 1000000008159291;
        "product_id" = "com.smartq.mystore.sub1m";
        "purchase_date" = "2011-09-19 09:20:54 Etc/GMT";
        quantity = 1;
        "transaction_id" = 1000000008162671;
    };
    status = 0;  
而如果失敗的話可能會如下所示,
status = 21006代表subscription expired。
注意的是這次他不會回傳latest_receipt_info,而是lastest_expired_receipt_info

{
    "latest_expired_receipt_info" =     {
        bid = "com.smartq.MyStore";
        bvrs = "1.0";
        "expires_date" = 1316424354739;
        "expires_date_formatted" = "2011-09-19 09:25:54 Etc/GMT";
        "item_id" = 465588051;
        "original_purchase_date" = "2011-09-19 08:34:24 Etc/GMT";
        "original_transaction_id" = 1000000008159291;
        "product_id" = "com.smartq.mystore.sub1m";
        "purchase_date" = "2011-09-19 09:20:54 Etc/GMT";
        quantity = 1;
        "transaction_id" = 1000000008162671;
    };
    receipt =     {
        bid = "com.smartq.MyStore";
        bvrs = "1.0";
        "expires_date" = 1316424354739;
        "expires_date_formatted" = "2011-09-19 09:25:54 Etc/GMT";
        "item_id" = 465588051;
        "original_purchase_date" = "2011-09-19 08:34:24 Etc/GMT";
        "original_transaction_id" = 1000000008159291;
        "product_id" = "com.smartq.mystore.sub1m";
        "purchase_date" = "2011-09-19 09:20:54 Etc/GMT";
        quantity = 1;
        "transaction_id" = 1000000008162671;
    };
    status = 21006;
}    
5. 在開發中我們都是在sandbox mode中測試,但是subscription的週期會因為為了測試方便會短很多,相關的mapping如下
6. 在sandbox mode中只會自動展期五次,第六次會直接expire。

其他注意事項
1. IAP只能在實機上測試,並且只能在sandbox mode下測試,而sandbox mode也只能用測試帳號測試。
2. 測試帳號必須要先在你的itunes connect中,簽署“iOS Paid Applications”這份contract才可以產生。
3. 因為IAP product的價錢可以透過itunes connect上調整,建議商品售價可以透過SKProductRequest去跟itunes connect詢問,而非寫死在code。
下面是4/12/2013新增的
4. Test account請不要在系統的設定(Settings)去登入,也不要留下信用卡帳號,因為一旦使用就不能在sandbox mode中使用
5. 如果你有gmail帳號,你可以用gmail的alias來新增Test account。例如你原本的email是 example@gmail.com,那你可以用example+test@gmail.com去申請。這樣就可以申請一堆測試帳號。
6. 即使是測試帳號,交易過的就不能移除,這對non-consumable product測是很麻煩,唯一的解法就是多產生幾個測試帳號。

Ref
[1] iTunes Connect Developer Guide 7.0
[2] In App Purchase Programming Guide

6 則留言:

  1. 您好...跟您請教一下喔,請問In App Purchase,有沒有不用另外架server的方法?(ps.包在同一個App裡面也不考慮...)感謝感謝...

    回覆刪除
    回覆
    1. IAP本來就不一定要用server啊,除非你需要purchase的content是從server過來的才會有需要。可以詳述一下你的需求是什麼嗎?

      刪除
  2. 請問一下, 回傳21006表示的是使用者已經取消subscription而導致expired了嗎? 謝謝~

    回覆刪除
  3. 請問一下,購買成功的狀態要怎麼儲存?比如說是a帳號買無廣告版本,我就讓下次a帳號之後進來如果都是登入狀態的話不會有廣告,我試了幾次都是買了之後再同檯機器上,就算a帳號登出也一樣是無廣告的版本
    可以告訴我要怎麼存在帳號上嗎??謝謝

    回覆刪除
  4. 請教popcorny , 商品處於Ready to Submit狀態是否就可以在app內測試了? 感謝您的分享

    回覆刪除