client_framework/docs/payment_flow.md
2026-04-22 17:46:22 +08:00

8.0 KiB
Raw Permalink Blame History

支付流程(多客户端通用)

1. 概述

本文档描述换皮应用可复用的支付全流程,覆盖:商品获取、支付方式选择、订单创建、平台内购回调、订单核销、补单与账户刷新。
文档以“能力与流程”表达,不绑定具体客户端项目、目录路径或某一语言实现。


2. 支付流程总览

用户点击充值 / Buy
    │
    ├─ 已登录 且 开启第三方支付
    │       │
    │       ├─ 拉取支付方式(基于商品/活动)
    │       ├─ 用户选择支付方式
    │       ├─ 创建订单(服务端生成业务订单)
    │       │
    │       ├─ 若为平台内购(如 Google Play
    │       │       ├─ 调起商店购买
    │       │       ├─ 获取 purchaseData + signature + storeOrderId
    │       │       └─ 回调服务端校验与入账
    │       │
    │       └─ 若为外部支付
    │               └─ 打开 payUrl 在 Web/外部浏览器完成支付
    │
    └─ 未登录 或 未开启第三方支付
            └─ 可走平台内购直购分支(由业务策略决定)

3. 支付分支依据(通用)

条件 说明
是否登录 通常需要用户身份用于订单归属与回调入账
是否开启第三方支付 由服务端用户配置或渠道策略控制
当前平台能力 Android / iOS 对内购与外部支付支持差异
商品配置 某些商品只允许特定支付方式

建议将分支判断集中在统一策略层,避免同一逻辑散落在多个页面。


4. 商品展示与获取

4.1 获取时机

  • 进入充值页时拉取一次;
  • 下拉刷新或切换国家/渠道后重新拉取;
  • 支付成功后建议刷新,确保档位与余额展示一致。

4.2 商品字段(通用语义)

字段语义 说明
productId 商店商品 ID内购必填
activityId 服务端活动/档位 ID建单常用
actualAmount 实付金额
originAmount 原价(可用于划线价)
bonus / bonusCredits 赠送积分
credits 到账积分(如与赠送分开展示)
title 商品文案(可能由服务端直接下发)

5. 第三方支付流程(通用)

5.1 拉取支付方式

以商品或活动为上下文请求支付方式列表,常见字段包括:

  • paymentMethod:主支付方式(例如平台内购、钱包、卡支付等)
  • subPaymentMethod:子方式(可选)
  • name / icon:展示信息
  • recommend:是否推荐

5.2 创建订单

创建订单请求通常包含(逻辑字段名

  • 应用标识(app
  • 用户标识(userId
  • 商品或活动标识(activityId / productId
  • 支付主方式(paymentMethod
  • 支付类型(paymentType,按渠道语义填写)
  • 子支付方式(subPaymentMethod,如卡种/钱包子通道)

关键点:subPaymentMethod 是独立语义字段。
仅传 paymentType 不会自动补出 subPaymentMethod

5.2.1 推荐入参组合(避免丢子支付方式)

  • 卡支付场景(示例):
    • paymentMethod = MIFAPAY
    • paymentType = MIFAPAY(或按后端约定值)
    • subPaymentMethod = CreditCard
  • 若传成 paymentType = CreditCard 且未传 subPaymentMethod,常见结果是:
    • paymentMethod
    • paymentType
    • 缺少 subPaymentMethod

响应通常返回:

  • orderId(业务订单号)
  • payUrl(外部支付链接;仅外部支付场景)
  • status(订单状态)
  • 可选 federation(用于与商店订单映射)

5.3 分支执行

  • 平台内购:拉起商店购买 -> 取回凭据 -> 回调服务端核验 -> 成功后完成/消费交易。
  • 外部支付:打开 payUrl 完成支付 -> 回前台后查询订单状态或拉取账户余额。

6. 平台内购标准链路Android/iOS 可类比)

  1. productId 调起商店支付;
  2. 拿到商店返回的交易凭据(如 purchaseDatasignaturestoreOrderId
  3. 调服务端回调接口完成验签与入账;
  4. 服务端成功后,客户端执行“完成交易/消费交易”(防止重复拥有问题);
  5. 刷新账户余额与订单状态。

关键原则:先服务端验单成功,再本地完成/消费交易,避免凭据丢失导致资产不一致。


7. 补单机制(订单恢复)

7.1 触发时机

  • 应用启动后;
  • 进入充值页时;
  • 支付异常返回时(例如网络中断、回调超时)。

7.2 恢复流程

  1. 拉取未完成/未核销的商店订单(历史订单 + 监听流中的待处理订单);
  2. 对每笔订单尝试找到业务订单映射(如 federation / orderId
  3. 若可映射:再次走服务端回调核验,成功后完成/消费交易;
  4. 若不可映射:按产品策略处理(仅完成/消费以解除占用,或进入人工排查队列);
  5. 恢复结束后刷新账户与充值记录。

8. API 能力清单(通用命名)

能力 典型方法 说明
获取商品列表 GET Android/iOS 可分端点
获取支付方式 POST/GET 入参通常含 activityId
创建订单 POST 返回 orderIdpayUrl
平台内购回调 POST 提交 purchaseDatasignature
订单列表 GET 历史支付记录
订单详情 GET 查询单笔订单状态

9. 核心字段对照(通用)

业务含义 常见请求字段 常见响应字段
应用标识 app -
用户标识 userId -
活动/档位 activityId -
支付方式 paymentMethod -
子支付方式 paymentType -
订单标识 orderId / id orderId
购买签名 signature -
购买数据 purchaseData -
商品 ID - productId
实付金额 - actualAmount
原价 - originAmount
赠送积分 - bonus / bonusCredits
支付链接 - payUrl
订单状态 - status

10. 常见问题

10.1 商品未找到

  • 现象:发起内购时提示商品不存在;
  • 常见原因:客户端 productId 与商店后台配置不一致,或商品未上架到当前测试轨道;
  • 排查建议:核对包名/应用 ID、商品 ID、地区、测试账号与轨道配置。

10.2 回调成功但积分未更新

  • 现象:支付侧显示成功,账户余额未变;
  • 常见原因:回调后未刷新账户、订单状态未落库、幂等冲突;
  • 排查建议:检查回调响应、订单状态接口与账户刷新链路。

10.3 重复购买被拦截(已拥有此内容)

  • 现象:商店提示已拥有,无法再次购买;
  • 常见原因:上一笔交易未完成/未消费;
  • 排查建议:执行补单恢复流程并确保完成/消费逻辑成功。

10.4 创建订单请求缺少子支付方式字段

  • 现象:抓包中 createPayment 入参有 paymentMethod,但缺少 subPaymentMethod
  • 常见原因:只传了 paymentType,没有传 subPaymentMethod
  • 排查建议
    • 检查应用侧建单调用是否显式传入 subPaymentMethod
    • 对照请求日志逐项核对三元组:paymentMethod / paymentType / subPaymentMethod
    • 若项目启用了字段映射,再额外确认映射配置与服务端契约一致。

11. 实施建议(多客户端复用)

  • 以“流程能力层”封装支付,不把分支逻辑写死在页面;
  • 页面只关心:档位展示、用户选择、状态反馈;
  • 建单、回调、补单、轮询统一由支付服务层负责;
  • 统一错误码与文案映射,避免各端提示不一致;
  • 对关键节点埋点:拉起支付、建单成功、回调成功、补单成功、入账成功;
  • 保持接口字段可映射,支持不同换皮应用的字段命名差异。