1. 程式人生 > >Google Play In-app Billing

Google Play In-app Billing

edit blank 通知 .py support develop androi 粗體 希望

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 v2

in-app-billing v3

參考推薦:

In-app Billing Overview(EOE wiki 百科)

In-app Billing Overview(android developer)

再分享一下我老師大神的人工智能教程吧。零基礎!通俗易懂!風趣幽默!還帶黃段子!希望你也加入到我們人工智能的隊伍中來!https://blog.csdn.net/jiangjunshow

Google Play In-app Billing