petsHero-AI/docs/googlepay.md
2026-03-12 20:40:37 +08:00

5.5 KiB
Raw Blame History

谷歌支付流程

本文档描述 Android 上 Google Play 内购的完整流程,与 recharge_screen.dartGooglePlayPurchaseServicePaymentApi 实现对应。


1. 流程总览

  • 第三方支付开启enable_third_party_payment === true 且已登录):先创建订单 → 调起谷歌支付 → 支付成功后回调 /v1/payment/googlepay
  • 第三方支付关闭或未登录:仅 Android 直接调起谷歌支付,不创建订单、不回调 googlepay。
用户点击 Buy某商品
    │
    ├─ 第三方支付开 + 已登录
    │       ├─ getPaymentMethods(activityId)
    │       ├─ 弹窗选择支付方式
    │       ├─ 若选「Google Pay」
    │       │       ├─ POST /v1/payment/createPayment → 得到 federation订单 id
    │       │       ├─ 调起 Google Play 内购productId = 商品 code/helm
    │       │       └─ 支付成功后 POST /v1/payment/googlepay见下文
    │       └─ 若选其他方式 → 打开 createPayment 返回的 payUrl
    │
    └─ 第三方支付关或未登录
            └─ 仅 Android直接调起 Google Play 内购productId = 商品 code无 createPayment、无 googlepay 回调

2. 创建订单(仅第三方 + 选 Google Pay 时)

项目 说明
接口 POST /v1/payment/createPayment
入参 sentinel, asset(userId), warrior(activityId), resource, ceremony选 Google Pay 时 resource/ceremony 含 "GooglePay"
关键响应 federation:订单 id后续 googlepay 回调必传;convert:其他支付方式的 payUrl选 Google Pay 时不使用
  • 当返回的 federation订单 id不为空时,继续调起谷歌支付并可在成功后回调 googlepay。
  • 当返回的 federation 为空时:可按业务要求重试创建订单(如最多 3 次),仍失败则提示失败。

3. 调起谷歌支付

项目 说明
代码 GooglePlayPurchaseService.launchPurchaseAndReturnData(productId)(所有内购统一使用)
productId 当前商品的 code(即接口里的 helm),须与 Google Play 后台「产品 ID」完全一致
成功结果 返回的凭据用于构造 googlepay 回调 body见下节

Android 执行;非 Android 提示 "Google Pay is only available on Android"。


4. 支付成功后回调:POST /v1/payment/googlepay

仅在第三方支付开 + 选 Google Pay + 已先创建订单时调用。请求体为 JSON服务端用于校验并落单。

4.1 请求体字段body

请求体为四个顶层字段语义与取值来源对应关系如下id / purchaseData / signature / userId 分别对应 federation / merchant / sample / asset

请求体字段 含义(填入的值) 客户端取值来源
sample 签名signature 谷歌支付成功后,GooglePlayPurchaseDetails.billingClientPurchasesignature
merchant 购买凭据 JSONpurchaseData 同上 billingClientPurchaseoriginalJson
federation 支付/订单 idid 创建订单接口 createPayment 返回的 federation
asset 用户 iduserId 当前登录用户 id与 createPayment 的 asset 一致)

4.2 示例 body 结构

{
  "sample": "YbOntv0sVOsZ5d4F8hIYdPNSMy9a4+5oAsV/...",
  "merchant": "{\"orderId\":\"GPA.3327-0087-2324-9960\",\"packageName\":\"com.xxx.xxxx\",\"productId\":\"com.xxx.xxxx599\",\"purchaseTime\":1773305500428,\"purchaseState\":0,\"purchaseToken\":\"...\",\"quantity\":1,\"acknowledged\":false}",
  "federation": "1315538320560683421235",
  "asset": "135303839048"
}
  • federation:来自 createPayment 的 federation(服务端订单 id
  • merchant:来自 Google Play 的 originalJson(整段购买凭据 JSON 字符串)。
  • sample:来自 Google Play 的 signature,服务端用其校验 merchant。
  • asset:当前用户 id。

4.3 与客户端实现对应

  • 内购成功后,从 GooglePlayPurchaseDetails.billingClientPurchasePurchaseWrapper)取 originalJsonsignature,分别填入请求体的 merchantsample
  • createPayment 返回的 federation 填入 federation,当前用户 id 填入 asset

5. 代码位置速查

步骤 位置
Buy 分支(第三方 vs 直接谷歌) recharge_screen.dart_onBuy_runThirdPartyPayment / _runGooglePay
创建订单 PaymentApi.createPayment;调用处在 _createOrderAndOpenUrl
调起内购并拿凭据 GooglePlayPurchaseService.launchPurchaseAndReturnData(productId)
回调 googlepay PaymentApi.googlepay(...),在 _createOrderAndOpenUrl 内、内购成功后调用
凭据数据结构 AndroidGooglePlayPurchaseDetails.billingClientPurchaseorderId, originalJson, signature

6. 小结

  1. 创建订单仅在选择「Google Pay」且第三方支付开启时调用 createPayment拿到 federation 后才会调起谷歌支付并回调 googlepay。
  2. 调起谷歌支付productId 固定为当前商品的 codehelm,与 Play 后台产品 ID 一致。
  3. 回调 googlepaybody 为四字段 samplesignaturemerchantpurchaseData/originalJsonfederation(订单 idassetuserIdfederation 为空则不回调,可按策略重试创建订单或提示失败。