GooglePay: 一个基于 Google Play Billing Library 封装的 Android 支付库

GooglePay

GooglePay 是一个基于 Google Play Billing Library 封装的 Android 支付库,旨在简化 Google 支付的接入流程,提供统一的接口管理一次性购买和订阅服务。

English | 简体中文

接入指南

本文档提供了将 Google Pay 库集成到您的 Android 应用程序中的详细指南。

1. 添加依赖

在您的项目 build.gradle 文件中添加 JitPack 仓库和依赖项。

根目录 build.gradle:

gradle 复制代码
allprojects {
    repositories {
        ...
        maven { url 'https://jitpack.io' }
    }
}

App 模块 build.gradle:

gradle 复制代码
dependencies {
    implementation 'com.github.darryrzhong:GooglePay:8.1.0-1.1' // 请检查最新版本
}

2. 初始化

在您的 Application 类中初始化 GooglePayClient。此设置配置了结算客户端、调试模式和订阅设置。

示例 (GpApp.kt):

kotlin 复制代码
class GpApp : Application() {
    override fun onCreate() {
        super.onCreate()

        GooglePayClient.getInstance()
            .setDebug(true) // 启用日志
            .setSubscriptionMode(SubscriptionMode.SingleMode) // 或 MultiModal (多订阅模式)
            .setSubscription(true) // 启用订阅支持
            .setInterval(15) // 自动刷新间隔 (如果适用)
            .registerActivitys(arrayListOf(MainActivity::class.java)) // 注册主要 Activity
            .initBillingClient(this, GooglePayServiceImpl.instance) // 使用上下文和服务实现进行初始化
    }
}

3. 实现 GooglePayService

您必须实现 GooglePayService 接口以提供商品 ID 并处理购买验证逻辑。

示例 (GooglePayServiceImpl.kt):

kotlin 复制代码
class GooglePayServiceImpl private constructor() : GooglePayService {

    companion object {
        val instance by lazy { GooglePayServiceImpl() }
    }

    // 返回在 Google Play Console 中配置的一次性消耗型商品 ID 列表
    override suspend fun getOneTimeConsumableProducts(): List<String> =
        suspendCancellableCoroutine { continuation ->
            val productList = listOf(
                "com.example.product.1",
                "com.example.product.2"
            )
            continuation.resume(productList)
        }

    // 返回一次性非消耗型商品 ID 列表 (如果有)
    override suspend fun getOneTimeNonConsumableProducts(): List<String> {
        return arrayListOf()
    }

    // 返回订阅商品 ID 列表
    override suspend fun getSubscribeProducts(): List<String> =
        suspendCancellableCoroutine { continuation ->
            val subsList = listOf(
                "com.example.vip.1month",
                "com.example.vip.1year"
            )
            continuation.resume(subsList)
        }

    // 处理购买流程 (验证和消耗/确认)
    override suspend fun handlePurchasesProcess(
        isPay: Boolean,
        productType: BillingProductType,
        purchases: Purchase
    ) {
        // 1. 与您的后端服务器验证购买交易
        // ... 验证逻辑 ...

        // 2. 验证通过后,消耗购买 (如果是消耗品) 或 确认购买 (如果是订阅)
        when (productType) {
            BillingProductType.INAPP -> {
                // 对于一次性消耗型商品
                GooglePayClient.getInstance().getPayService<OneTimeService>()
                    .consumePurchases(purchases, isPay)
            }

            BillingProductType.SUBS -> {
                // 对于订阅商品
                GooglePayClient.getInstance().getPayService<SubscriptionService>()
                    .consumePurchases(purchases, isPay)
            }
        }
    }

    override fun printLog(tag: String, msg: String) {
        Log.d(tag, msg)
    }
}

4. 一次性购买流程

发起一次性购买 (例如:游戏货币、道具):

  1. 构建 BillingParams:

    • accountId: 业务方标识用户的唯一 ID。
    • productId: Google Play 商品 ID。
    • chargeNo: 业务方生成的订单号 (用于追踪)。
  2. 启动支付流程:

    • 获取 OneTimeService
    • 调用 launchBillingFlow

示例:

kotlin 复制代码
val billingParams = BillingParams.Builder()
    .setAccountId("user_123")
    .setProductId("com.example.product.1")
    .setChargeNo("order_456")
    .build()

val result = GooglePayClient.getInstance().getPayService<OneTimeService>()
    .launchBillingFlow(requireActivity(), billingParams)

if (result.code != AppBillingResponseCode.OK) {
    // 处理错误 (例如:显示 Toast 提示)
    result.message.showTips(requireContext())
}

5. 订阅流程

发起订阅:

  1. 构建 BillingSubsParams:

    • accountId: 用户唯一 ID。
    • productId: 订阅商品 ID。
    • basePlanId: 基础方案 ID (Billing Library 5+ 需要)。
    • offerId: 优惠 ID (如果适用)。
    • chargeNo: 业务订单号 (可选,建议用于追踪)。
  2. 启动支付流程:

    • 获取 SubscriptionService
    • 调用 launchBillingFlow

示例:

kotlin 复制代码
val billingSubsParams = BillingSubsParams.Builder()
    .setAccountId("user_123")
    .setProductId("com.example.vip.1month")
    .setBasePlanId("base-plan-id") // 新版结算配置需要
    .setOfferId("offer-id") // 可选
    .setChargeNo("order_789") // 可选,建议用于追踪
    .build()

val result = GooglePayClient.getInstance().getPayService<SubscriptionService>()
    .launchBillingFlow(requireActivity(), billingSubsParams)

if (result.code != AppBillingResponseCode.OK) {
    // 处理错误
    result.message.showTips(requireContext())
}

6. 事件处理

使用 observePayEvent 扩展函数监听支付事件 (成功、失败等)。这可以在 Activity、Fragment 或 Dialog 中完成。

示例:

kotlin 复制代码
observePayEvent { payEvent ->
    when (payEvent) {
        is BillingPayEvent.PaySuccessful -> {
            // 支付成功
            // 注意:消耗/确认操作在 GooglePayService.handlePurchasesProcess 中处理
            "支付成功".showTips(requireContext())
        }
        is BillingPayEvent.PayFailed -> {
            // 支付失败
            payEvent.message.showTips(requireContext())
        }
        is BillingPayEvent.PayConsumeSuccessful -> {
            // 消耗成功 (内部事件)
        }
        is BillingPayEvent.PayConsumeFailed -> {
            // 消耗失败
        }
    }
}

7. 查询商品

您可以查询商品详情 (价格、标题等) 以在 UI 中显示。

一次性商品:

kotlin 复制代码
val products = GooglePayClient.getInstance().getPayService<OneTimeService>()
    .queryProductDetails(listOf("com.example.product.1"))
// 使用结果更新 UI

订阅商品:

kotlin 复制代码
val subsDetails = GooglePayClient.getInstance().getPayService<SubscriptionService>()
    .querySubsOfferDetails(subsOfferParams)

8. 恢复购买

要恢复购买 (例如:用户重装应用或更换设备时),调用 queryPurchases()。这将触发 handlePurchasesProcess 处理任何未消耗/未确认的活跃购买,或者仅仅刷新本地缓存。

kotlin 复制代码
GooglePayClient.getInstance().queryPurchases()

9. 检查 Google Play 可用性

当 Google Play 服务不可用时,库内部会自动使用空实现进行处理,因此您的应用不会崩溃。不过,您仍然可以使用 isGoogleAvailable 来根据需要隐藏支付 UI 元素。

kotlin 复制代码
if (GooglePayClient.getInstance().isGoogleAvailable(context)) {
    // 显示支付 UI
} else {
    // 隐藏支付 UI 或显示其他内容
}

10. 生命周期管理与自动刷新

库会自动处理 BillingClient 的生命周期管理。

自动刷新: 如果您通过 registerActivitys() 注册了重要 Activity(如首页或商城页),库将在以下情况自动刷新库存并处理消耗(基于 setInterval 配置的间隔):

  1. 当这些 Activity 每次可见时。
  2. 每次应用回到前台时。
kotlin 复制代码
GooglePayClient.getInstance().endConnection() // 可选:应用终止时手动断开连接

11. 重要注意事项

  • 生命周期: 库会处理 BillingClient 的生命周期管理。
  • 验证: 务必在授予权益之前在您的后端服务器上验证购买,以防止欺诈。
  • 消耗/确认: Google 要求在 3 天内确认 (订阅) 或消耗 (消耗品) 购买,否则将会退款。您实现的 GooglePayService 中的 handlePurchasesProcess 是在验证后触发此操作的地方。

12. Api Docs

Api Docs

更多指南

相关推荐
qq_170264751 小时前
unity出安卓年龄分级的arr包问题
android·unity·游戏引擎
kejiashao3 小时前
Android View的绘制流程及事件分发机制
android
小蜜蜂嗡嗡3 小时前
flutter实现付费解锁内容的遮挡
android·flutter
进击的cc3 小时前
拒绝背诵!一文带你打穿 Android ANR 发生的底层全链路
android·面试
进击的cc3 小时前
App 启动优化全家桶:别再只盯着 Application 了,热启动优化你真的做对了吗?
android·面试
彭波3964 小时前
安卓手机端安装xapk、apkm软件!怎样安装xapk软件?安卓的apk和XAPK的区别?附教程
android·智能手机
Yang-Never5 小时前
ADB ->adb shell perfetto 抓取 trace 指令
android·开发语言·adb·android studio
2501_937189237 小时前
莫凡电视:地方台专属聚合 稳定直播播放工具
android·源码·源代码管理
耶叶9 小时前
Android 新权限申请模型(Activity Result API)
android
阿拉斯攀登9 小时前
【RK3576 安卓 JNI/NDK 系列 04】JNI 核心语法(下):字符串、数组与对象操作
android·驱动开发·rk3568·瑞芯微·rk安卓驱动·jni字符串操作