跳转到内容

Google Play

Kasskeep 用 Play Developer API 校验购买,替你完成确认(acknowledge)和消耗(consume),并通过 Pub/Sub 推送订阅接收实时开发者通知(RTDN)。渠道 id:google_play,平台:android。

  1. 在 Google Cloud 控制台选一个项目,启用 Google Play Android Developer API。
  2. 在 IAM & Admin → Service accounts 下创建服务账号。它不需要任何 Cloud 角色。在 Keys → Add key 下创建 JSON 密钥并下载。
  3. 在 Play Console 打开 Users and permissions → Invite new users,填入服务账号邮箱,在 App permissions 下添加你的 App,并授予:
    • View financial data, orders and cancellation survey responses;
    • Manage orders and subscriptions。
  4. 权限最长可能要 24 小时才生效。在此之前 API 会返回 401 或 403。
  5. 上传密钥:
终端窗口
npx @kasskeep/cli apps update --id app_xxx --android-package com.example.app --google-service-account-file ./play-service-account.json

JSON 里必须有 client_email 和 private_key。整个文件会加密保存;GET .../credentials 只返回 client email、项目 id 和私钥指纹。

  1. 在 Google Cloud 控制台 Pub/Sub → Create topic,比如命名为 play-rtdn。
  2. 在主题的权限里,给 [email protected] 授予 Pub/Sub Publisher 角色。
  3. 在主题上创建订阅:
    • 投递类型选 Push,端点填 https://api.kasskeep.com/v1/stores/google/<app_id>/rtdn;
    • 启用 authentication,选一个服务账号(它的邮箱就是下面的 Pub/Sub 邮箱),并设置 audience。直接用端点地址作 audience 最省事。
  4. 把 audience 和邮箱告诉 Kasskeep。两者都设置之前,RTDN 会返回 422:
终端窗口
npx @kasskeep/cli apps update --id app_xxx \
--google-pubsub-audience https://api.kasskeep.com/v1/stores/google/app_xxx/rtdn \
--google-pubsub-email [email protected]
  1. 在 Play Console 打开你的 App,进入 Monetize → Monetization setup → Real-time developer notifications,填入完整主题名 projects/<project>/topics/play-rtdn,发送一条测试通知。

一个主题可以有多个订阅,所以别的系统可以通过自己的订阅收到同样的通知。

  • Authorization: Bearer 里的 OIDC token 必须由 Google 签名、由 accounts.google.com 签发、未过期,aud 等于配置的 audience,且已验证的 email 等于配置的邮箱。否则返回 401。
  • 消息里的 packageName 必须等于 App 的 android_package。否则返回 400。
  • 消息按 messageId 去重。通知只当作一个信号:Kasskeep 总是先从 API 拉取当前状态,再记录。
  • 成功、重复和未知 token 返回 200。API 调用失败返回 502,处理出错返回 500,好让 Pub/Sub 重新投递。

Kasskeep 记录每笔购买后都会确认或消耗它。告诉它哪些一次性商品是消耗型的;末尾的 * 表示前缀匹配:

终端窗口
npx @kasskeep/cli apps update --id app_xxx --google-consumable-products "coins_*,gems_100"

列表里的商品会被消耗,其他一次性商品按非消耗型确认。消耗型商品如果没列进去,就会被确认而非消耗,用户将无法再次购买。传这个参数会替换整个列表;传空字符串则清空。

确认失败会在后台重试,从 1 分钟后开始,间隔逐次翻倍,最长每 2 小时一次。3 天内未确认的购买会被 Google 退款,所以如果某笔购买的确认一直失败(通常是缺少 Play 权限),需要你去处理。

  • 一次性商品:Play 商品 id 就是 product_id。请启用待处理购买(pending purchases)。待处理购买在完成之前不会被记录或确认。
  • 订阅:订阅 id 就是 product_id。基础方案和优惠以 data.base_plan_id 和 data.offer_id 给出。如果不同周期对应的权限不同,请使用不同的订阅 id。
  • 订阅购买只读取第一个 line item;不支持附加订阅(add-on)。
  • 升级和降级:带 linkedPurchaseToken 的新购买会合并到原有订阅,并保留它的 original_transaction_id。
  • Play Billing Library 8 或更高版本。把 obfuscatedAccountId 设为用户 id。SDK 会替你做。
  • 把 purchaseToken 提交给 Kasskeep。不要在客户端确认或消耗。
Google 状态 status
SUBSCRIPTION_STATE_ACTIVE active;关闭自动续订时为 canceled
SUBSCRIPTION_STATE_CANCELED 到期前为 canceled,之后为 expired
SUBSCRIPTION_STATE_IN_GRACE_PERIOD grace_period
SUBSCRIPTION_STATE_ON_HOLD billing_retry
SUBSCRIPTION_STATE_PAUSED paused
SUBSCRIPTION_STATE_EXPIRED、SUBSCRIPTION_STATE_PENDING_PURCHASE_CANCELED expired
SUBSCRIPTION_STATE_PENDING 不记录
已作废(voided)或 SUBSCRIPTION_REVOKED revoked

Kasskeep 还会每小时读取一次 Voided Purchases API(首次回溯 7 天,最多 30 天),并重新检查快到期的订阅,以及处于宽限期、保留期(on hold)或暂停状态的订阅。