以下文章極大部份翻譯自官方文件,我也是 IAB 的初學者,所以如果有錯誤歡迎指正。
關於 In-app Billing API
應 用程式(App)使用 API 透過裝置中內建的 Google Play app 來存取 In-app Billing 服務,Google Play app 會在你的 App 及 Google Play server 間傳送計費的請求及回應,你的 App 不會直接和 Google Play server 溝通,相反的,你的 App 是透過 IPC(Interprocess communication) 傳送付費的請求給 Google Play app 然後接收從 Google Play app 傳回的結果。你的 App 不用管理任何網路連線的事。In-app Billing 只能在透過 Google Play 發佈的應用程式上執行。要完成 App 內付款的流程,Google Play app 必須能透過網路存取 Google Play server。
目前 Google Play 支援兩個版本的 In-app Billing API,V3及V2。
Version 3 (官方建議使用):
- 使用較容易的方式從 Google Play 取得產品資料。
- 訂購資訊在購買完成時同步傳送到裝置上。
- 所有的購買行為是受管理的,意即 Google Play 持續追蹤使用者的內購商品擁有權。使用者不能擁有多個內購商品的副本,在任何時間點只能有一個商品。
- 購買的商品可以是消耗品,當用完時,該商品會被顯示為 "unowned" 狀態,這時候可以透過 Google Play 再次購買。
- 購買請求是透過單一 API 介面(sendBillingRequest)。
- Google Play 的回應是非同步的,以廣播意圖的形式回應。
- 沒有可消耗品的商品型式,必須自行處理。
- 支援訂閱式及不受管理的內購商品,及受管理的內購商品。
內購商品 (In-app Products)
在 App 中的內購商品為數位商品,透過 App 賣給使用者,像是遊戲幣、應用程式的升級或解除功能限制及新的內容等等。你只能使用 In-app Billing 販賣數位內容,不能賣實體商品、實體服務或任何需寄送才能取得的商品。不像付費型 App ,使用者可以在購買後的"試用時間"內由使用者自己取消購買;當使用者付費購買內購商品時,是沒有退款的機制讓使用者自己取消購買(但可寫信給開發者,由 開發者決定是否取消該次付款)。Google Play 沒有提供任何形式的遞送內容的機制,開發者必須自行傳遞數位商品給購買的使用者。內購式商品永遠明確的只和一款 App 產生關聯,也就是說,一個 App 不能購買由另一個 App 所發佈的內購式商品,即使是由同一個開發者所販賣的。
商品類型
開發者可以在 Google Play Developer Console (開發者控制台)中定義要販售的商品。類型有:
- managed in-app products:託管式商品。
- subscriptions:訂閱的內容。
- unmanaged in-app products:非託管式商品。
Google Play 購物流程
對使用者來說,買 App 的購物流程和買內購式商品的流程是一樣的。開發者必須有成為 Google Checkout Merchant (Checkout商家)才能使用 In-app Billing 的服務。當使用者開始購買一項商品,你的 App 會送出一個指定商品的付款請求,接著 Google Play 會控管整個交易的結帳細節,包含請求及驗證付款格式並且處理金流。當結帳流程完成後,Google Play 會送出購買明細給你的 App ,像是訂單號碼、訂購日期和時間以及付款金額,你的 App 完全不用控制整個交易流程,全部交由 Google Play 處理。
重要:官方強烈建議開發者在應用程式發佈前,使用混淆器來混淆程式碼,這是基於安全考量。
In-app Billing Version 3 API
特點:- 同步式的購買流程
- 可追蹤消耗性商品
- 本地端暫存內購商品資料
內購式商品(Purchasing Items)購買流程:
(圖片來源:http://developer.android.com/google/play/billing/api.html#purchase)
1. App 送出 isBillingSupported 的請求,向 Google Play 確認目前這個 In-app Billing API 版本是否支援付款。
2. 當 App 被啟動或使用者登入,就是檢查使用者擁有哪些購買項目的時候。要查詢使用者購買過哪些內購式商品,可以送出 getPurchases 請求。如果請求成功,會回傳一個 Bundle,包含已購買商品的ID清單、個人的購買明細清單及為購買簽名的清單。
3. 通常來說,開發者會想要告知使用者有哪些商品可以購買,要查詢開發者在 Google Play 定義的可內購式商品的細節,App 可以送出 getSkuDetails 的請求,開發者必須在查詢請求中指定產品ID清單。查詢成功則回傳一個 Bundle,包含相關的產品細節,像是價格、標題、說明及購買類型。
4. 假如某個內購式商品尚未屬於使用者,開發者就可以對使用者顯示購買提示(例如購買按鈕),當使用者按下按鈕送出購買請求,App 就會送出 getBuyIntent ,指定該項商品的ID及其他參數來購買。開發者應該在"開發者控制台"建立一個新的內購式商品時記下商品ID。
- Google Play 回傳一個 Bundle 內含一個 PendingIntent 可以讓使用者開始付款結帳的界面。
- App 會呼叫 startIntentSenderForResult 來啟動這個 PendingIntent。
- 當 這個結帳流程結束(指使用者購買成功或取消購買),Google Play 會回傳一個 Intent 到 App 的 onActivityResult 方法,結果碼(result code)會表示這次的購買是成功的或被取消,在回傳的 Intent 中包含了購買商品的資訊,有一個由 Google Play 產生的 purchaseToken 字串,可用來識別這次的交易。
消耗性商品購買流程:
(圖片來源:http://developer.android.com/google/play/billing/api.html#consume)
在 Version 3 裡,內購式商品都是被託管的,也就是說,所有的內購商品的所有權都是受 Google Play 管理,App 可以在需要的時候查詢使用者的購物資訊。當使用成功購買一項商品時,購買記錄會被儲存在 Google Play,當一項商品被購買後,它就會成為"被擁有(owned)"狀態,當處於"被擁有"狀態時,不能再度在 Google Play 中重覆購買。必須對被使用者擁有的商品送出消除的請求,才能再度在 Google Play 中購買該項商品,消除該商品會讓狀態恢復到"未被擁有"的狀態,前一次的購物資料將被丟棄。
要讓使用者重新取回商品的擁有權,可以讓 App 對 Google Play 呼叫 getPurchases。App 可以透過呼叫 consumePurchase 送出一個消除的請求,在請求的參數中,必須指定一個唯一的 purchaseToken 字串,這個字串是當初在 Google Play 完成購買時所給予的,然後 Google Play 會回傳狀態碼說明是否消除成功。
開發者要決定內購式商品為消耗性或非消耗性,兩者的說明:
- Non-consumable Items(非消耗性商品):只能在 App 中購買一次,並且提供永久的使用,該商品會和 Google 帳號相關聯。
- Consumable Items(可消耗性商品):能在 App 中在該商品用完時再次購買,例如遊戲中的藥水。
在應用程式中管理消耗性商品的基本流程如下:
- 呼叫 getBuyIntent 來啟動付款。
- 從 Google Play 取得 Bundle ,說明付款是否成功。
- 假如成功,呼叫 consumePurchase 來消費這次的購買。
- 從 Google Play 取得回傳碼,說明消費是否順利完成。
- 假如成功,就在 App 中提供該項商品。
- 送出 getPurchases 查詢使用者擁有的商品。
- 如果有任何可消費的商品,呼叫 consumePurchase 來消費該商品,這步驟是必要的,因為 App 可能已完成購買某項商品的訂單,但是在 App 送出消費請求前中止或離線了。
- 從 Google Play 取得回應碼,說明消費是否成功。
- 假如成功,就在 App 中提供該商品。
本地快取
因 為 Google Play 客戶端現在會快取內購資訊在本地裝置上,所以開發者可以使用 Version 3 API 頻繁的查詢購買資訊,例如,呼叫 getPurchases 。不像前一個版本的 API ,很多 Version 3 API 的呼叫會透過在快取中查找替代透過網路連線到 Google Play 的方式,這很明顯的提升的 API 的回應速度。總結整理
- 如果是第一次使用IAB,就使用V3 API,比V2好用易上手。
- V3需透過Google Play app來傳送購買訊息,所以必須使用實機測試,除非模擬器上有Google Play app(即Play 商店)
- 瞭解您的商品屬於一次性購買或屬於消耗品,選擇正確的商品販賣類型。
參考資料:
Google Play In-app Billing