Files
webman-buildadmin-mall/docs/PlayX-对接文档(积分商城).md
2026-03-30 11:47:32 +08:00

28 KiB
Raw Blame History

0. 交付说明(给 PlayX

  • 交付物:本文件(接口清单 + 业务流程 + 联调验收清单)。
  • 建议联调顺序Token 验证(远程 PlayX 或本地 verify_token_local_only)→ 每日推送 → 领取 → 红利发放 → 提现入账 → 实物后台处理。
  • 约定:接口 URL、字段最终表、签名细节以 PlayX 提供的最终口径为准;本文档负责把流程、幂等、重试与最小字段集合先对齐。

1. 文档目的与范围

本文档用于 PlayX 与积分商城Points Mall联调对接。范围仅包含

  • 前端PlayX 以内嵌 Iframe 打开商城 H5使用 postMessage 传递 token/session。
  • 后端:商城后端独立部署;与 PlayX 后端通过 REST API 通讯。
  • 数据同步:仅 PlayX 每日 Cron 推送T+1玩家数据到商城用于计算“待领取积分/今日可领取上限”。
  • 发放方式:商城在红利兑换/提现(回平台余额)下单后,直接调用 PlayX API 发放/入账PlayX 侧每 10 分钟 Cron 执行 5.9 adjustment/最终入账。

不在本文档范围内:

  • 任何实时 webhook充值、外部积分、流水等
  • 会员端“同步额度/同步流水”按钮触发的对接链路。

2. 系统边界与调用方向

flowchart LR
  PlayXFrontend["PlayXFrontend"] -->|"postMessage(token/session)"| MallFrontend["MallFrontend(Iframe)"]
  MallFrontend -->|"API(商城后端)"| MallBackend["MallBackend"]
  MallBackend -->|"TokenVerificationAPI"| PlayXBackend["PlayXBackend"]
  PlayXBackend -->|"DailyPushAPI(T+1)"| MallBackend
  MallBackend -->|"BonusGrantAPI/BalanceCreditAPI"| PlayXBackend

playx.verify_token_local_only=true「Token 验证」一步在商城内完成,不经过 PlayXBackend 的 Token Verification API详见 §4.1

3. 关键业务对象与状态机

3.1 资产口径(最小集合)

  • LockedPoints待领取积分:由 PlayX 每日推送的“昨日输赢净额”在商城端按规则计算得到,未领取前不可消费。
  • AvailablePoints可用积分:领取后可用于兑换/提现的积分余额。
  • TodayLimit今日可领取上限:由 PlayX 每日推送的“昨日总存款”按规则计算得到。
  • TodayClaimed今日已领取:当日累计领取量(用于进度条与上限控制)。

3.2 订单类型

  • BONUS:红利兑换
  • PHYSICAL:实物兑换
  • WITHDRAW:提现回平台余额(非现金出款)

3.3 统一订单状态

  • PENDING处理中:订单已创建,等待发放/审核/发货等后续处理
  • COMPLETED已发放:红利到账或提现入账完成
  • SHIPPED已发货:实物已发货,包含物流公司与单号
  • REJECTED已驳回:失败或人工拒绝;积分需退回(退回规则见 6.2

4. 端到端流程6 条)

4.1 登录鉴权Iframe + token

接口与字段细节以代码为准完整说明见同目录《PlayX-接口文档.md》§3 H5、§3.2 temLogin、§3.3 verify-token)。

4.1.1 身份与数据模型(商城侧)

  • 商城用户:表 mall_userH5 临时登录、后台创建等均落此表)。
  • PlayX 资产扩展:表 mall_playx_user_asset,与 mall_user 一对一mall_user_idplayx_user_id 均唯一)。
  • 业务侧用户标识:对外接口中的 user_id(字符串)在多数场景下即 playx_user_idPlayX 玩家 ID
    • 若用户仅通过商城 临时登录 进入、尚无 PlayX 正式 ID商城会生成占位 ID形如 mall_{mall_user.id},与每日推送中的真实 user_id 区分(避免与纯数字 ID 混淆)。
  • H5 调业务接口时:服务端内部统一解析为 mall_user.id再查资产与订单解析规则见《PlayX-接口文档》§3.1)。

4.1.2 模式 A联调 PlayX生产/预发,远程校验 token

  1. 用户在 PlayX 内打开积分商城入口iframe
  2. PlayX 前端通过 postMessage 将 PlayX 下发的 token(及必要上下文)传给商城 H5。
  3. 商城 H5 调用商城后端 POST /api/v1/playx/verify-token,由商城向 PlayX 的 Token Verification APIplayx.api.base_url + playx.api.token_verify_url)发起校验。
  4. 前提:配置 playx.verify_token_local_only = false,且 playx.api.base_url 已配置为可访问的 PlayX 基地址。
  5. PlayX 返回 user_idusername(及可选会话过期时间等)。
  6. 商城写入 mall_playx_sessionsession_id + 上述 user_id/username + 过期时间),后续 H5 可用 session_idtoken(商城临时 token见模式 B 调用资产/领取等接口。

幂等与安全:

  • H5 不要把 PlayX 的 user_id 当作唯一可信凭据直传下单;以 token 换 session 或由商城签发 token 的流程为准。
  • PlayX 侧 Token Verification API 的鉴权/签名若有按双方约定可参考《PlayX-接口文档》§2.1)。

4.1.3 模式 B本地 / 无 PlayX 环境(商城自校验,不请求 PlayX

用于开发、联调前自测、或 PlayX 接口未就绪时:

  1. 配置 playx.verify_token_local_only = true(环境变量 PLAYX_VERIFY_TOKEN_LOCAL_ONLY,默认可为开启,以项目 config/playx.php 为准)。
  2. 此时 /api/v1/playx/verify-token 不会访问 PlayX,仅在商城内校验 商城临时 tokentoken 表类型 muser,由下方 temLogin 签发)。
  3. 调用 GET/POST /api/v1/temLogin?username=...(需 buildadmin.agent_auth.temp_login_enable = true):不存在则创建 mall_user,并保证存在 mall_playx_user_asset(含 playx_user_id,默认 mall_{id}),返回 userInfo.tokenplayx_user_idexpires_in 等。
  4. 再用该 token 调用 verify-token 可得到 session_id,与模式 A 一样供后续接口使用;或直接带 token / ba-token 调资产等接口见《PlayX-接口文档》§3.1)。

4.1.4 会话续期与前端约定

  • 会话续期:玩家停留时间较长时,若商城 API 返回 token/session 失效(如 401H5 可通过 postMessage 请 PlayX 父页面 重新派发 PlayX token(模式 A模式 B 下可重新 temLogin 或走 /api/common/refreshTokenmuser-refresh)换取新 access token。
  • 具体错误码与 Headerba-token以前端与《PlayX-接口文档》为准。

4.2 每日 T+1 入池PlayX → 商城)

  1. PlayX 在每日固定时间向商城调用 Daily Push API,推送昨日玩家数据。(注:请确认并约定好 date 字段对应的具体时区边界,如以 UTC+8 为准)。
  2. 商城按 user_id + date 幂等去重入库。由于不支持通过重复推送做数据修正,若 PlayX 发现个别账单算错了,请联系商城运营在后台进行人工调账处理,勿重复推送。
  3. 商城计算:
    • 新增保障金(待领取积分增量)
    • 今日可领取上限
  4. 会员次日进入商城时,可在首页看到更新后的 LockedPoints 与 TodayLimit。

4.3 领取流程Locked → Available

  1. 会员在首页点击“领取”。
  2. 商城后端校验LockedPoints > 0且 TodayLimit - TodayClaimed > 0。
  3. 商城计算 canClaim = min(LockedPoints, TodayLimit - TodayClaimed),并原子更新:
    • LockedPoints -= canClaim
    • AvailablePoints += canClaim
    • TodayClaimed += canClaim
  4. 返回最新资产,前端刷新。

幂等:

  • 领取操作建议使用 claim_request_id(由前端生成或后端生成返回)实现幂等,避免重复点击导致重复领取。

4.4 红利兑换(商城 → PlayX 发放)

  1. 会员在“红利”商品点击兑换并确认(为避免客诉,商城前端会提示会员:红利发放预计在此后约 10 分钟内入账,请耐心等待)。
  2. 商城创建 BONUS 订单PENDING并校验/扣减可用积分(原子扣减)。
  3. 商城调用 PlayX Bonus Grant API,传递红利发放信息(字段见 5.3)。
  4. 若 PlayX API 返回初步排队接收成功HTTP 200 且 status="accepted"
    • 商城订单保持 PENDING等待 PlayX 侧 10 分钟 Cron 最终发放/入账)。
    • 记录 playx_transaction_id(或外部流水号)用于后续追踪。
    • 商城后端将通过调用 PlayX 的 “交易状态查询 API”见 5.5)来轮询获取最终结果,最终确认为成功后,商城订单才会流转闭环为 COMPLETED。
  5. 若 PlayX API 返回失败:
    • 订单保持 PENDING并记录失败原因与下一次可重试时间
    • 支持后台“手动重试”(见 6.3
    • 若经过 N 次重试仍失败或确认 PlayX 侧不可达成:订单转 REJECTED 并退回积分(见 6.2

4.5 实物兑换(商城后台人工处理)

  1. 会员选择实物并填写收货信息(姓名/电话/地址)。
  2. 商城创建 PHYSICAL 订单PENDING并原子扣减可用积分。
  3. 后台运营:
    • 发货:录入物流公司与单号 → 状态 SHIPPED
    • 驳回:录入原因 → 状态 REJECTED → 自动退回积分

4.6 提现回平台余额(商城 → PlayX 入账)

  1. 会员在“提现到平台余额”商品点击提现并确认(前端同样需向用户提示约 10 分钟入账预期)。
  2. 商城创建 WITHDRAW 订单PENDING并原子扣减可用积分。
  3. 商城调用 PlayX Balance Credit API(或同一发放接口的提现模式),传入入账信息。
  4. 若 PlayX API 返回初步排队接收成功HTTP 200 且 status="accepted"
    • 商城订单保持 PENDING等待 PlayX 侧 10 分钟 Cron 最终入账)。
    • 记录 playx_transaction_id(或外部流水号)用于后续追踪。
    • 商城后端通过「交易状态查询 API」见 5.5)轮询获取终态,确认成功后订单才流转为 COMPLETED。
  5. 若 PlayX API 返回失败(非 200 或 statusaccepted):失败处理同 4.4。

5. 接口清单(按调用方向)

说明:以下为接口“结构与字段清单”。具体 URL、Header、签名算法、错误码需 PlayX 提供或双方确认后固化。

5.1 PlayX → MallDaily Push API每日推送

  • 目的:推送昨日玩家数据,用于 T+1 计算入池与领取上限。
  • 幂等键user_id + datedate 建议为 PlayX 业务日)
  • Method/Path建议POST /api/v1/playx/daily-push

请求字段说明(最小集合,来自现有资料):

字段名 类型 必填 说明
request_id String 请求的唯一网关流水号,商城端用于日志追踪和外层防重。
date String 数据归属的业务日期(如 "2026-03-18"),用于限定该批数据的生效周期。
user_id String 玩家在 PlayX 的唯一标识 ID在此商城体系中以此作为核心绑定主键。
username String 玩家展示名,仅用于后台日志人工可读性或冗余展示,不作业务主键。
lifetime_total_deposit Decimal 玩家历史总充值(如有需要用于玩家 VIP 分层,当前传值保留即可)。
lifetime_total_withdraw Decimal 玩家历史总提现(储备字段)。
yesterday_win_loss_net Decimal 昨日净输赢金额(如果玩家亏损,应为负数)。务必是已扣除返点、红利、奖励、推荐佣金、VIP Bonus 的税后净额,严格代表玩家的真实净负盈利。
yesterday_total_deposit Decimal 昨日玩家总充值金额积分商城专门用此字段来计算“今日可领取上限TodayLimit”。

请求示例:

{
  "request_id": "px_20260319_000001",
  "date": "2026-03-18",
  "user_id": "U123",
  "username": "demo_user_01",
  "lifetime_total_deposit": 5000.0,
  "lifetime_total_withdraw": 2000.0,
  "yesterday_win_loss_net": -120.5,
  "yesterday_total_deposit": 50.0
}

响应字段说明(建议):

字段名 类型 必填 说明
request_id String 完全透传原请求的 request_id,便于双向日志匹配追踪。
accepted Boolean true 标识商城已成功接收并解析了该批数据。
deduped Boolean true,标识该条数据因 user_id + date 已存在而被商城系统幂等静默丢弃(去重)。
message String 成功或失败的补充说明(如 "ok""duplicate input" 等异常提示)。

响应示例:

{
  "request_id": "px_20260319_000001",
  "accepted": true,
  "deduped": false,
  "message": "ok"
}

5.2 Mall → PlayXToken Verification API

  • 目的:商城后端校验 token/session获取可信 user_idusername
  • Method/Path示例占位POST /api/v1/auth/verify-token

请求字段说明(建议):

字段名 类型 必填 说明
request_id String 商城系统生成的唯一请求流水号。
tokensession String 从带有商城的 Iframe postMessage 接收到的用户加密登录散列或临时会话凭证。

请求示例:

{
  "request_id": "mall_20260319_9f1b6d",
  "token": "eyJhbGciOi..."
}

响应字段说明(建议):

字段名 类型 必填 说明
request_id String 透传请求时的 request_id
user_id String 该凭证解密后对应的、在 PlayX 平台具有唯一性的玩家专属 ID。
username String 该玩家显示名用于加载商城的界面头部“欢迎xxx”渲染。
token_expire_at String Token 的物理过期时间(如 ISO8601用于商城前端预判是否到了需要执行无感续期重置的底线时间。

响应示例:

{
  "request_id": "mall_20260319_9f1b6d",
  "user_id": "U123",
  "username": "demo_user_01",
  "token_expire_at": "2026-03-19T10:12:00Z"
}

5.3 Mall → PlayXBonus Grant API红利发放

来自 PlayX 现有字段清单(待 PlayX 确认最终口径):

请求字段说明(待 PlayX 确认最终口径):

字段名 类型 必填 说明
request_id String 商城发起的 HTTP 请求流水号(纯用于网关层)。
externalTransactionId String 核心防重键:强制要求 PlayX 凭此字段做完全的幂等拦截。这是商城侧派发红利的唯一本地订单号(如 "BONUS_ORD001")。
user_id String 要派发红利的玩家在 PlayX 的基础 ID这需对齐每日推送。
memberLogin String 玩家登录名(若当前 PlayX 核心接口必须传登录名,则商城会补充;若以 user_id 为准,此项可废弃)。
amount Decimal 实际加给玩家游戏余额或红利钱包的具体现金数字。
rewardName String 商城中对应的该红利商品名称,用于让用户后续在 PlayX 流水里看懂这笔钱从何而来。
description String 系统行为备注说明(如 "PointsMall bonus")。
memberInboxMessage String 是否需借调此时机向玩家发送站内站群信内容提示。
category String 标明该红利在游戏侧的所属业务类别的枚举代码(如 daily)。
categoryTitle String 该红利业务类别的中文展示名称。
multiplier (或 turnover) Int 款项入账后,玩家需完成的打码流水约束倍数(如 1 倍或 5 倍)。
startTime / endTime String 红利生效时间窗口(起止时间,视 PlayX 规则传参)。

请求示例:

{
  "request_id": "mall_bonus_20260319_000001",
  "externalTransactionId": "BONUS_ORD20260319_000001",
  "user_id": "U123",
  "memberLogin": "demo_user_01",
  "amount": 50.0,
  "rewardName": "每日回馈 50",
  "description": "PointsMall bonus redemption",
  "memberInboxMessage": "红利已提交,预计 10 分钟内到账",
  "category": "daily",
  "categoryTitle": "每日回馈",
  "multiplier": 1,
  "startTime": "2026-03-19T00:00:00Z",
  "endTime": "2026-03-19T23:59:59Z"
}

响应字段说明(建议):

字段名 类型 必填 说明
request_id String 透传请求号。
playx_transaction_id String PlayX 内部初创的接收入列单号或派发流水号,商城会将其归档以备应对极端客诉争议寻找记录用。
status String 核心状态枚举。若为 accepted,表示请求成功列入 10 分钟 Cron商城中止重试其他值皆触发商城的补偿拦截网。
message String 对入列状态的额外提示信息内容。

响应示例:

{
  "request_id": "mall_bonus_20260319_000001",
  "playx_transaction_id": "PX_TX_778899",
  "status": "accepted",
  "message": "queued"
}

5.4 Mall → PlayXBalance Credit API提现回平台余额

字段建议与 5.3 保持结构一致,至少包含:

请求字段说明(建议与 5.3 保持结构一致):

字段名 类型 必填 说明
request_id String 商城下发的网络请求追溯号。
externalTransactionId String 提现唯一单号,提现接口也需要基于此值做绝对拦截幂等功能
user_id String 申请提现的玩家 ID。
memberLogin String 玩家名(视老接口历史包袱兼容)。
amount Decimal 本次提现要充入 PlayX 主游戏平台真金余额池的具体现金。
multiplier (或 turnover_rule) Int 本真金提现入账后的硬性流水锁定要求倍数限制。
description String 日志源记录说明(如 "PointsMall withdraw")。

请求示例:

{
  "request_id": "mall_withdraw_20260319_000001",
  "externalTransactionId": "WITHDRAW_ORD20260319_000002",
  "user_id": "U123",
  "memberLogin": "demo_user_01",
  "amount": 100.0,
  "multiplier": 1,
  "description": "PointsMall withdraw to PlayX balance"
}

响应说明与 5.3 (Bonus Grant API) 保持一致,主要接收 status="accepted" 作为暂挂确认。

{
  "request_id": "mall_withdraw_20260319_000001",
  "playx_transaction_id": "PX_TX_889900",
  "status": "accepted",
  "message": "queued"
}

5.5 Mall → PlayXTransaction Status Query API交易终态查询

  • 目的:红利/提现申请经 PlayX 接收后(即返回 accepted 后)可能处于排队发放下款状态(如 10 分钟 Cron。商城将通过此接口查询最终业务结果用于闭环商城自身的 PENDING 订单。
  • Method/Path预留GET /api/v1/transaction/status
  • 传参方式:使用 Query String 传递查询主键(若 PlayX 更倾向 POST可改为 POST + JSON body但需在联调前双方定稿一种即可

示例:

  • GET /api/v1/transaction/status?externalTransactionId=WITHDRAW_ORD20260319_000002
  • GET /api/v1/transaction/status?playx_transaction_id=PX_TX_889900(与 externalTransactionId 二选一,推荐优先 externalTransactionId

轮询建议(商城侧):首次调用可在入队成功后约 1 分钟开始;之后间隔约 60 秒 查询一次,直至 statusCOMPLETEDFAILED,或累计轮询达到约 1520 分钟(与 10 分钟 Cron 留足余量)仍未终态则告警并转人工跟进。

请求字段说明(建议选其一作主键):

字段名 类型 必填 说明
externalTransactionId String 是* 商城之前提报请求时创建挂钩的原始提现单号,推荐此查维优先。
playx_transaction_id String 如果之前排队响应抛出了内部派发流水,也可以持此作为二级兜底查询条件。(二选一必填)

响应字段说明(建议):

字段名 类型 必填 说明
status String 该笔资产调拨定时任务执行的彻底终态。只有两种预期终点:COMPLETED(入账成功) 或 FAILED(发放彻底阻断:如平台风控/未通过规则/账号封禁)。如果返回 PENDING 表示该 10 分钟 Cron 仍然没碰这笔单。
amount Decimal 最后实际结算派发的精准明细金额数。
message String 若拦截至 FAILED 终态,该字段负责说明 PlayX 端驳回的业务层原因,便于商城后端登记审计并自动回退积分。

6. 一致性、幂等与退回规则

6.1 幂等原则

  • 每日推送:以 user_id + date 去重,重复推送不得导致重复入池。
  • 兑换/提现交易:以 externalTransactionId 幂等(商城生成并传给 PlayX
  • 领取:以 claim_request_id 幂等,避免重复领取。

6.2 退积分规则(建议统一)

  • 红利/提现
    • PlayX API 调用失败:订单保持 PENDING进入可重试队列不立即退积分避免“退了但 PlayX 已受理/最终入账”的不一致)。
    • 当订单被判定为“最终失败”(例如超过最大重试次数或 PlayX 返回不可恢复错误)时:订单转 REJECTED退回积分并记录原因。
  • 实物
    • 驳回必须退回积分,并记录 reject_reason

6.3 重试与后台操作边界

  • 仅允许对 “尚未收到 status = \"accepted\" 响应、且可以确认未成功发放/未入账” 的订单发起重试。
  • 每次重试必须生成并记录 retry_request_id 与操作者审计日志。
  • 强制防重约定**PlayX 必须根据 externalTransactionId 提供严格的幂等拦截能力!**由于网络请求存在“Read Timeout读超时”的黑盒场景即 PlayX 实际已处理但响应由于网络中断未抵达商城,商城将会发起重试保护。如果 PlayX 不去拦截此重发单号,将必然出现给用户发双份钱的高危资损事故。

接收成功与终态闭环判定(关键约定):

  • 第一步(接收排队):本系统调用发放类 API仅当收到 HTTP 200 且 status = "accepted" 时,视为 PlayX 已接收入队成功,此时商城绝不再对发放接口发起新的成功路径请求。若返回非 200、或响应超时、或未能解析出明确 accepted:商城可对同一 externalTransactionId 进行有限次重试;PlayX 须对该单号严格幂等——重复请求不得产生第二笔发放,且应返回与首次受理一致或可识别的幂等结果(如再次返回 accepted 或明确 DUPLICATE_REQUEST 等,由双方约定响应形态)。
  • 第二步(确认终态闭环):针对已入队返回 accepted 的订单,商城将调用**“交易终态查询 API”5.5**验证 PlayX 后台的最终发放结果实现闭环更新。

默认重试策略(建议):

  • 自动重试:对 PLAYX_UPSTREAM_ERROR/超时类错误,最多 3 次(间隔 1min/5min/15min
  • 不重试INVALID_SIGNATUREREQUEST_EXPIREDRULE_NOT_SATISFIEDINVALID_TOKEN(需要修复请求或重新鉴权)。
  • 人工重试:后台按钮触发,要求输入原因并记录审计。

7. 安全要求Shared Secret Key

建议所有 PlayX ↔ Mall 的后端调用统一:

  • Header
    • X-Request-Id
    • X-Timestamp
    • X-Signature
  • 签名:使用共享 SecretKey,对 request body + timestamp + requestId 进行 HMAC具体算法由双方定稿
  • 时效timestamp 允许偏差窗口(例如 5 分钟),超出拒绝。

签名建议(可直接落地的默认):

  • X-Signature = HMAC_SHA256(secret, canonical_string)
  • canonical_string = X-Timestamp + \"\\n\" + X-Request-Id + \"\\n\" + HTTP_METHOD + \"\\n\" + PATH + \"\\n\" + SHA256(REQUEST_BODY_JSON)

其中:

  • PATH 不含域名与 querystring例如 /api/v1/playx/daily-push)。
  • REQUEST_BODY_JSON 使用原始 request body不做 key 排序时需双方约定序列化方式更推荐双方统一为“key 排序后的紧凑 JSON”

8. 错误码与可观测(建议)

最低要求:

  • INVALID_SIGNATURE
  • REQUEST_EXPIRED
  • INVALID_TOKEN
  • DUPLICATE_REQUEST
  • INSUFFICIENT_POINTS
  • RULE_NOT_SATISFIED
  • PLAYX_UPSTREAM_ERROR

错误码返回结构(建议统一):

{
  "request_id": "xxx",
  "code": "PLAYX_UPSTREAM_ERROR",
  "message": "timeout",
  "retryable": true
}

8.1 幂等:同一 externalTransactionId 重复调用Bonus Grant / Balance Credit

PlayX 须保证:同一 externalTransactionId 无论被调用多少次,资金侧最多只入账一次。商城在「读超时重试」或联调压测时会重复提交同一单号,响应须符合以下 两种约定之一(联调前择一写死,避免双方解析不一致)。

模式 A推荐再次请求仍返回 HTTP 200且与首次受理语义一致

  • 第二次及以后请求:status 仍为 "accepted"(或文档约定的等价成功态),不得再次触发新的发放队列条目导致双发。
  • 建议同时带回首次playx_transaction_id(若与首次不同,须在联调中禁止或说明兼容规则)。
{
  "request_id": "mall_bonus_20260319_000099",
  "playx_transaction_id": "PX_TX_778899",
  "status": "accepted",
  "message": "duplicate externalTransactionId, already accepted"
}

模式 B显式重复错误码HTTP 状态可与 PlayX 规范一致,如 200 或 409联调前约定

  • codeDUPLICATE_REQUEST(或双方统一的幂等冲突码),retryablefalse,提示商城勿再重试发放接口、改查 5.5 终态。
{
  "request_id": "mall_bonus_20260319_000099",
  "code": "DUPLICATE_REQUEST",
  "message": "externalTransactionId already processed",
  "retryable": false,
  "playx_transaction_id": "PX_TX_778899"
}

日志与审计:

  • 每次跨系统调用必须落 request_id、入参摘要、响应摘要、耗时、结果码。

9. 联调与验收清单

9.1 鉴权

  • token 正常/过期/无效/重复请求
  • postMessage 未收到 token 的超时提示

9.2 每日推送

  • 正常推送 1 次
  • 同一 user_id+date 重复推送(应 dedup
  • 跨时区日期边界(按约定业务日)

9.3 领取

  • locked=0 不可领取
  • 上限不足部分领取
  • 幂等:重复点击不重复加积分

9.4 红利/提现

  • 发放接口HTTP 200 且 status="accepted" 后,订单 PENDING记录 playx_transaction_id不再对发放接口重放(终态靠 5.5)。
  • 发放接口:非 200 / 超时 / 非 accepted:失败原因落库,可自动或人工重试;PlayX 对同一 externalTransactionId 须严格幂等
  • 交易终态查询5.5:按 externalTransactionId 查询,验证返回 COMPLETED / FAILED / PENDING;长时间 PENDING 走告警与人工。
  • 幂等联调:同一 externalTransactionId 连续发送 2 次PlayX 侧不得重复入账,第二次响应须符合双方约定的幂等语义。

9.5 实物

  • 提交收货信息
  • 发货录入物流单号
  • 驳回退积分并展示原因

10. 需要 PlayX 提供/确认的信息清单(用于联调收口)

  • Token Verification APIURL、请求/响应字段、错误码、token 有效期/刷新策略、是否支持 session。
  • Daily Push API推送时间点、时区、date 口径(业务日还是自然日)、失败重发策略、字段定义(特别是 yesterday_win_loss_net 的扣项范围)。
  • Bonus Grant API / Balance Credit APIURL、鉴权签名要求、字段最终表、确认以 externalTransactionId 作为拦截幂等键,以及返回的 playx_transaction_id 定义与查询方式。
  • 交易终态查询 API如适用:提供专门供商城拉取订单最终入账结果的查询接口 URL 及返回结构。
  • 发送站内信 API如适用:在管理后台手动处理实物商品发货/驳回时,如需通过信箱通知用户,请提供外部触发站内信的 API 渠道。
  • 枚举值配置:请尽早提供发放接口中 category 等字段的固定枚举值字典,以便商城后台完成商品发货配置项的落库。