数据库备份

This commit is contained in:
2026-04-21 16:00:02 +08:00
parent 7b9187fb62
commit ca0a9e75e0
42 changed files with 1178 additions and 438 deletions

View File

@@ -1,17 +1,17 @@
## 0. 交付说明(给 PlayX
## 0. 交付说明(给 playX
- **交付物**:本文件(接口清单 + 业务流程 + 联调验收清单)。
- **建议联调顺序**Token 验证(远程 PlayX 或本地 `verify_token_local_only`)→ 每日推送 → 领取 → 红利发放 → 提现入账 → 实物后台处理。
- **约定**:接口 URL、字段最终表、签名细节以 PlayX 提供的最终口径为准;本文档负责把流程、幂等、重试与最小字段集合先对齐。
- **建议联调顺序**Token 验证(远程 playX 或本地 `verify_token_local_only`)→ 每日推送 → 领取 → 红利发放 → 提现入账 → 实物后台处理。
- **约定**:接口 URL、字段最终表、签名细节以 playX 提供的最终口径为准;本文档负责把流程、幂等、重试与最小字段集合先对齐。
## 1. 文档目的与范围
本文档用于 PlayX 与积分商城Points Mall联调对接。范围仅包含
本文档用于 playX 与积分商城Points Mall联调对接。范围仅包含
- 前端:PlayX 以内嵌 Iframe 打开商城 H5使用 postMessage 传递 token/session。
- 后端:商城后端独立部署;与 PlayX 后端通过 REST API 通讯。
- 数据同步:仅 PlayX 每日 Cron 推送T+1玩家数据到商城用于计算“待领取积分/今日可领取上限”。
- 发放方式:商城在红利兑换/提现(回平台余额)下单后,直接调用 PlayX API 发放/入账;PlayX 侧每 10 分钟 Cron 执行 5.9 adjustment/最终入账。
- 前端:playX 以内嵌 Iframe 打开商城 H5使用 postMessage 传递 token/session。
- 后端:商城后端独立部署;与 playX 后端通过 REST API 通讯。
- 数据同步:仅 playX 每日 Cron 推送T+1玩家数据到商城用于计算“待领取积分/今日可领取上限”。
- 发放方式:商城在红利兑换/提现(回平台余额)下单后,直接调用 playX API 发放/入账;playX 侧每 10 分钟 Cron 执行 5.9 adjustment/最终入账。
不在本文档范围内:
@@ -22,22 +22,22 @@
```mermaid
flowchart LR
PlayXFrontend["PlayXFrontend"] -->|"postMessage(token/session)"| MallFrontend["MallFrontend(Iframe)"]
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
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**。
> 当 **`playX.verify_token_local_only=true`** 时「Token 验证」一步在商城内完成,**不经过** `playXBackend` 的 Token Verification API详见 **§4.1**。
## 3. 关键业务对象与状态机
### 3.1 资产口径(最小集合)
- **LockedPoints待领取积分**:由 PlayX 每日推送的“昨日输赢净额”在商城端按规则计算得到,未领取前不可消费。
- **LockedPoints待领取积分**:由 playX 每日推送的“昨日输赢净额”在商城端按规则计算得到,未领取前不可消费。
- **AvailablePoints可用积分**:领取后可用于兑换/提现的积分余额。
- **TodayLimit今日可领取上限**:由 PlayX 每日推送的“昨日总存款”按规则计算得到。
- **TodayLimit今日可领取上限**:由 playX 每日推送的“昨日总存款”按规则计算得到。
- **TodayClaimed今日已领取**:当日累计领取量(用于进度条与上限控制)。
### 3.2 订单类型
@@ -57,48 +57,48 @@ flowchart LR
### 4.1 登录鉴权Iframe + token
> **接口与字段细节**以代码为准,完整说明见同目录《PlayX-接口文档.md》§3 H5、§3.2 `temLogin`、§3.3 `verifyToken`)。
> **接口与字段细节**以代码为准,完整说明见同目录《playX-接口文档.md》§3 H5、§3.2 `temLogin`、§3.3 `verifyToken`)。
#### 4.1.1 身份与数据模型(商城侧)
- **商城用户**:表 `mall_user`H5 临时登录、后台创建等均落此表)。
- **PlayX 资产扩展**:表 `mall_playx_user_asset`,与 `mall_user` **一对一**`mall_user_id``playx_user_id` 均唯一)。
- **业务侧用户标识**:对外接口中的 `user_id`(字符串)在多数场景下即 **`playx_user_id`**PlayX 玩家 ID
- 若用户仅通过商城 **临时登录** 进入、尚无 PlayX 正式 ID商城会生成占位 ID形如 **`mall_{mall_user.id}`**,与每日推送中的真实 `user_id` 区分(避免与纯数字 ID 混淆)。
- **H5 调业务接口时**:服务端内部统一解析为 **`mall_user.id`**,再查资产与订单(解析规则见《PlayX-接口文档》§3.1)。
- **playX 资产扩展**:表 `mall_playx_user_asset`,与 `mall_user` **一对一**`mall_user_id``playx_user_id` 均唯一)。
- **业务侧用户标识**:对外接口中的 `user_id`(字符串)在多数场景下即 **`playx_user_id`**playX 玩家 ID
- 若用户仅通过商城 **临时登录** 进入、尚无 playX 正式 ID商城会生成占位 ID形如 **`mall_{mall_user.id}`**,与每日推送中的真实 `user_id` 区分(避免与纯数字 ID 混淆)。
- **H5 调业务接口时**:服务端内部统一解析为 **`mall_user.id`**,再查资产与订单(解析规则见《playX-接口文档》§3.1)。
#### 4.1.2 模式 A联调 PlayX生产/预发,远程校验 token
#### 4.1.2 模式 A联调 playX生产/预发,远程校验 token
1. 用户在 PlayX 内打开积分商城入口iframe
2. PlayX 前端通过 postMessage 将 **PlayX 下发的 token**(及必要上下文)传给商城 H5。
3. 商城 H5 调用商城后端 **`POST /api/v1/mall/verifyToken`**,由商城向 PlayX 的 **Token Verification API**`playx.api.base_url` + `playx.api.token_verify_url`)发起校验。
4. **前提**:配置 **`playx.verify_token_local_only = false`**,且 **`playx.api.base_url`** 已配置为可访问的 PlayX 基地址。
5. PlayX 返回 **`user_id``username`**(及可选会话过期时间等)。
1. 用户在 playX 内打开积分商城入口iframe
2. playX 前端通过 postMessage 将 **playX 下发的 token**(及必要上下文)传给商城 H5。
3. 商城 H5 调用商城后端 **`POST /api/v1/mall/verifyToken`**,由商城向 playX 的 **Token Verification API**`playX.api.base_url` + `playX.api.token_verify_url`)发起校验。
4. **前提**:配置 **`playX.verify_token_local_only = false`**,且 **`playX.api.base_url`** 已配置为可访问的 playX 基地址。
5. playX 返回 **`user_id``username`**(及可选会话过期时间等)。
6. 商城写入 **`mall_playx_session`**`session_id` + 上述 `user_id`/`username` + 过期时间),后续 H5 可用 **`session_id`** 或 **`token`(商城临时 token见模式 B** 调用资产/领取等接口。
幂等与安全:
- H5 **不要**把 PlayX 的 `user_id` 当作唯一可信凭据直传下单;**以 token 换 session** 或由商城签发 token 的流程为准。
- PlayX 侧 Token Verification API 的鉴权/签名(若有)按双方约定(可参考《PlayX-接口文档》§2.1)。
- H5 **不要**把 playX 的 `user_id` 当作唯一可信凭据直传下单;**以 token 换 session** 或由商城签发 token 的流程为准。
- playX 侧 Token Verification API 的鉴权/签名(若有)按双方约定(可参考《playX-接口文档》§2.1)。
#### 4.1.3 模式 B本地 / 无 PlayX 环境(商城自校验,不请求 PlayX
#### 4.1.3 模式 B本地 / 无 playX 环境(商城自校验,不请求 playX
用于开发、联调前自测、或 PlayX 接口未就绪时:
用于开发、联调前自测、或 playX 接口未就绪时:
1. 配置 **`playx.verify_token_local_only = true`**(环境变量 **`PLAYX_VERIFY_TOKEN_LOCAL_ONLY`**,默认可为开启,以项目 `config/playx.php` 为准)。
2. 此时 **`/api/v1/mall/verifyToken` 不会访问 PlayX**,仅在商城内校验 **商城临时 token**token 表类型 **`muser`**,由下方 `temLogin` 签发)。
1. 配置 **`playX.verify_token_local_only = true`**(环境变量 **`PLAYX_VERIFY_TOKEN_LOCAL_ONLY`**,默认可为开启,以项目 `config/playx.php` 为准)。
2. 此时 **`/api/v1/mall/verifyToken` 不会访问 playX**,仅在商城内校验 **商城临时 token**token 表类型 **`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.token`**、**`playx_user_id`**、**`expires_in`** 等。
4. 再用该 token 调用 **`verifyToken`** 可得到 **`session_id`**,与模式 A 一样供后续接口使用;或直接带 **`token` / `ba-token`** 调资产等接口(见《PlayX-接口文档》§3.1)。
4. 再用该 token 调用 **`verifyToken`** 可得到 **`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/refreshToken`**`muser-refresh`)换取新 access token。
- 具体错误码与 Header`ba-token`)以前端与《PlayX-接口文档》为准。
- **会话续期**:玩家停留时间较长时,若商城 API 返回 token/session 失效(如 401H5 可通过 postMessage 请 playX 父页面 **重新派发 playX token**(模式 A模式 B 下可重新 **`temLogin`** 或走 **`/api/common/refreshToken`**`muser-refresh`)换取新 access token。
- 具体错误码与 Header`ba-token`)以前端与《playX-接口文档》为准。
### 4.2 每日 T+1 入池(PlayX → 商城)
### 4.2 每日 T+1 入池(playX → 商城)
1. PlayX 在每日固定时间向商城调用 **Daily Push API**,推送昨日玩家数据。(**注:请确认并约定好 `date` 字段对应的具体时区边界,如以 UTC+8 为准**)。
2. 商城按 `user_id + date` 幂等去重入库。由于不支持通过重复推送做数据修正,**若 PlayX 发现个别账单算错了,请联系商城运营在后台进行人工调账处理**,勿重复推送。
1. playX 在每日固定时间向商城调用 **Daily Push API**,推送昨日玩家数据。(**注:请确认并约定好 `date` 字段对应的具体时区边界,如以 UTC+8 为准**)。
2. 商城按 `user_id + date` 幂等去重入库。由于不支持通过重复推送做数据修正,**若 playX 发现个别账单算错了,请联系商城运营在后台进行人工调账处理**,勿重复推送。
3. 商城计算:
- 新增保障金(待领取积分增量)
- 今日可领取上限
@@ -118,19 +118,19 @@ flowchart LR
- 领取操作建议使用 `claim_request_id`(由前端生成或后端生成返回)实现幂等,避免重复点击导致重复领取。
### 4.4 红利兑换(商城 → PlayX 发放)
### 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 最终发放/入账)。
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 返回失败:
- **商城后端将通过调用 playX 的 “交易状态查询 API”见 5.5)来轮询获取最终结果**,最终确认为成功后,商城订单才会流转闭环为 COMPLETED。
5.playX API 返回失败:
- 订单保持 PENDING并记录失败原因与下一次可重试时间
- 支持后台“手动重试”(见 6.3
- 若经过 N 次重试仍失败或确认 PlayX 侧不可达成:订单转 REJECTED 并退回积分(见 6.2
- 若经过 N 次重试仍失败或确认 playX 侧不可达成:订单转 REJECTED 并退回积分(见 6.2
### 4.5 实物兑换(商城后台人工处理)
@@ -140,25 +140,25 @@ flowchart LR
- 发货:录入物流公司与单号 → 状态 SHIPPED
- 驳回:录入原因 → 状态 REJECTED → 自动退回积分
### 4.6 提现回平台余额(商城 → PlayX 入账)
### 4.6 提现回平台余额(商城 → playX 入账)
1. 会员在“提现到平台余额”商品点击提现并确认(**前端同样需向用户提示约 10 分钟入账预期**)。
2. 商城创建 WITHDRAW 订单PENDING并原子扣减可用积分。
3. 商城调用 PlayX **Balance Credit API**(或同一发放接口的提现模式),传入入账信息。
4.PlayX API 返回初步排队接收成功HTTP 200 且 `status="accepted"`
- 商城订单保持 PENDING等待 PlayX 侧 10 分钟 Cron 最终入账)。
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 或 `status``accepted`):失败处理同 4.4。
5.playX API 返回失败(非 200 或 `status``accepted`):失败处理同 4.4。
## 5. 接口清单(按调用方向)
> 说明:以下为接口“结构与字段清单”。具体 URL、Header、签名算法、错误码需 PlayX 提供或双方确认后固化。
> 说明:以下为接口“结构与字段清单”。具体 URL、Header、签名算法、错误码需 playX 提供或双方确认后固化。
### 5.1 PlayX → MallDaily Push API每日推送
### 5.1 playX → MallDaily Push API每日推送
- **目的**:推送昨日玩家数据,用于 T+1 计算入池与领取上限。
- **幂等键**`user_id + date`date 建议为 PlayX 业务日)
- **幂等键**`user_id + date`date 建议为 playX 业务日)
- **Method/Path建议**`POST /api/v1/mall/dailyPush`
请求字段说明(最小集合,来自现有资料):
@@ -167,7 +167,7 @@ flowchart LR
| --- | --- | --- | --- |
| `request_id` | String | 是 | 请求的唯一网关流水号,商城端用于日志追踪和外层防重。 |
| `date` | String | 是 | 数据归属的业务日期(如 `"2026-03-18"`),用于限定该批数据的生效周期。 |
| `user_id` | String | 是 | 玩家在 PlayX 的唯一标识 ID在此商城体系中以此作为核心绑定主键。 |
| `user_id` | String | 是 | 玩家在 playX 的唯一标识 ID在此商城体系中以此作为核心绑定主键。 |
| `username` | String | 否 | 玩家展示名,仅用于后台日志人工可读性或冗余展示,不作业务主键。 |
| `lifetime_total_deposit` | Decimal | 否 | 玩家历史总充值(如有需要用于玩家 VIP 分层,当前传值保留即可)。 |
| `lifetime_total_withdraw` | Decimal | 否 | 玩家历史总提现(储备字段)。 |
@@ -209,7 +209,7 @@ flowchart LR
}
```
### 5.2 Mall → PlayXToken Verification API
### 5.2 Mall → playXToken Verification API
- **目的**:商城后端校验 token/session获取可信 `user_id``username`
- **Method/Path示例占位**`POST /api/v1/auth/verify-token`
@@ -235,7 +235,7 @@ flowchart LR
| 字段名 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `request_id` | String | 是 | 透传请求时的 `request_id`。 |
| `user_id` | String | 是 | 该凭证解密后对应的、在 PlayX 平台具有唯一性的玩家专属 ID。 |
| `user_id` | String | 是 | 该凭证解密后对应的、在 playX 平台具有唯一性的玩家专属 ID。 |
| `username` | String | 否 | 该玩家显示名用于加载商城的界面头部“欢迎xxx”渲染。 |
| `token_expire_at` | String | 否 | Token 的物理过期时间(如 ISO8601用于商城前端预判是否到了需要执行无感续期重置的底线时间。 |
@@ -250,26 +250,26 @@ flowchart LR
}
```
### 5.3 Mall → PlayXBonus Grant API红利发放
### 5.3 Mall → playXBonus Grant API红利发放
来自 PlayX 现有字段清单(待 PlayX 确认最终口径):
来自 playX 现有字段清单(待 playX 确认最终口径):
请求字段说明(待 PlayX 确认最终口径):
请求字段说明(待 playX 确认最终口径):
| 字段名 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `request_id` | String | 是 | 商城发起的 HTTP 请求流水号(纯用于网关层)。 |
| `externalTransactionId` | String | 是 | **核心防重键:强制要求 PlayX 凭此字段做完全的幂等拦截**。这是商城侧派发红利的唯一本地订单号(如 `"BONUS_ORD001"`)。 |
| `user_id` | String | 是 | 要派发红利的玩家在 PlayX 的基础 ID这需对齐每日推送。 |
| `memberLogin` | String | 否 | 玩家登录名(若当前 PlayX 核心接口必须传登录名,则商城会补充;若以 `user_id` 为准,此项可废弃)。 |
| `externalTransactionId` | String | 是 | **核心防重键:强制要求 playX 凭此字段做完全的幂等拦截**。这是商城侧派发红利的唯一本地订单号(如 `"BONUS_ORD001"`)。 |
| `user_id` | String | 是 | 要派发红利的玩家在 playX 的基础 ID这需对齐每日推送。 |
| `memberLogin` | String | 否 | 玩家登录名(若当前 playX 核心接口必须传登录名,则商城会补充;若以 `user_id` 为准,此项可废弃)。 |
| `amount` | Decimal | 是 | 实际加给玩家游戏余额或红利钱包的具体现金数字。 |
| `rewardName` | String | 否 | 商城中对应的该红利商品名称,用于让用户后续在 PlayX 流水里看懂这笔钱从何而来。 |
| `rewardName` | String | 否 | 商城中对应的该红利商品名称,用于让用户后续在 playX 流水里看懂这笔钱从何而来。 |
| `description` | String | 否 | 系统行为备注说明(如 `"PointsMall bonus"`)。 |
| `memberInboxMessage` | String | 否 | 是否需借调此时机向玩家发送站内站群信内容提示。 |
| `category` | String | 是 | 标明该红利在游戏侧的所属业务类别的枚举代码(如 `daily`)。 |
| `categoryTitle` | String | 否 | 该红利业务类别的中文展示名称。 |
| `multiplier` (或 `turnover`) | Int | 是 | 款项入账后,玩家需完成的打码流水约束倍数(如 1 倍或 5 倍)。 |
| `startTime` / `endTime` | String | 否 | 红利生效时间窗口(起止时间,视 PlayX 规则传参)。 |
| `startTime` / `endTime` | String | 否 | 红利生效时间窗口(起止时间,视 playX 规则传参)。 |
请求示例:
@@ -296,7 +296,7 @@ flowchart LR
| 字段名 | 类型 | 必填 | 说明 |
| --- | --- | --- | --- |
| `request_id` | String | 是 | 透传请求号。 |
| `playx_transaction_id` | String | 否 | PlayX 内部初创的接收入列单号或派发流水号,商城会将其归档以备应对极端客诉争议寻找记录用。 |
| `playx_transaction_id` | String | 否 | playX 内部初创的接收入列单号或派发流水号,商城会将其归档以备应对极端客诉争议寻找记录用。 |
| `status` | String | 是 | 核心状态枚举。若为 `accepted`,表示请求成功列入 10 分钟 Cron商城中止重试其他值皆触发商城的补偿拦截网。 |
| `message` | String | 否 | 对入列状态的额外提示信息内容。 |
@@ -311,7 +311,7 @@ flowchart LR
}
```
### 5.4 Mall → PlayXBalance Credit API提现回平台余额
### 5.4 Mall → playXBalance Credit API提现回平台余额
字段建议与 5.3 保持结构一致,至少包含:
@@ -323,7 +323,7 @@ flowchart LR
| `externalTransactionId` | String | 是 | **提现唯一单号,提现接口也需要基于此值做绝对拦截幂等功能**。 |
| `user_id` | String | 是 | 申请提现的玩家 ID。 |
| `memberLogin` | String | 否 | 玩家名(视老接口历史包袱兼容)。 |
| `amount` | Decimal | 是 | 本次提现要充入 PlayX 主游戏平台真金余额池的具体现金。 |
| `amount` | Decimal | 是 | 本次提现要充入 playX 主游戏平台真金余额池的具体现金。 |
| `multiplier` (或 `turnover_rule`) | Int | 是 | 本真金提现入账后的硬性流水锁定要求倍数限制。 |
| `description` | String | 否 | 日志源记录说明(如 `"PointsMall withdraw"`)。 |
@@ -337,7 +337,7 @@ flowchart LR
"memberLogin": "demo_user_01",
"amount": 100.0,
"multiplier": 1,
"description": "PointsMall withdraw to PlayX balance"
"description": "PointsMall withdraw to playX balance"
}
```
@@ -352,11 +352,11 @@ flowchart LR
}
```
### 5.5 Mall → PlayXTransaction Status Query API交易终态查询
### 5.5 Mall → playXTransaction Status Query API交易终态查询
- **目的**:红利/提现申请经 PlayX 接收后(即返回 `accepted` 后)可能处于排队发放下款状态(如 10 分钟 Cron。商城将通过此接口查询最终业务结果用于闭环商城自身的 PENDING 订单。
- **目的**:红利/提现申请经 playX 接收后(即返回 `accepted` 后)可能处于排队发放下款状态(如 10 分钟 Cron。商城将通过此接口查询最终业务结果用于闭环商城自身的 PENDING 订单。
- **Method/Path预留**`GET /api/v1/transaction/status`
- **传参方式**:使用 **Query String** 传递查询主键(若 PlayX 更倾向 POST可改为 `POST` + JSON body但需在联调前双方定稿一种即可
- **传参方式**:使用 **Query String** 传递查询主键(若 playX 更倾向 POST可改为 `POST` + JSON body但需在联调前双方定稿一种即可
示例:
@@ -378,21 +378,21 @@ flowchart LR
| --- | --- | --- | --- |
| `status` | String | 是 | 该笔资产调拨定时任务执行的彻底终态。只有两种预期终点:**`COMPLETED`**(入账成功) 或 **`FAILED`**(发放彻底阻断:如平台风控/未通过规则/账号封禁)。如果返回 `PENDING` 表示该 10 分钟 Cron 仍然没碰这笔单。 |
| `amount` | Decimal | 否 | 最后实际结算派发的精准明细金额数。 |
| `message` | String | 否 | 若拦截至 `FAILED` 终态,该字段负责说明 PlayX 端驳回的业务层原因,便于商城后端登记审计并自动回退积分。 |
| `message` | String | 否 | 若拦截至 `FAILED` 终态,该字段负责说明 playX 端驳回的业务层原因,便于商城后端登记审计并自动回退积分。 |
## 6. 一致性、幂等与退回规则
### 6.1 幂等原则
- **每日推送**:以 `user_id + date` 去重,重复推送不得导致重复入池。
- **兑换/提现交易**:以 `externalTransactionId` 幂等(商城生成并传给 PlayX
- **兑换/提现交易**:以 `externalTransactionId` 幂等(商城生成并传给 playX
- **领取**:以 `claim_request_id` 幂等,避免重复领取。
### 6.2 退积分规则(建议统一)
- **红利/提现**
- PlayX API 调用失败:订单保持 PENDING进入可重试队列不立即退积分避免“退了但 PlayX 已受理/最终入账”的不一致)。
- 当订单被判定为“最终失败”(例如超过最大重试次数或 PlayX 返回不可恢复错误)时:订单转 REJECTED退回积分并记录原因。
- playX API 调用失败:订单保持 PENDING进入可重试队列不立即退积分避免“退了但 playX 已受理/最终入账”的不一致)。
- 当订单被判定为“最终失败”(例如超过最大重试次数或 playX 返回不可恢复错误)时:订单转 REJECTED退回积分并记录原因。
- **实物**
- 驳回必须退回积分,并记录 `reject_reason`
@@ -400,12 +400,12 @@ flowchart LR
- 仅允许对 “尚未收到 `status = \"accepted\"` 响应、且可以确认未成功发放/未入账” 的订单发起重试。
- 每次重试必须生成并记录 `retry_request_id` 与操作者审计日志。
- **强制防重约定****PlayX 必须根据 `externalTransactionId` 提供严格的幂等拦截能力!**由于网络请求存在“Read Timeout读超时”的黑盒场景PlayX 实际已处理但响应由于网络中断未抵达商城,商城将会发起重试保护。如果 PlayX 不去拦截此重发单号,将必然出现给用户发双份钱的高危资损事故。
- **强制防重约定****playX 必须根据 `externalTransactionId` 提供严格的幂等拦截能力!**由于网络请求存在“Read Timeout读超时”的黑盒场景playX 实际已处理但响应由于网络中断未抵达商城,商城将会发起重试保护。如果 playX 不去拦截此重发单号,将必然出现给用户发双份钱的高危资损事故。
接收成功与终态闭环判定(关键约定):
- **第一步(接收排队)**:本系统调用发放类 API仅当收到 HTTP 200 且 `status = "accepted"` 时,视为 PlayX 已接收入队成功,此时商城**绝不再对发放接口发起新的成功路径请求**。若返回非 200、或响应超时、或未能解析出明确 `accepted`:商城可对**同一** `externalTransactionId` 进行有限次重试;**PlayX 须对该单号严格幂等**——重复请求不得产生第二笔发放,且应返回与首次受理一致或可识别的幂等结果(如再次返回 `accepted` 或明确 `DUPLICATE_REQUEST` 等,由双方约定响应形态)。
- **第二步(确认终态闭环)**:针对已入队返回 accepted 的订单,商城将调用**“交易终态查询 API”5.5**验证 PlayX 后台的最终发放结果实现闭环更新。
- **第一步(接收排队)**:本系统调用发放类 API仅当收到 HTTP 200 且 `status = "accepted"` 时,视为 playX 已接收入队成功,此时商城**绝不再对发放接口发起新的成功路径请求**。若返回非 200、或响应超时、或未能解析出明确 `accepted`:商城可对**同一** `externalTransactionId` 进行有限次重试;**playX 须对该单号严格幂等**——重复请求不得产生第二笔发放,且应返回与首次受理一致或可识别的幂等结果(如再次返回 `accepted` 或明确 `DUPLICATE_REQUEST` 等,由双方约定响应形态)。
- **第二步(确认终态闭环)**:针对已入队返回 accepted 的订单,商城将调用**“交易终态查询 API”5.5**验证 playX 后台的最终发放结果实现闭环更新。
默认重试策略(建议):
@@ -415,7 +415,7 @@ flowchart LR
## 7. 安全要求Shared Secret Key
建议所有 PlayX ↔ Mall 的后端调用统一:
建议所有 playX ↔ Mall 的后端调用统一:
- Header
- `X-Request-Id`
@@ -459,7 +459,7 @@ flowchart LR
### 8.1 幂等:同一 `externalTransactionId` 重复调用Bonus Grant / Balance Credit
PlayX 须保证:**同一** `externalTransactionId` 无论被调用多少次,**资金侧最多只入账一次**。商城在「读超时重试」或联调压测时会重复提交同一单号,响应须符合以下 **两种约定之一**(联调前择一写死,避免双方解析不一致)。
playX 须保证:**同一** `externalTransactionId` 无论被调用多少次,**资金侧最多只入账一次**。商城在「读超时重试」或联调压测时会重复提交同一单号,响应须符合以下 **两种约定之一**(联调前择一写死,避免双方解析不一致)。
**模式 A推荐再次请求仍返回 HTTP 200且与首次受理语义一致**
@@ -475,7 +475,7 @@ PlayX 须保证:**同一** `externalTransactionId` 无论被调用多少次,
}
```
**模式 B显式重复错误码HTTP 状态可与 PlayX 规范一致,如 200 或 409联调前约定**
**模式 B显式重复错误码HTTP 状态可与 playX 规范一致,如 200 或 409联调前约定**
- `code``DUPLICATE_REQUEST`(或双方统一的幂等冲突码),`retryable``false`,提示商城勿再重试发放接口、改查 5.5 终态。
@@ -515,9 +515,9 @@ PlayX 须保证:**同一** `externalTransactionId` 无论被调用多少次,
### 9.4 红利/提现
- 发放接口HTTP 200 且 `status="accepted"` 后,订单 PENDING记录 `playx_transaction_id`**不再对发放接口重放**(终态靠 5.5)。
- 发放接口:非 200 / 超时 / 非 `accepted`:失败原因落库,可自动或人工重试;**PlayX 对同一 `externalTransactionId` 须严格幂等**。
- 发放接口:非 200 / 超时 / 非 `accepted`:失败原因落库,可自动或人工重试;**playX 对同一 `externalTransactionId` 须严格幂等**。
- **交易终态查询5.5**:按 `externalTransactionId` 查询,验证返回 `COMPLETED` / `FAILED` / `PENDING`;长时间 `PENDING` 走告警与人工。
- 幂等联调:同一 `externalTransactionId` 连续发送 2 次,PlayX 侧**不得重复入账**,第二次响应须符合双方约定的幂等语义。
- 幂等联调:同一 `externalTransactionId` 连续发送 2 次,playX 侧**不得重复入账**,第二次响应须符合双方约定的幂等语义。
### 9.5 实物
@@ -525,7 +525,7 @@ PlayX 须保证:**同一** `externalTransactionId` 无论被调用多少次,
- 发货录入物流单号
- 驳回退积分并展示原因
## 10. 需要 PlayX 提供/确认的信息清单(用于联调收口)
## 10. 需要 playX 提供/确认的信息清单(用于联调收口)
- **Token Verification API**URL、请求/响应字段、错误码、token 有效期/刷新策略、是否支持 session。
- **Daily Push API**推送时间点、时区、date 口径(业务日还是自然日)、失败重发策略、字段定义(特别是 `yesterday_win_loss_net` 的扣项范围)。