### 簡介與背景 ![messageImage_1743753008828](https://hackmd.io/_uploads/SJXSyMpaJg.jpg) ![image](https://hackmd.io/_uploads/SkZIkzaTkx.png) - Google Play Billing Library 是 Android 應用內購買的主要方式 - 不再單稱「in-app billing」,因為支援範圍更廣(例如 Google Assistant) - 將逐步淘汰舊有的 AIDL 方式 - Play Billing Library 將是未來唯一支援新功能的方式 --- ### 為什麼要淘汰 AIDL ![image](https://hackmd.io/_uploads/rJ4Dyzppke.png) ![image](https://hackmd.io/_uploads/rJ0ggGppyg.png) - AIDL 是基於服務綁定,開發者需自行處理連線與中斷 - 難以維護,易造成錯誤(如更新參數導致崩潰) - 無法主動得知新版本與功能更新 - 開發者需自行負責 UI 呼叫與錯誤處理,體驗不佳 --- ### 使用 Play Billing Library 的優勢 ![image](https://hackmd.io/_uploads/rk3FyM66ke.png) ![image](https://hackmd.io/_uploads/Syc9gGaa1x.png) - 內建超過 20 億次交易的驗證機制 - 提供封裝好的 API 和輔助類別,減少樣板程式碼 - 自動處理連線與錯誤重試機制 - 支援非同步回呼,改善購買流程與體驗 - 自動處理 UI 顯示與快取,減少開發負擔 --- ### Library 的實作特點與優化 ![image](https://hackmd.io/_uploads/BkmRez6TJx.png) - 提供錯誤碼、常數等系統級處理,開發者無需自行定義 - 自動解析 API 回傳資料,避免手動處理 Bundle 或 HashMap - 支援 API 演進,不需開發者重複修正參數名稱或格式 - 可搭配 Kotlin 更容易撰寫與維護 --- ### 新功能僅支援新版 Library - 例如「Purchase Anywhere」等功能僅支援新版 Billing Library - 舊版 AIDL 與 Billing Library v1 將無法使用新功能 - Google 不再更新 AIDL 版本,建議儘速遷移 --- ### 遷移建議與開發步驟 ![image](https://hackmd.io/_uploads/HkDy-Mapkl.png) ![image](https://hackmd.io/_uploads/HyGWWGaa1l.png) ![image](https://hackmd.io/_uploads/Sk-PWz6ayl.png) - 在 `gradle` 中加入 Billing Library 依賴 - 檢查 Google 官方文件以瞭解各項操作 API - 移除原本 AIDL 相關類別與樣板程式碼 - 建立 BillingClient 實例,實作回呼介面 BillingClientStateListener - 使用 `startConnection` 建立連線,不需自行綁定服務 --- ### 購買流程與狀態監聽 - 不需再使用 `onActivityResult` 處理結果 - 可使用 Listener 接收完成事件通知,簡化流程管理 - Billing Library 自動處理購買結果與訂閱狀態變更 --- ### 政策與期限提醒 - 自 2021 年 5 月 1 日起,Google Play 不再接受使用 AIDL 或 Billing Library v1 的新 App 或更新版本 - 建議立即規劃並開始遷移,避免影響上架與功能開發 --- ### 舊版 AIDL vs 新版 Billing Library 的程式碼差異 ![image](https://hackmd.io/_uploads/Bk5PZzpp1x.png) ![image](https://hackmd.io/_uploads/HkSt-zaa1x.png) ![image](https://hackmd.io/_uploads/Sk7hbfTT1g.png) ![image](https://hackmd.io/_uploads/ByD6-fp6ke.png) ![image](https://hackmd.io/_uploads/HkfkMfTTkx.png) ![image](https://hackmd.io/_uploads/BJTyGz66Jx.png) - AIDL 需自行處理 Service 連線與中斷,容易出錯(如 Intent 名稱拼寫錯誤) - Billing Library 使用 Builder 模式建立 `BillingClient` - 不需處理權限、Service 綁定、Retry 機制等 - 建立連線後可直接查詢商品資訊 - 購買流程簡化,使用 PurchaseParams + `launchBillingFlow()` 即可 - 購買結果透過 Listener 接收回傳,不再使用 `onActivityResult` --- ### 實作注意事項與檢查清單 ![image](https://hackmd.io/_uploads/SJr4MMpTyg.png) - 所有購買必須在三天內「確認(acknowledge)」以避免自動退款 - 消耗型商品(如遊戲幣)需在再次販售前先執行 consume - 非消耗型商品(如訂閱、付費解鎖)需明確執行 acknowledge - 建議使用 Server 驗證購買憑證以防止濫用 - 不建議使用 Developer Payload 作為安全機制,容易被攔截 - 可選擇性使用 Developer Payload,但應搭配其他安全驗證機制 --- ### 即時開發者通知(Real-time Developer Notification) ![image](https://hackmd.io/_uploads/ryEiMfp6Jl.png) - 可即時接收訂閱相關事件(取消、升級、帳號暫停、寬限期等) - 避免不斷查詢 Google Play API,降低 API 配額耗盡風險 - 採用 Google Cloud Pub/Sub 推送機制,免費額度足夠使用 - Server 端接收通知後解析訊息,取得購買憑證與訂閱資訊 --- ### 通知流程與處理機制 ![image](https://hackmd.io/_uploads/ry40Gfa6yl.png) ![image](https://hackmd.io/_uploads/Hk0JmzTaJx.png) - 當訂閱狀態改變,Play Store 發出 Pub/Sub 訊息 - Server 透過 Cloud Pub/Sub 訂閱特定主題接收通知 - 通知內容包含 purchase token、package name 與商品 ID - 根據接收內容可直接辨識用戶行為並更新資料,無需額外 API 請求 --- ### 未來發展與平台支援 ![image](https://hackmd.io/_uploads/r1CXmfTTye.png) - 正在開發 C++、Unity、Unreal Engine 的支援版本 - 適用於需要原生支援的遊戲引擎平台 - 可聯繫開發者關係團隊參與測試與回饋 --- ### 其他補充資源 ![image](https://hackmd.io/_uploads/H1CEQGppkx.png) ![image](https://hackmd.io/_uploads/rkaB7zpTJe.png) - Play Pass 提供固定價格訂閱多款遊戲與應用,適合推廣新產品 - 官方網站提供完整文件與程式碼範例(含即時通知與 server-side 實作) - 可參考「Trivial Drive Kotlin 版本」作為學習樣板 - 開發者可在 GitHub 上提供回饋與回報問題 --- # Terminology - **開發者倡導者(Developer Advocate)**:負責與開發者社群溝通並推廣技術產品的角色。 - **Google Play Billing Library**:Google 提供的客戶端函式庫,用來在 Android 應用內實作付款與訂閱功能。 - **AIDL(Android Interface Definition Language)**:Android 用來定義跨進程通訊介面的語言。 - **應用內結帳(In-app Billing)**:讓用戶在應用程式中購買數位商品或訂閱的功能。 - **購買流程(Purchase Flow)**:從商品顯示到完成付款的使用者操作流程。 - **消費型商品(Consumable Product)**:一次性使用、可重複購買的虛擬商品。 - **非消費型商品(Non-consumable Product)**:永久生效、只購買一次的虛擬商品。 - **訂閱(Subscription)**:用戶定期付款以持續存取內容或服務。 - **Play 商店 UI(Play Store UI)**:Google Play 提供的原生付款介面。 - **用戶體驗(User Experience, UX)**:使用者在操作應用程式時的整體感受。 - **客戶端函式庫(Client Library)**:用來簡化開發者整合 API 的工具套件。 - **服務綁定(Service Binding)**:將應用程式連接至系統服務以進行溝通的程序。 - **重試機制(Retry Mechanism)**:當連線失敗時自動再次嘗試連線的邏輯。 - **版本檢查(Version Check)**:確認使用的函式庫是否為最新版本。 - **常數定義(Constant Definition)**:定義不變的值來避免硬編碼錯誤。 - **錯誤碼(Error Code)**:用於判斷操作結果的代碼值。 - **Bundle 解析(Bundle Parsing)**:解析從 Play Store 傳回的資料包內容。 - **API 演進(API Evolution)**:API 隨版本更新新增或修改功能的過程。 - **非同步回呼(Asynchronous Callback)**:當操作完成時通知應用的程式設計方式。 - **事件監聽器(Listener)**:接收特定事件(如購買完成)的介面。 - **活動結果處理(onActivityResult)**:傳統方式接收其他活動返回資料的方法。 - **主線程(Main Thread)**:Android 中負責 UI 更新的主要執行緒。 - **背景執行緒(Background Thread)**:非主線程,用來執行耗時操作。 - **Gradle 整合(Gradle Integration)**:透過 Gradle 設定專案依賴的方式。 - **購買歷史(Purchase History)**:用戶過去已購買的商品清單。 - **錯誤處理(Error Handling)**:在程式出錯時採取的對應動作。 - **偵錯工具(Debugging Tool)**:協助開發者找出與修復錯誤的工具。 - **快取管理(Cache Management)**:暫存資料以提升效能的策略。 - **資料一致性(Data Consistency)**:確保本地資料與伺服器同步的狀態。 - **API 解析器(API Parser)**:協助解析與包裝 API 回傳資料的元件。 - **事件生命週期(Lifecycle Events)**:應用中各組件的啟動與銷毀過程。 - **非同步操作(Asynchronous Operation)**:不阻塞主線程的操作方式。 - **程式碼重構(Refactoring)**:改善現有程式碼結構但不改變功能的行為。 - **購買通知(Purchase Notification)**:從 Play Billing 傳送的購買狀態通知。 - **用戶狀態(User State)**:用戶目前訂閱、購買的資訊狀態。 - **兼容性(Compatibility)**:系統或元件能否與其他版本正常運作的能力。 - **事件排程(Event Scheduling)**:在特定時間點觸發事件的邏輯。 - **資料封裝(Data Encapsulation)**:隱藏資料實作細節僅提供存取介面。 - **購買成功(Purchase Success)**:交易順利完成且已交付商品的狀態。 - **交易處理(Transaction Handling)**:處理交易驗證、交付、紀錄等程序。 - **授權(Authorization)**:確認用戶是否有權進行某項操作的程序。 - **登入狀態(Login Status)**:用戶是否登入的檢查機制。 - **伺服器同步(Server Synchronization)**:與伺服器保持資料同步的機制。 - **資料綁定(Data Binding)**:將 UI 元素與資料模型直接連結。 - **彈性更新(Flexible Update)**:允許應用在不中斷使用情況下進行更新。 - **Kotlin 支援(Kotlin Support)**:Billing Library 提供對 Kotlin 的良好整合。 - **遷移指南(Migration Guide)**:從舊版系統轉換至新版所需步驟的說明。 - **範例程式碼(Sample Code)**:供開發者參考的實作範例。 - **遺留代碼(Legacy Code)**:舊有但仍在使用的程式碼基礎。 - **購買驗證(Purchase Verification)**:確認購買請求是否真實有效的過程。 - **應用更新限制(App Update Restriction)**:不符合條件的應用不得更新上架的政策。 - **Builder 模式(Builder Pattern)**:一種創建物件的設計模式,能逐步設置屬性並建構最終物件。 - **BillingClient**:Google Play Billing Library 的核心類別,用來管理與 Play 的連線及付款操作。 - **startConnection()**:啟動與 Google Play Billing 的連線流程的方法。 - **onBillingSetupFinished()**:在 BillingClient 成功連線後觸發的回呼函數。 - **querySkuDetailsAsync()**:非同步查詢商品(SKU)詳細資料的方法。 - **PurchaseParams**:設定購買請求參數的資料結構。 - **launchBillingFlow()**:啟動付款流程的函數,觸發 Play Store 的付款 UI。 - **onPurchasesUpdated()**:當購買結果回傳時觸發的回呼函數。 - **BillingResult**:表示購買或查詢等操作結果的物件。 - **Purchase**:包含用戶購買資料的物件。 - **handlePurchase()**:處理用戶完成購買後應用內邏輯的方法。 - **requestCode**:用於識別回傳結果對應的請求代碼。 - **intent data**:從另一個 Activity 返回時傳遞的資料。 - **acknowledgePurchase()**:確認使用者購買行為的方法,避免退款。 - **消費商品(Consumable Product)**:可重複購買且使用後會消耗的虛擬商品。 - **非消費商品(Non-Consumable Product)**:一次購買即可永久使用的商品。 - **consumeAsync()**:消耗商品的方法,讓相同商品能再次購買。 - **伺服器端驗證(Server-side Verification)**:在後端伺服器驗證購買資料以防止詐騙的流程。 - **developerPayload**:開發者自訂的資料字串,用來傳遞附加資訊。 - **中間人攻擊(Man-in-the-middle Attack)**:攔截用戶資料或通訊內容的安全威脅。 - **Realtime Developer Notification(RTDN)**:即時推送訂閱事件通知至開發者伺服器的機制。 - **取消訂閱(Subscription Cancelation)**:用戶主動或因付款失敗終止訂閱。 - **升級訂閱(Subscription Upgrade)**:用戶轉移至更高價位的訂閱方案。 - **帳戶暫停(Account Hold)**:因付款問題暫停使用的狀態。 - **寬限期(Grace Period)**:付款失敗後,系統暫不終止服務的過渡期。 - **Google Cloud Pub/Sub**:Google Cloud 提供的即時訊息推播服務。 - **訊息主題(Topic)**:Pub/Sub 中訊息分類與訂閱的識別單位。 - **購買憑證(Purchase Token)**:驗證與識別購買交易的唯一字串。 - **產品 ID(Product ID)**:用於識別商品的唯一代碼。 - **資料消費者(Message Consumer)**:負責接收與處理推送訊息的後端服務。 - **Quotas(配額)**:Google API 可使用的請求次數限制。 - **主動輪詢(Polling)**:定時向伺服器發出請求以取得最新資料的方式。 - **備援驗證(Redundant Verification)**:額外的驗證流程,以確保資料正確性與安全性。 - **Play Pass**:Google 推出的訂閱服務,提供多款應用與遊戲的無限使用權。 - **Trivial Drive Sample**:Google 官方提供的範例應用程式,用來示範 Billing 功能。 - **Kotlin 整合(Kotlin Integration)**:Billing Library 與 Kotlin 程式語言的兼容性。 - **Unity Plugin**:針對 Unity 開發者的 Billing 整合外掛。 - **Unreal Plugin**:針對 Unreal Engine 的 Google Play Billing 整合外掛。 - **Gradle 依賴(Gradle Dependency)**:透過 Gradle 設定與引入函式庫的方式。 - **錯誤代碼常數(Error Code Constant)**:用於比對錯誤狀態的定義代碼。 - **API 回應解析(API Response Parsing)**:解讀來自 API 回傳資料的流程。 - **回呼函數(Callback Function)**:特定事件發生後被系統自動觸發的函式。 - **服務重新連接(Service Reconnect)**:在失去連線後自動重新建立的流程。 - **使用者授權驗證(User Authorization Validation)**:確認使用者身分與權限的機制。 - **應用事件日誌(App Event Logging)**:記錄應用中發生的重要事件以供追蹤。 - **購買流程觸發(Purchase Flow Trigger)**:引導用戶進行付款的操作。 - **授權過期(Authorization Expired)**:原本有效的授權因超時而失效。 - **Play Billing V1 停用政策**:Google 宣布不再接受使用舊版 AIDL 或 V1 函式庫的應用。 - **回應碼處理(Response Code Handling)**:根據回傳代碼決定應採取的動作。 - **活動生命週期整合(Activity Lifecycle Integration)**:將 Billing 操作融入應用主流程的處理方式。 - **UI 快取(UI Caching)**:快取使用者界面資料以減少資料讀取次數。 - **應用重構(App Refactoring)**:對應用架構或程式碼進行優化與更新的過程。