Google Play In app Billing
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
0, 概述
應用程式內部付費機制(Google Play In-app Billing, 以下簡稱應用內支付)是Google Play的一項服務,這種服務為應用內購買提供支付流程。
要使用這項服務,你的應用會對一個特定的應用內產品傳送一個結賬請求。然後該服務會處理這筆交易的所有細節,包括請求和確認支付形式和處理金融方面的交易。支付流程完成後,該服務會發送購買細節到你的App,比如訂單號、訂單時間、價格。你的App無需理會金融方面的交易,這都由Google Play的應用內支付服務來提供。
1, 產品型別與購買方式
應用內支付支援不同種類的產品型別和購買型別,為你的App提供靈活的賺錢方式。在所有情況下,你都要使用Google Play開發者控制檯定義你的產品,包括產品型別、購買型別、庫存單位、價格、描述等等。想了解更多資訊,請看 管理應用內支付
產品型別
使用本服務你能賣兩種產品:應用內產品 和 訂閱
兩種產品的賬單特性完全不同,但是我們的API能讓你使用同樣的通訊模型、資料結構、使用者互動來處理他們,後面會講到。
- 應用內產品——使用者一次購買一個的東西。例如,典型是讓使用者購買數字內容,解鎖App功能,一次性充值,或者新增任何東西到使用者體驗。不像購買Apps,一旦使用者買了就沒有退款的視窗了。如果使用者想退款只有聯絡開發者。
- 該產品可以用兩種方式出售: “限定賬號”和“不限賬號”。該產品總是跟唯一的App耦合。也就是說,一個App不能購買另一個App裡面釋出的產品,即使由一個開發者開發。該類產品被所有的應用內支付服務支援。
- 訂閱(購買後有一定有效期)——這種物品使用開發者指定的、每隔一段時間就迴圈的賬單。當用戶購買一個subscription,Google Play和它的支付處理器自動為使用者生成一個賬單,包含指定的時限和價格,裝載這個數目到原始的支付方法。一旦使用者購買一個訂閱後,Google Play繼續無限期地為這個產品標價,不會請求使用者的確認。使用者能在任何時候取消這個訂閱。
- 只能使用“限定賬號”的方式。因為如果是買第一種產品,一旦使用者買了就不會退款。若想退款只有直接聯絡開發者。想看更多資訊以及如何銷售,請看 訂閱 文件。
購買方式
我們的應用內支付服務提供兩種購買方式:“限定賬號”和“不限賬號”
購買方式決定了Google Play如何來處理和跟蹤購買:
- 限定賬號——物品只能每次被一個Google Play賬號購買,當用戶選擇這種型別,Google Play 會為每個賬號的每次購買永久儲存交易資訊。這使你能夠查詢到Google Play裡面的購買資訊。如果使用者嘗試購買一個已經買過的產品,那麼系統會返回一個已經購買的錯誤報告。
- 如果你出售遊戲等級或者應用特性,這種方式就很有用。這些東西往往不是一個臨時行為,需要被儲存以便用處重新安裝你的App,刪除他裝置裡的資料,或者把你的App安裝到另一臺裝置。
- 不限賬號——物品的交易資訊是不儲存在Google Play中的。這意味著你無法從Google Play中查詢你的交易資訊,你必須自己負責管理交易資訊。同樣的,如果用這種方式,Google Play不會阻止使用者多次購買,貨物能購買多少次就交給你自己控制了。
- 這種方式很有用,如果你想出售一些類似消費品的東西,如燃料和魅力值。這些東西常常在你的應用裡面被消費掉,而且能多次購買。
2, 應用內支付架構
你的App使用裝置中Google Play App提供的API 來訪問應用內支付服務。Google Play App 使用非同步訊息迴圈來傳達賬單請求,並且在你的App和Google Play伺服器間執行響應。在實踐中,你的App絕不會直接與Google Play伺服器互動(見圖1)。相反,你的App使用IPC傳送結賬請求到Google Play App,然後取回購買響應,方式是非同步廣播。你的App自己不會去管與Google Play伺服器的網路連線或者使用其他特殊的API。
圖1:你的App通過Google Play App傳送和取回結賬訊息,後者負責與Google Play伺服器通訊。
Your App 《——》 Google Play App 《——》 Market Server
有些應用內支付實現會使用私有的伺服器來交付內容或確認交易,但是遠端伺服器不必實現應用內支付。如果你出售需要下載到使用者裝置的數字內容到媒體檔案,這種情況下私有伺服器會有用。你也可能使用遠端伺服器來儲存使用者交易歷史或執行各種確保支付安全的任務,比如簽名驗證。雖然你能夠在App裡面處理所有安全相關任務,但還是建議你放在遠端伺服器裡,因為這樣有助於你的App減少被攻擊的風險。
典型的應用內支付實現包含3個元件:
• 一個Service (在示例中被命名為BillingService),它處理從你的App傳送賬單請求到Google Play 應用內支付服務的購物訊息。
• 一個BroadcastReceiver (在示例中被命名為 BillingReceiver),他接收來自Google Play App的所有的賬單非同步響應。
• 一個安全元件 (在示例中被命名為Security),它執行安全相關的任務, 比如簽名驗證和隨機數生成。想了解應用內支付安全的更多資訊, 請看本文中後續的Security controls。
你可能同樣希望使用另外兩個支援支付的元件:
• 一個響應Handler (在示例中被命名為 ResponseHandler),他提供App指定的購物通知、報錯和其他狀態訊息的處理。
• 一個觀察者 (在示例中被命名為PurchaseObserver),它負責傳送回撥到你的App,以便你能使用購買資訊和狀態更新你的GUI。
除了這些元件,你的App必須實現儲存使用者資訊的方法,還有使用者的購買、選擇貨物的介面。你不必提供結賬的介面,當用戶初始化一個應用內購買,Google Play App會展示出結賬介面的。當用戶完成結賬流程,你的App會繼續執行。
3, 應用內支付訊息巨集定義
basic request-response messaging that takes place between your application and the Google Play application. 當用戶開始購買,你的App使用IPC函式呼叫傳送購物訊息到Google Play的應用內支付服務(MarketBillingService)。Google Play App同步響應所有支付請求,為你的App提供狀態通知等等資訊。Google Play App 也非同步響應一些賬單請求,為你的App提供出錯訊息和交易細節。下面的章節描述了你的App和Google Play App之間基本的請求/響應訊息。
請求巨集定義
你的App發出應用內支付請求,需要呼叫IPC函式 (sendBillingRequest()),這個函式由MarketBillingService介面提供。該介面定義於 Android Interface Definition Language 檔案(IMarketBillingService.aidl). 你能夠下載該AIDL檔案和應用內支付示例程式。
sendBillingRequest()函式只有一個Bundle引數。你傳送的Bundle必須包含一系列鍵值對來制定各種請求引數,比如賬單請求的型別、被購買的物品和它的型別, 還有傳送該請求的App。想了解更多的關於請求中的Bundle鍵的資訊,請見應用內支付Service介面。
Bundle中最重要的鍵之一是 BILLING_REQUEST 鍵,它讓你指定賬單請求的型別。Google Play應用內支付服務支援如下5種賬單請求:
• CHECK_BILLING_SUPPORTED
這個請求用來驗證Google Play App是否支援應用內支付。你常常得在App首次執行時候傳送這個請求。這個請求非常有用,因為你可以根據是否支援應用內支付來安排你下一步的UI。
• REQUEST_PURCHASE
傳送購買請求到Google Play,它也是應用內支付的基礎。 You send this request when a user indicates that he or she wants to purchase an item in your application.當用戶表示他想在你的App裡面購買一些東西的時候,你就傳送這個請求。 Google Play通過顯示結賬GUI來響應這個請求。
• GET_PURCHASE_INFORMATION
取回購買狀態改變的資訊。使用者成功或失敗購物都會使購買狀態改變。退款也會觸發狀態改變。一旦購買狀態改變,Google Play會主動通知你,所以你有你想自己取回資訊的時候才傳送該請求。
• CONFIRM_NOTIFICATIONS
確認你的App收到了購買狀態改變的通知。Google Play會一直髮送狀態改變通知到你的App,直到你傳送這個確認。
• RESTORE_TRANSACTIONS
取回使用者的交易狀態,只針對限定賬號的購買 和 訂閱。僅僅在你想取回使用者交易狀態的時候才傳送該請求,這種情況往往發生於你的App被重新安裝或者首次安裝時。
響應巨集定義
Google Play App可以響應同步的或非同步的應用內支付請求,同步響應的 Bundle 包含如下的3個鍵:
• RESPONSE_CODE 提供請求的狀態、出錯資訊。
• PURCHASE_INTENT 提供 PendingIntent, 你使用它來生成一個結賬介面。
• REQUEST_ID 提供請求的身份識別,你用它來匹配請求與非同步響應。
這些鍵不是跟每個請求都相關的。 想了解更多,請看下文的訊息傳遞流程。
非同步響應訊息被以個別廣播的形式來發送,包括下面3個巨集:
• com.android.vending.billing.RESPONSE_CODE
該響應包括一個Google Play伺服器響應碼,它在你做出應用內支付請求後傳送。伺服器響應碼能顯示你的賬單請求已成功傳送到Google Play ,或者是請求出錯。該響應不會用來報告購買狀態的變更 (比如退款或購買資訊)。想了解更多的關於該響應的碼字資訊,請看 應用內支付的伺服器響應碼.
• com.android.vending.billing.IN_APP_NOTIFY
該響應表示購買狀態變更,也就是說購買成功、取消、退款。該響應包含一個或多個通知ID。每個通知ID跟一個指定的伺服器端訊息繫結, 每個訊息又包含了一個或多個交易。在你的App收到IN_APP_NOTIFY廣播後,你傳送一個 GET_PURCHASE_INFORMATION 請求,連同通知ID,去檢索訊息細節。
• com.android.vending.billing.PURCHASE_STATE_CHANGED
該響應包含一個或多個交易的細節資訊,交易資訊在一個JSON串中。該JSON串是已簽名的,而且簽名連同那個JSON串(未加密)傳送給你的App。為幫助確保你的應用內支付訊息的安全,你的App可以校驗JSON串的簽名。
該JSON串由叫做PURCHASE_STATE_CHANGED 的intent返回,它為你的App提供一個或多個賬單交易的細節。一個針對訂閱的JSON串示例如下:
{ "nonce" : 1836535032137741465,
"orders" :
[{ "notificationId" : "android.test.purchased",
"orderId" : "transactionId.android.test.purchased",
"packageName" : "com.example.dungeons",
"productId" : "android.test.purchased",
"developerPayload" : "bGoa+V7g/yqDXvKRqq+JTFn4uQZbPiQJo4pf9RzJ",
"purchaseTime" : 1290114783411,
"purchaseState" : 0,
"purchaseToken" : "rojeslcdyyiapnqcynkjyyjh" }]
}
想了解更多關於JSON串的域的資訊, 請看應用內支付廣播。
訊息傳遞流程
典型的訊息傳遞流程在圖2中顯示。每次sendBillingRequest()傳遞的請求型別都用粗體標示,廣播intents用斜體標示。為了講得明白,圖2沒有顯示為每次請求傳送的RESPONSE_CODE 廣播intents。
圖2.購物請求的訊息傳遞流程
基本的流程是如下的9步:
1. 你的App傳送一個購買請求(REQUEST_PURCHASE),指定一個產品ID和其他引數。
2. PURCHASE_INTENT 鍵提供一個 PendingIntent, 你的App利用它來為給定的產品ID生成一個結賬的UI。 Google Play App給你的App傳送一個Bundle,其中包含3個鍵:RESPONSE_CODE, PURCHASE_INTENT, REQUEST_ID
3. 你的App發起一個掛起intent,同時彈出一個埋單的UI。(注意:你必須從一個Activity context發起掛起intent,而不能是整個程式的context。)
4. 當結賬流程結束(使用者成功購買了貨物或者取消了購買),Google Play 會給你的App傳送一個通知訊息(IN_APP_NOTIFY 廣播)。這個通知訊息包括了指向該交易的通知ID。
5. 你的App通過傳送一個GET_PURCHASE_STATE_CHANGED來請求交易資訊,該請求指定了交易的通知ID。
6. Google Play App傳送一個 Bundle,攜帶兩個鍵:RESPONSE_CODE、REQUEST_ID。
7. Google Play 給你的App傳送交易資訊,該資訊儲存在PURCHASE_STATE_CHANGED 廣播 intent中。
8. 你的App通過傳送一個確認訊息(CONFIRM_NOTIFICATIONS)來確認你接收到了給定通知ID的交易資訊,該訊息指定了你接收到交易資訊對應的通知ID
9. Google Play App給你的App傳送一個Bundle,裡面包含RESPONSE_CODE鍵和 REQUEST_ID鍵。
記住,當你從Google Play 接收到交易資訊(圖2第8步),你必須傳送一個確認。否則,Google Play會繼續傳送IN_APP_NOTIFY訊息因為你沒有確認。作為最佳實踐,對一個貨物,直到你交付客戶之前你都不應傳送CONFIRM_NOTIFICATIONS請求。這樣可以保證:一旦你的應用崩潰或者其他原因無法發貨,你的App仍然會接收來自Google Play的IN_APP_NOTIFY廣播,表示你需要發貨。同樣的,作為最佳實踐,你的App必須能夠處理包含多重訂單的IN_APP_NOTIFY 訊息。
圖3顯示的是,修復交易請求的訊息流程。對每個 sendBillingRequest()方法的請求型別都用粗體標示, 廣播用斜體. 為了簡明,圖3沒有顯示發給每個請求的RESPONSE_CODE 廣播。
圖3. 修復交易請求的訊息流程
該請求觸發了三個響應:
第一個響應是一個Bundle ,它攜帶一個RESPONSE_CODE鍵和一個REQUEST_ID 鍵。
第二個響應是Google Play App傳送一個 RESPONSE_CODE 廣播,它提供請求的狀態資訊和錯誤資訊。RESPONSE_CODE訊息總是指向一個特定的請求ID,所以你能決定RESPONSE_CODE訊息適合哪個請求。
第三個響應是RESTORE_TRANSACTIONS請求,也會觸發一個PURCHASE_STATE_CHANGED廣播,此廣播包含在一個購買請求內傳送的同類交易資訊。然而,不像購買請求一樣,該交易不會同通知ID一起交給你。
所以你不必使用CONFIRM_NOTIFICATIONS訊息響應這個intent。
注意:只有當你的App首次安裝或者解除安裝後再次安裝,你才應當使用RESTORE_TRANSACTIONS 請求型別。
圖4顯示了檢查系統是否支援應用內支付的訊息流程。sendBillingRequest()函式的請求型別用粗體顯示。
圖4. 檢查系統是否支援應用內支付的訊息流程
對CHECK_BILLING_SUPPORTED請求的同步響應提供了一個攜帶伺服器響應碼的Bundle。
1) RESULT_OK 響應碼錶明應用內支付被支援;
2) RESULT_BILLING_UNAVAILABLE 響應碼錶明 應用內支付不被支援,因為你指定的API 版本不可識別,或者使用者無法合法地進行應用內購買(比如說,使用者位於一個無法使用應用內支付的國家).
3) SERVER_ERROR也可能被返回,表明Google Play伺服器有問題。
處理 IN_APP_NOTIFY 訊息
通常,你的App接到一個來自Google Play的 IN_APP_NOTIFY廣播,作為 REQUEST_PURCHASE訊息的響應 (請看圖2). IN_APP_NOTIFY廣播通知你的App請求購買的狀態改變了。要檢索購買細節的話,你的App要傳送 GET_PURCHASE_INFORMATION 請求。Google Play用PURCHASE_STATE_CHANGED廣播來響應, 該廣播包含了購買狀態變更的資訊。然後你的App傳送給一個 CONFIRM_NOTIFICATIONS訊息,通知 Google Play你收到了購買狀態變更的資訊。
Your App ——》 REQUEST_PURCHASE(You) ——》 IN_APP_NOTIFY(Play) ——》 GET_PURCHASE_INFORMATION(You)——》PURCHASE_STATE_CHANGED(Play) ——》 CONFIRM_NOTIFICATIONS(You)——》RESPONSE_CODE(Play)
在一些特殊情況下,你會收到多條IN_APP_NOTIFY訊息,即使你確認接收到了購買資訊;或者你會收到IN_APP_NOTIFY資訊說購買狀態改變了,但你從來沒有發起過購買。這兩種特殊情況你的App都必須能夠處理。
處理多次 IN_APP_NOTIFY 訊息
當Google Play接到對應於PURCHASE_STATE_CHANGED 的CONFIRM_NOTIFICATIONS訊息,它通常會停止傳送針對該 PURCHASE_STATE_CHANGED 訊息的IN_APP_NOTIFY intents。 然而,有時候 Google Play會發送重複的IN_APP_NOTIFY intents 雖然你的App已經發送 CONFIRM_NOTIFICATIONS。當你傳送CONFIRM_NOTIFICATIONS時裝置丟失網路連線,這就可能發生。 此時Google Play可能不會接到 CONFIRM_NOTIFICATIONS 所以它會發送多個IN_APP_NOTIFY 直到它受到你的確認。所以你的App必須能夠識別後來的IN_APP_NOTIFY 訊息是對應以往處理的哪個交易。你能夠通過檢查JSON串中的orderID來做到這一點,因為每個交易有唯一的一個orderId。
處理退款和其他未請求便傳送的 IN_APP_NOTIFY 訊息
兩種情況下你的App會收到IN_APP_NOTIFY廣播,即使你的App沒有傳送REQUEST_PURCHASE。圖5 顯示了這兩種情況的訊息傳遞流程。每個 sendBillingRequest()函式的請求型別用粗體顯示,廣播用斜體顯示。為了清晰,圖5 沒有畫出針對每次請求的RESPONSE_CODE廣播。
圖5. 處理退款和其他未請求便傳送IN_APP_NOTIFY訊息的流程
第一種情況,你的App可能收到IN_APP_NOTIFY, 當用戶把你的App安裝到多臺裝置中,然後使用者從其中一臺發起應用內購買。
此時Google Play傳送一個IN_APP_NOTIFY 訊息到第二臺裝置, 通知App購買狀態發生了改變。你的App要能處理這條資訊,就像它處理來自應用初始化的REQUEST_PURCHASE訊息響應一樣, 以便你的App最終接收到 PURCHASE_STATE_CHANGED 廣播intent訊息,該訊息包括了被購買商品的資訊。 這隻適用於 購買資訊 被設定為“限定賬號”的商品。
第二種情況,你的App會收到IN_APP_NOTIFY廣播,當Google Play接到一個來自Google Wallet的退款通知。
此時Google Play 傳送一個IN_APP_NOTIFY到你的App。你的App就像它處理來自應用初始化的REQUEST_PURCHASE訊息響應一樣處理這個訊息,最終使得你的App能收到PURCHASE_STATE_CHANGED訊息,包含被退款的商品資訊。
退款資訊在JSON串中,該串與PURCHASE_STATE_CHANGED廣播是一起的。同樣的 JSON串中的purchaseState 域被置為2
重要提醒:你不能使用Google Wallet API來發出退款或者取消應用內支付交易。你必須通過你的Google Wallet商業賬號手工操作。但你可以使用Google Wallet API取回訂單資訊。
4, 安全控制
為幫助確保傳送給你的交易資訊的完整性,Google Play 對JSON字串進行了簽名,它位於PURCHASE_STATE_CHANGED廣播intent中。Google Play 使用私鑰來關聯你的釋出賬號來建立這個簽名。釋出者站點生成一個RSA key來匹配每個釋出賬號。在你的賬號概覽頁面,你可以找到這個金鑰對的公鑰部分。他跟Google Play許可證使用的公鑰一樣。
當Google Play對一個賬單響應做簽名,它包括未加密的JSON串和一個簽名。當你的App接到這個簽名過的響應後,你可使用你的RSA key的公鑰部分來校驗該簽名。通過執行簽名驗證你能夠檢測到被篡改的或被欺騙的響應。你能在App裡執行這個簽名校驗步驟。然而,如果你的App連線到一個安全的遠端伺服器,我們建議你在伺服器上完成校驗步驟。
應用內支付也使用nonce(一次性隨機數)來幫助驗證Google Play返回的購買資訊的完整性。你的App必須生成一個隨機數然後用GET_PURCHASE_INFORMATION和 RESTORE_TRANSACTIONS請求跟它一起傳送。當Google Play 接收到請求,它把隨機數加入包含交易資訊的JSON串,然後對這個JSON串簽名並返回給你的App。當你的App收到此JSON串後你必須校驗它的隨機數和簽名。
如果想了解更多最佳安全設計的實踐,請看 安全與設計
5, 應用內支付的要求和限制
在你開始應用內支付之前,確保你知悉如下要求和限制:
• 應用內支付只能在Google Play釋出的App中使用。
• 想使用Google Play應用內支付,你必須擁有一個Google錢包商業版賬號。
• 應用內支付需要2.3.4或更高版本的Android Market App. 想用“訂閱”的話,需要3.5或更高版本的Google Play App。 在Android 3.0平板上, 需要安裝5.0.12或更高版本的MyApps。
• 執行Android 1.6 (API level 4)或更高版本的裝置才能使用應用內支付。
• 使用應用內支付可以賣數字內容,應用內支付不可出售實物、個人服務或者其他任何需要實物交付的東西。
• Google Play 不提供任何形式的內容交付,這由你自己負責。
• 在一個不聯網的裝置裡無法使用應用內支付。為完成購買請求,使用者必須能夠連線上Google Play 伺服器。
要了解更多應用內支付的要求,請看 應用內支付可用性與政策
6, 示例程式碼
官方示例與下載 :
In-app Billing Version 2(Dungeons)
In-app Billing Version 3(TrivialDrive)
或 打包下載
示例程式碼教程:
參考推薦:
In-app Billing Overview(EOE wiki 百科)
In-app Billing Overview(android developer)