petsHero-AI/docs/payment_flow.md
2026-03-13 22:04:57 +08:00

7.4 KiB
Raw Permalink Blame History

支付流程(当前实现)

本文档描述充值页「Buy」点击后的完整支付流程recharge_screen.dartPaymentApiGooglePlayPurchaseService 实现一致。


1. 流程总览

用户点击 Buy
    │
    ├─ lucky === true 且已登录
    │       │
    │       ├─ getPaymentMethods(activityId)
    │       ├─ 弹窗选择支付方式_PaymentMethodDialog
    │       ├─ createPayment(activityId, productId, paymentMethod, subPaymentMethod)
    │       │
    │       ├─ 若选中的是 Google Payresource/ceremony == "GooglePay"
    │       │       ├─ 调起 Google Play 内购productId = item.code
    │       │       ├─ 拿到 serverVerificationData
    │       │       └─ POST /v1/payment/googlepay(merchant, federation, asset)
    │       │
    │       └─ 否则(其他支付方式)
    │               └─ 打开 createPayment 返回的 payUrlconvert在外部浏览器完成支付
    │
    └─ lucky !== true 或未登录
            └─ 仅 Android直接调起 Google Play 内购productId = item.code无 createPayment

2. 支付分支依据

  • 数据来源/v1/user/common_info 响应中的 surgeJSON 字符串),解析得到 lucky
  • 客户端状态UserState.enableThirdPartyPayment(登录后由 AuthService 从 common_info 写入)。
  • 分支
    • 第三方支付lucky == trueUserState.userId 非空 → 走「获取支付方式 → 弹窗选择 → 创建订单 → 按支付方式分支」。
    • 直接谷歌支付:否则(未开三方或未登录)→ 仅 Android 下直接调起 Google Play 内购,不调 getPaymentMethods / createPayment。

3. 支付界面与商品展示

  • 界面recharge_screen.dart
  • 商品来源GET /v1/payment/getGooglePayActivitiesAndroid或 getApplePayActivitiesiOS列表为 data.summonactivitys
  • 单条商品字段V2 映射)
字段(映射后) 说明
helm 产品代码,即 Google Pay 商品 ID(与 Play 后台「产品 ID」必须一致
warrior 活动 IDactivityIdgetPaymentMethods / createPayment 必传
guardian 实际金额,界面带 $ 显示
curriculum 原价,界面中划线显示
forge 赠送积分,界面展示
glossary 标题greaves=积分数familiar=货币等
  • 界面规则:价格 / 原价 / 赠送积分同一行展示;仅当前点击的 item 的 Buy 按钮显示 loading_loadingProductId

4. 第三方支付流程lucky === true

4.1 步骤顺序

步骤 说明
1 用户点击某商品的 Buy得到该商品的 activityIdwarriorproductIdhelm/code
2 POST /v1/payment/get-payment-methodsbodywarrior=activityIdvambrace=国家(可选)。
3 弹窗 支付方式列表renew用户选择一项 → 得到 resourcepaymentMethod、ceremonysubPaymentMethod
4 POST /v1/payment/createPaymentbodysentinel, asset(userId), warrior(activityId), resource, ceremony得到 federation订单 ID、convertpayUrl等。
5a resource 或 ceremony 为 "GooglePay"(不区分大小写):调起 Google Play 内购productId=item.code成功后用 serverVerificationData 作为 merchant 调用 POST /v1/payment/googlepaymerchant, federation, asset不打开 payUrl。
5b 否则:若有 convertpayUrl则用 url_launcher 在外部浏览器打开;无则仅提示订单已创建。

4.2 支付方式弹窗

  • 在 get-payment-methods 成功后,展示 Select payment method 弹窗_PaymentMethodDialog列表项来自 renewPaymentMethodItemresource, ceremony, name, icon, recommend 等)。
  • 用户选择一项后关闭弹窗,用选中的 resource、ceremony 调用 createPayment取消弹窗则不创建订单并清除 loading。

4.3 选中 Google Pay 时的子流程

  • 条件:_isGooglePay(paymentMethod, subPaymentMethod) 为 true即 paymentMethod 或 subPaymentMethod 转为小写后等于 "googlepay")。
  • 仅 Android 执行;非 Android 提示 "Google Pay is only available on Android" 并结束。
  • 调用 GooglePlayPurchaseService.launchPurchaseAndReturnData(productId)(所有内购统一使用):
    • productId 为当前商品的 codehelm
    • 成功返回 serverVerificationDatamerchant失败/取消返回 null。
  • 若有 merchant 且订单 IDfederation存在调用 PaymentApi.googlepay(merchant, federation, asset)根据返回提示成功或失败并打点AdjustEvents

5. 直接谷歌支付lucky !== true

  • Android:调用 GooglePlayPurchaseService.launchPurchaseAndReturnData(item.code),不请求 getPaymentMethods / createPayment凭据可用于后续服务端回调。
  • 成功/失败通过 SnackBar 与 AdjustEvents 打点;商品 ID 仍为 item.code(须与 Play 后台产品 ID 一致)。
  • 非 Android提示 "Google Pay is only available on Android"。

6. 接口与字段速查

  • GET /v1/payment/getGooglePayActivities
    Querysentinel, portal响应 data.summon / data.cleanse单项含 helm, warrior, guardian, curriculum, forge 等。

  • POST /v1/payment/get-payment-methods
    Bodywarrior(activityId), vambrace(可选)。响应 data.renew每项 resource, ceremony, brigade, greylist, deny 等。

  • POST /v1/payment/createPayment
    Querysentinel, asset(userId)。Bodysentinel, asset, warrior, resource, ceremony(可选)。
    响应 datafederation(订单ID), convert(payUrl), destroy(状态), handshake, transplant 等。

  • POST /v1/payment/googlepay
    Querysentinel, asset(userId)。Bodymerchant(购买凭据 serverVerificationData), federation(订单ID), asset, sample(签名可选)。
    响应 datafederation, line(状态), awaken(是否加积分) 等。

  • 请求/响应 V2 加解密与字段映射以 petsHeroAI_client_guide.md 为准。


7. 代码与文档对应

功能 位置
支付分支与 Buy 入口 recharge_screen.dart_onBuy → enableThirdPartyPayment ? _runThirdPartyPayment : _runGooglePay
第三方:获取支付方式 + 弹窗 _runThirdPartyPaymentPaymentApi.getPaymentMethods → _PaymentMethodDialog
第三方:创建订单 + Google Pay / 打开链接 _createOrderAndOpenUrlcreatePayment → _isGooglePay ? launchPurchaseAndReturnData + googlepay : launchUrl(convert)
直接谷歌支付 _runGooglePay → _launchGooglePlayPurchase → GooglePlayPurchaseService.launchPurchaseAndReturnData
谷歌内购 + 凭据上报 google_play_purchase_service.dartlaunchPurchaseAndReturnDataPaymentApi.googlepay
商品未找到排查 docs/google_pay_product_not_found.md

8. 小结

  • 三方开getPaymentMethods → 弹窗选支付方式 → createPayment → 选 Google Pay 则内购 + googlepay 回调,否则打开 payUrl。
  • 三方关:仅 Android 直接内购item.code无 createPayment。
  • 商品 ID:始终使用接口返回的 helmitem.code须与 Google Play 后台「产品 ID」完全一致否则会出现「系统无法找到您要购买的商品」。