Google Play Billing 迁移 AI 提示词
概述
此 AI 提示词驱动大语言模型(如 ChatGPT、Claude 或 Gemini)将您的 Google Play Billing 代码迁移到 Aptoide Android Billing SDK。将其与您现有的集成一起粘贴,AI 便会充当迁移工程师,设置构建风味(Build Flavors),并使用 Aptoide 特定的 API 镜像您当前的架构模式。
AI 提示词
## PROMPT: Adaptive Mirror-Integration of Aptoide Billing SDK
## Goal
Integrate the Aptoide Billing SDK into this Android project by strictly mirroring the existing Google Play Billing implementation. The objective is to have a "plug-and-play" version for Aptoide that follows the current project's coding patterns, naming conventions, and architecture, but uses the correct Aptoide-specific APIs.
## Reference Documentation
Use this for Aptoide-specific syntax: https://docs.connect.aptoide.com/docs/android-billing-sdk
## Step 1: Analysis of Current Implementation
1. Scan the project to identify how **Google Play Billing** is currently implemented.
2. Identify the key components:
* Where the Google `BillingClient` is initialized.
* Which wrapper classes (e.g., `BillingManager`, `BillingRepository`) handle the purchase flow, SKU/Product queries, and consumption.
* How the UI or ViewModels observe purchase updates (e.g., Listeners, LiveData, Flows).
* How Dependency Injection (if any) provides the Billing service.
## Step 2: Infrastructure Setup (Build Variants)
1. Define a `distribution` flavor dimension in the app-level `build.gradle` (or `build.gradle.kts`).
2. Create two flavors: `googlePlay` and `aptoide`.
3. Isolate dependencies:
* Move Google Billing dependencies to `googlePlayImplementation`.
* Add Aptoide Billing to `aptoideImplementation` using the `+` to always have the newest version of major available: `implementation("com.aptoide:android-aptoide-billing:1.+")`.
4. In a multi-modular project, add correctly the flavor dimensions to all the `build.gradle` files that use the Billing module.
## Step 3: Aptoide Public Key Configuration (CRITICAL)
1. In the root `gradle.properties` file, add a placeholder variable: `APTOIDE_PUBLIC_KEY="PASTE_YOUR_PUBLIC_KEY_HERE"`
2. In the app-level `build.gradle` `aptoide` flavor block, expose this to the app using `buildConfigField`:
* Groovy: `buildConfigField "String", "APTOIDE_PUBLIC_KEY", project.property('APTOIDE_PUBLIC_KEY')`
* Kotlin DSL: `buildConfigField("String", "APTOIDE_PUBLIC_KEY", project.property("APTOIDE_PUBLIC_KEY").toString())`
3. **Developer Note requirement:** In your final response to me, display a prominent warning reminding me to replace the placeholder in `gradle.properties` with the actual key from the Aptoide Console.
## Step 4: Mirror-Image Implementation (Source Sets)
1. **Source Set Separation:**
* Move the existing Google Billing wrapper logic/classes into `src/googlePlay/java` (or `kotlin`).
* Create identical class files and package structures in `src/aptoide/java` (or `kotlin`).
2. **Wrapper Class Parity:**
* Inside `src/aptoide/`, rewrite the billing wrapper logic using the Aptoide SDK. You MUST keep the **exact same wrapper class names, custom method signatures, and custom return types** as the Google version (e.g., if Google has `class MyBillingManager`, Aptoide must have `class MyBillingManager`).
3. **Aptoide SDK Specifics (DO NOT USE GOOGLE IMPORTS IN APTOIDE):**
* Use Aptoide imports: `com.aptoide.sdk.billing.*` (e.g., `AptoideBillingClient`, `Purchase`, `ProductDetails`, `BillingFlowParams`, `QueryProductDetailsParams`) and `com.aptoide.sdk.billing.listeners.*` for the listeners (e.g., `AptoideBillingClientStateListener`, `ConsumeResponseListener`). Here is a list of all the available classes, annotations and listeners in Aptoide Billing SDK:
- com.aptoide.sdk.billing.AptoideBillingClient.BillingResponseCode
- com.aptoide.sdk.billing.AptoideBillingClient.FeatureType
- com.aptoide.sdk.billing.AptoideBillingClient.ProductType
- com.aptoide.sdk.billing.UnfetchedProduct.StatusCode
- com.aptoide.sdk.billing.AccountIdentifiers
- com.aptoide.sdk.billing.AptoideBillingClient
- com.aptoide.sdk.billing.BillingFlowParams
- com.aptoide.sdk.billing.BillingFlowParams.Builder
- com.aptoide.sdk.billing.BillingFlowParams.ProductDetailsParams
- com.aptoide.sdk.billing.BillingFlowParams.ProductDetailsParams.Builder
- com.aptoide.sdk.billing.BillingResult
- com.aptoide.sdk.billing.ConsumeParams
- com.aptoide.sdk.billing.ConsumeParams.Builder
- com.aptoide.sdk.billing.ProductDetails
- com.aptoide.sdk.billing.ProductDetails.OneTimePurchaseOfferDetails
- com.aptoide.sdk.billing.ProductDetails.PricingPhase
- com.aptoide.sdk.billing.ProductDetails.PricingPhases
- com.aptoide.sdk.billing.ProductDetails.SubscriptionOfferDetails
- com.aptoide.sdk.billing.ProductDetails.TrialDetails
- com.aptoide.sdk.billing.Purchase
- com.aptoide.sdk.billing.QueryProductDetailsParams
- com.aptoide.sdk.billing.QueryProductDetailsParams.Builder
- com.aptoide.sdk.billing.QueryProductDetailsParams.Product
- com.aptoide.sdk.billing.QueryProductDetailsParams.Product.Builder
- com.aptoide.sdk.billing.QueryProductDetailsResult
- com.aptoide.sdk.billing.QueryPurchasesParams
- com.aptoide.sdk.billing.QueryPurchasesParams.Builder
- com.aptoide.sdk.billing.ReferralDeeplink
- com.aptoide.sdk.billing.UnfetchedProduct
- com.aptoide.sdk.billing.listeners.AptoideBillingClientStateListener
- com.aptoide.sdk.billing.listeners.ConsumeResponseListener
- com.aptoide.sdk.billing.ProductDetailsResponseListener
- com.aptoide.sdk.billing.PurchasesResponseListener
- com.aptoide.sdk.billing.PurchasesUpdatedListener
* **Initialization:** You MUST replace `BillingClient` with `AptoideBillingClient`. It requires the Public Key in the Builder. Use exactly this pattern:
```kotlin
val billingClient = AptoideBillingClient.newBuilder(context)
.setListener(purchasesUpdatedListener)
.setPublicKey(BuildConfig.APTOIDE_PUBLIC_KEY)
.build()
```
* Use `AptoideBillingClientStateListener` for the `startConnection` method.
## Step 5: Semantic Feature Mapping (SDK Differences)
Identify and bridge the functional gaps between the two SDKs to maintain signature parity:
1. **Threading differences (CRITICAL):** The Aptoide `launchBillingFlow()` method **MUST NOT** be called on the Main/UI Thread (this will cause a crash). Wrap the `launchBillingFlow()` call inside a background thread (e.g., Coroutines `Dispatchers.IO` or an RxJava background scheduler) in the Aptoide implementation.
2. **Acknowledge vs Consume:** Aptoide does not support a separate `acknowledgePurchase` step like Google does for subscriptions/non-consumables. If the Google implementation has an `acknowledge()` method, implement it as a "No-Op" (returning success immediately) in the Aptoide flavor, and ensure all purchases are finalized using Aptoide's `consumeAsync` function instead.
3. **Product Types:** Map Google’s `ProductType.SUBS` and `ProductType.INAPP` to `AptoideBillingClient.ProductType.SUBS` and `AptoideBillingClient.ProductType.INAPP`.
4. **General Logic:** Verify all other functional differences and apply the Aptoide SDK logic correctly while maintaining the original custom wrapper method signatures so the UI doesn't break.
## Step 6: Verification & Cleanliness
* The `src/main` folder should remain completely untouched.
* The UI and ViewModels should not know which SDK is being used; they should simply call the wrapper classes that now exist in both flavor source sets.
---
## PHASE 2: Validation Audit (Mandatory)
After completing the code generation, you must perform a self-audit and report on the following:
1. **Isolation Audit:** Confirm zero `com.aptoide.sdk.billing` imports exist in `src/main` or `src/googlePlay`. Conversely, confirm zero `com.android.billingclient.api` imports exist in `src/aptoide`.
2. **Threading Audit:** Explicitly verify that `AptoideBillingClient.launchBillingFlow()` is executed on a background thread.
3. **Builder Audit:** Explicitly verify that `AptoideBillingClient.newBuilder` uses `.setPublicKey(BuildConfig.APTOIDE_PUBLIC_KEY)`.
4. **Signature Check:** Confirm that the public API of your custom wrapper classes in `src/aptoide` is identical to the `src/googlePlay` version.
5. **Cleanliness Check:** Confirm that `src/main` (UI/ViewModels) remained untouched.
**Final Requirement:** If any discrepancies are found during your audit, fix them before providing the final code and report.
如何使用此提示词
虽然您可以将此提示词复制/粘贴到基于网页的 AI(如 ChatGPT 或 Claude)中,但通过使用能够直接访问您仓库上下文的 AI 驱动 IDE 或 Agent,您将获得最高的成功率。
推荐方法:AI 代码编辑器(Cursor / Android Studio 集成 AI)
使用 Cursor 或 Android Studio 内置的集成 AI Agent 之类的工具,可以让 AI 对您的整个代码库建立索引。这带来了以下几项优势:
- 上下文感知: AI 会自动找到您的
BillingClient初始化和build.gradle,您无需手动查找并粘贴这些文件。 - 自动创建文件: AI 可以为您创建新的源集(
src/aptoide/java)并移动文件。 - 直接生成 PR: 您可以要求 AI 将这些更改直接应用到一个新分支,然后您便可以将其作为标准的拉取请求(Pull Request)进行审查。
AI 集成后的检查
虽然 AI 可以显著加快迁移过程,但计费是一个关键系统。在提交生成的代码之前,您应执行以下手动检查:
1. 占位符验证
AI 将为您的 Aptoide 公钥使用占位符。您必须在 build.gradle 或 BuildConfig 中手动将其替换为在您的 Aptoide 帐户中找到的实际密钥。否则将导致 SDK 在处理购买结果时失败,并返回 BillingResponseCode DEVELOPER_ERROR (5)。
2. 依赖版本
AI 模型可能并不总是掌握 Aptoide SDK 的最新版本。请将 build.gradle 中的实现版本与我们的官方 Maven 仓库进行交叉核对,以确保您使用的是最新的稳定版本。
3. 消耗逻辑审查
Aptoide 使用 consume 调用来确定交易。请仔细审查 步骤 5 中 AI 生成的映射,特别是它如何处理"Acknowledge"调用。确保非消耗型商品和订阅按照您应用特定的权益逻辑进行处理。
4. 风味同步
请验证您的计费类中引用的所有资源(字符串、可绘制对象或布局)在 src/googlePlay 和 src/aptoide 两个源集中都存在,或者已被安全地移动到 src/main。如果某个风味中缺少资源,则仅在选择该特定变体时才会导致构建失败。
5. 最终沙盒测试
切勿假设 AI 生成的逻辑 100% 准确。代码集成后,请按照沙盒环境指南,在发布前执行完整的端到端测试。
使用示例
以下是一个如何在 Android Studio 内置 AI Agent 中使用此提示词的示例。