数据库备份

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

@@ -2,35 +2,35 @@
本文件为 **内部使用** 的完整说明,用于:
- 梳理积分商城与 PlayX 之间的 **全量业务流程**(含当前选型与备选方案)。
- 梳理积分商城与 playX 之间的 **全量业务流程**(含当前选型与备选方案)。
- 统一后台实现口径(资产计算、订单状态机、幂等、重试、对账)。
- 为后续版本扩展(实时 webhook、同步按钮、PlayX 拉取模式)预留空间。
- 为后续版本扩展(实时 webhook、同步按钮、playX 拉取模式)预留空间。
对外给 PlayX 的精简版请参考:`PlayX-对接文档(积分商城).md`
对外给 playX 的精简版请参考:`playX-对接文档(积分商城).md`
## 2. 当前选型概览V1.0
- **主键标识**`user_id`(贯穿每日推送、资产、订单、发放接口)。
- **集成方式**
- 前端:商城 H5 以 Iframe 嵌入 PlayXpostMessage 传 token/session。
- 后端:商城独立服务,通过 REST API 与 PlayX 通讯。
- 前端:商城 H5 以 Iframe 嵌入 playXpostMessage 传 token/session。
- 后端:商城独立服务,通过 REST API 与 playX 通讯。
- **数据来源**
- 资产池:仅使用 **每日 Cron 推送T+1** 的历史输赢与充值数据。
- 不引入实时充值/流水 webhook 作为资产来源。
- **发放模式**
- 商城在红利/提现下单后,**直接调用 PlayX 发放接口**Bonus Grant / Balance Credit
- PlayX 侧每 10 分钟 Cron 执行 5.9 adjustment / 最终入账。
- 商城在红利/提现下单后,**直接调用 playX 发放接口**Bonus Grant / Balance Credit
- playX 侧每 10 分钟 Cron 执行 5.9 adjustment / 最终入账。
- **幂等责任分工(方案 A与对外文档一致**
- **PlayX**:对 Bonus Grant / Balance Credit 按 **`externalTransactionId` 严格幂等**——同一单号重复请求不得产生第二笔发放;须返回与首次受理一致或可识别的幂等结果(具体 HTTP 体字段由联调约定)。
- **商城**:为每笔红利/提现生成**全局唯一** `externalTransactionId`;收到 HTTP 200 且 `status="accepted"` 后**不再向发放接口重放**;对网络超时等“未知是否受理”场景,可在有限次内重试**同一** `externalTransactionId`,依赖 PlayX 幂等保证不双发(见第 6 章)。
- **playX**:对 Bonus Grant / Balance Credit 按 **`externalTransactionId` 严格幂等**——同一单号重复请求不得产生第二笔发放;须返回与首次受理一致或可识别的幂等结果(具体 HTTP 体字段由联调约定)。
- **商城**:为每笔红利/提现生成**全局唯一** `externalTransactionId`;收到 HTTP 200 且 `status="accepted"` 后**不再向发放接口重放**;对网络超时等“未知是否受理”场景,可在有限次内重试**同一** `externalTransactionId`,依赖 playX 幂等保证不双发(见第 6 章)。
## 3. 角色、系统与对象
### 3.1 角色
- **会员**:在 PlayX 内通过 Iframe 使用积分商城。
- **会员**:在 playX 内通过 Iframe 使用积分商城。
- **运营/客服**:使用商城后台管理商品、订单、调账。
- **PlayX 平台**:数据源与权益发放执行方。
- **playX 平台**:数据源与权益发放执行方。
### 3.2 主要对象与前端看板展示映射
@@ -38,13 +38,13 @@
- 前端展示专用虚拟字段由可用积分按固定比例折算10 分 = 1 元),用于给玩家呈现直观价值,非底层独立资产。
- **待领取积分 (LockedPoints)**
- **定义**:基于昨日玩家亏损转化来的“保障池”,未领取前不可消费。
- **数据源**PlayX 每日推送的 `Yesterday Player Win loss`(取绝对值 × 返还比例)。
- **数据源**playX 每日推送的 `Yesterday Player Win loss`(取绝对值 × 返还比例)。
- **可用积分 (AvailablePoints)**
- **定义**:玩家当前拥有的、可立即抵扣兑换和提现的真实积分资产。
- **交互消耗**:所有兑换、提现操作均扣减该字段。
- **今日可领取上限 (TodayLimit)**
- **定义**:限制玩家当日最多能“挽回”多少积分。
- **数据源**PlayX 每日推送的 `Yesterday Total Deposit`(昨日总充值 × 解锁比例)。
- **数据源**playX 每日推送的 `Yesterday Total Deposit`(昨日总充值 × 解锁比例)。
- **今日已领取 (TodayClaimed)**
- **定义**:记录玩家当日累计已领取的积分规模,辅助校验上限,每日重置。
- **订单 (Order)**
@@ -55,11 +55,11 @@
### 4.1 登录与会话建立
1. 会员在 PlayX 点击“积分商城”入口。
1. 会员在 playX 点击“积分商城”入口。
2. 父页面加载 Iframe商城前端进入“连接中/鉴权中”态。
3. PlayX 前端通过 postMessage 发送:
3. playX 前端通过 postMessage 发送:
- `token` 或 session 标识。
4. 商城前端将 token 传给后端,后端调用 PlayX 的 **Token Verification API** 验证身份:
4. 商城前端将 token 传给后端,后端调用 playX 的 **Token Verification API** 验证身份:
- **请求参数**
- `token`:接收到的用户会话凭证。
- `request_id`:系统发起的鉴权校验流水号。
@@ -72,11 +72,11 @@
**安全与会话续期要点**
- **安全拦截**:不信任前端传入的 `user_id`,必须通过 Token Verification API 获取可信 `user_id`
- **Token 续期**:如果用户在商城停留过久导致 Token 过期(接口返回 `401 / INVALID_TOKEN`),商城前端需通过 `postMessage` 通知 PlayX 父页面重新派发新 Token 以实现静默续期;若无法自动续期,则需弹窗引导用户重新进入商城。
- **Token 续期**:如果用户在商城停留过久导致 Token 过期(接口返回 `401 / INVALID_TOKEN`),商城前端需通过 `postMessage` 通知 playX 父页面重新派发新 Token 以实现静默续期;若无法自动续期,则需弹窗引导用户重新进入商城。
### 4.2 每日 T+1 数据推送与资产入池
数据来源:PlayX 每日 Cron。
数据来源:playX 每日 Cron。
- **交互字段说明T+1 核心输入)**
- `date`:归属业务定日(用于限定该批数据的生效周期)。
@@ -87,7 +87,7 @@
商城处理逻辑:
1.`user_id + date` 幂等入库,避免重复处理。(**注:需与 PlayX 明确 `date` 的时区定义,如 UTC+8 等**)。
1.`user_id + date` 幂等入库,避免重复处理。(**注:需与 playX 明确 `date` 的时区定义,如 UTC+8 等**)。
2. 根据业务规则计算:
- `新增保障金 = ABS(yesterday_win_loss_net) * 返还比例`(仅当 yesterday_win_loss_net < 0 时产生)。
- `今日可领取上限 = yesterday_total_deposit * 解锁比例`。**注意:今日上限每日独立计算,不结转至次日。**
@@ -95,7 +95,7 @@
**数据修正机制**
- T+1 推送不支持覆盖更新(冲正)。如果 PlayX 上游数据算错导致推送有误,商城在二次推送时会触发去重拦截(`deduped`)。此类异常数据统一由**商城后台人工调账**处理。
- T+1 推送不支持覆盖更新(冲正)。如果 playX 上游数据算错导致推送有误,商城在二次推送时会触发去重拦截(`deduped`)。此类异常数据统一由**商城后台人工调账**处理。
### 4.3 领取流程(从待挽回转化为可用)
@@ -137,18 +137,18 @@
- 商品信息 & 消耗积分
5. 原子扣减 `AvailablePoints`
6. 生成 `externalTransactionId`(例如 `BONUS_ORD{订单号}`)。
7. 调用 PlayX Bonus Grant API核心透传字段详见外部对接文档
7. 调用 playX Bonus Grant API核心透传字段详见外部对接文档
- `externalTransactionId`:本单派发流水号(**防重**:用于要求下游强制幂等拦截)。
- `user_id`:玩家标示。
- `amount`:红利发放切实的现金面值。
- `multiplier`:这笔款项后续提款的流水约束倍数。
- `rewardName`:展示给玩家此笔红利来源名称。
- `category`:便于平台统计对账的红利业务大类。
8. PlayX 返回:
8. playX 返回:
- 若 HTTP 200 且 `status = "accepted"`
- 记录 `playx_transaction_id`
- 订单保持 PENDING等待对方系统最终发放
- **发起请求动作不再重试**。但商城侧需定时调用 PlayX 提供的 **交易状态查询 API** 轮询确认该订单最终结果,成功则转 `COMPLETED`,失败则转 `REJECTED` 并退分。
- **发起请求动作不再重试**。但商城侧需定时调用 playX 提供的 **交易状态查询 API** 轮询确认该订单最终结果,成功则转 `COMPLETED`,失败则转 `REJECTED` 并退分。
- 否则:
- 记录失败原因。
- 进入“可重试队列”(自动/人工重试,见第 6 章)。
@@ -160,12 +160,12 @@
- 校验库存/积分。
- 创建 PENDING 订单,扣减 `AvailablePoints`
3. 后台处理:
- 发货:录入物流公司与单号,状态 → SHIPPED。**(可选:调用 PlayX Inbox API 给用户发送发货通知站内信)**。
- 驳回:录入驳回原因,状态 → REJECTED并退回积分。**(可选:调用 PlayX Inbox API 告知用户驳回原因)**。
- 发货:录入物流公司与单号,状态 → SHIPPED。**(可选:调用 playX Inbox API 给用户发送发货通知站内信)**。
- 驳回:录入驳回原因,状态 → REJECTED并退回积分。**(可选:调用 playX Inbox API 告知用户驳回原因)**。
### 4.6 提现回平台余额WITHDRAW 操作逻辑)
本流程旨在将兑换所得的虚拟积分,按照规定“提现”为充入 PlayX 平台账户的真实金额。
本流程旨在将兑换所得的虚拟积分,按照规定“提现”为充入 playX 平台账户的真实金额。
1. **前端选择与展示**
- 会员在首页或“提现到平台”类别列表中选择特定提现档位(如:提现 100 元,需要 1000 积分1倍流水要求
@@ -178,19 +178,19 @@
- 原子扣减数据库内该会员的 `AvailablePoints`
- 创建 WITHDRAW 暂挂订单(状态 `PENDING`),记录该单提现对应的 `amount``multiplier`
- 生成外部交易单号 `externalTransactionId`(如 `WITHDRAW_ORD{订单号}`)。
4. **调用 PlayX API 发放(核心参数解析)**
- 商城发包调用 PlayX 的 Balance Credit API
4. **调用 playX API 发放(核心参数解析)**
- 商城发包调用 playX 的 Balance Credit API
- `externalTransactionId`:本提现申请的订单号(**提现防重唯一拦截键**)。
- `user_id`:发起提现的玩家 ID。
- `amount`:要充入平台余额池的真金面值。
- `multiplier/turnover_rule`:该笔提现资金入账后锁定的打码流水倍数条件。
5. **异步等待终态与 UI 回显**
- 收到 API `accepted` 响应后,商城将不间断返回前端“提交成功,预计 10 分钟内处理”。
- 商城内部保持该订单为 PENDING并进入定时轮询状态监控 PlayX 10 分钟 Cron 执行后的“最终业务发货结果”,闭环完成后才转入 COMPLETED 或对失败按规则退分。
- 商城内部保持该订单为 PENDING并进入定时轮询状态监控 playX 10 分钟 Cron 执行后的“最终业务发货结果”,闭环完成后才转入 COMPLETED 或对失败按规则退分。
## 5. 扩展与备选方案(暂不对外)
本章为 **扩展设计/备选方案**,当前版本不对 PlayX 提出实现要求,只在内部保留。
本章为 **扩展设计/备选方案**,当前版本不对 playX 提出实现要求,只在内部保留。
### 5.1 实时充值 webhook备选
@@ -198,7 +198,7 @@
示例设计:
- PlayX 在充值成功后,调用商城的充值 webhook
- playX 在充值成功后,调用商城的充值 webhook
- 字段:`user_id``amount``transaction_id``occurred_at`
- 商城:
-`transaction_id` 幂等入库。
@@ -210,11 +210,11 @@
### 5.2 外部积分来源 webhook任务/轮盘)
用途:把 PlayX 任务、幸运轮盘等活动产出的积分汇总到商城。
用途:把 playX 任务、幸运轮盘等活动产出的积分汇总到商城。
示例设计:
- PlayX 调用 webhook
- playX 调用 webhook
- 字段:`user_id``points``source``transaction_id`
- 商城:
-`transaction_id` 幂等增加 `AvailablePoints` 或某个“活动积分池”。
@@ -235,20 +235,20 @@
**后端业务逻辑选型推荐**
- **方案 A建议商城做拉取请求**
- 会员点击同步按钮,商城后端拦截并向 PlayX 系统调用一个**“查询今日实时余额/重算存款 API”**。
- 会员点击同步按钮,商城后端拦截并向 playX 系统调用一个**“查询今日实时余额/重算存款 API”**。
- 获取到最新存款后,累加或覆盖当前的 `TodayLimit`
- **方案 BPlayX 控制权)**
- 点击后,通过 iframe 的 `postMessage` 向父级 PlayX 窗口发送同步指令。
- PlayX 在自身域内统计今日所有游戏存款流水进行汇总归集(甚至一键转账入主钱包的操作)。
- 处理完成后 PlayX 主动请求积分商城的`更新 webhook`来给 `TodayLimit` 加额,最后前端获取成功事件刷新。
- **方案 BplayX 控制权)**
- 点击后,通过 iframe 的 `postMessage` 向父级 playX 窗口发送同步指令。
- playX 在自身域内统计今日所有游戏存款流水进行汇总归集(甚至一键转账入主钱包的操作)。
- 处理完成后 playX 主动请求积分商城的`更新 webhook`来给 `TodayLimit` 加额,最后前端获取成功事件刷新。
- **当前定案落地方向**
- 根据原型要求,本功能**必须落地**。推荐使用方案 A。商城侧需准备一个接受通知的 APIPlayX 需要支持实时提供玩家当日总存款的只读 API以供点击拉取。对于 V1.0 对外文档里若不打算实现,需与 PlayX 进一步交涉决定是否阉割掉此按钮。
- 根据原型要求,本功能**必须落地**。推荐使用方案 A。商城侧需准备一个接受通知的 APIplayX 需要支持实时提供玩家当日总存款的只读 API以供点击拉取。对于 V1.0 对外文档里若不打算实现,需与 playX 进一步交涉决定是否阉割掉此按钮。
### 5.4 发放模式备选:PlayX 定时拉取
### 5.4 发放模式备选:playX 定时拉取
备选方案:
-PlayX 每 10 分钟调用商城查询接口,拉取待发放订单列表,然后自行发放。
-playX 每 10 分钟调用商城查询接口,拉取待发放订单列表,然后自行发放。
需要新增:
@@ -257,7 +257,7 @@
当前选型:
- 考虑到复杂度与 PlayX 当前发放系统形态,最终选择 **商城主动调用 PlayX 发放 API** 的模式,拉取模式仅保留在内部文档中作为备选。
- 考虑到复杂度与 playX 当前发放系统形态,最终选择 **商城主动调用 playX 发放 API** 的模式,拉取模式仅保留在内部文档中作为备选。
## 6. 幂等、重试与状态机(内部实现口径)
@@ -270,25 +270,25 @@
### 6.2 发放请求状态机(商城内部)
针对每个订单BONUS/WITHDRAW在商城内部维护推送playx状态,例如:
针对每个订单BONUS/WITHDRAW在商城内部维护推送playX状态,例如:
- `NOT_SENT`:未发送给 PlayX。
- `SENT_PENDING`:已发送,等待 PlayX 响应。
- `NOT_SENT`:未发送给 playX。
- `SENT_PENDING`:已发送,等待 playX 响应。
- `ACCEPTED`:收到 HTTP 200 且 `status = "accepted"`
- `FAILED_RETRYABLE`:失败且可重试(如超时、上游错误)。
- `FAILED_FINAL`:最终失败(达到重试上限或 PlayX 返回不可恢复错误)。
- `FAILED_FINAL`:最终失败(达到重试上限或 playX 返回不可恢复错误)。
关键规则:
- 只有在 `NOT_SENT``FAILED_RETRYABLE` 状态下才允许“再次发送”。
- 一旦进入 `ACCEPTED`,不得再发请求(自动或人工)。
- 订单业务状态PENDING/COMPLETED/REJECTED与推送playx状态之间要有清晰映射:
- 订单业务状态PENDING/COMPLETED/REJECTED与推送playX状态之间要有清晰映射:
- `ACCEPTED` + 对账确认成功 → `COMPLETED`
- `FAILED_FINAL``REJECTED`(并退积分)。
### 6.3 重试策略(内部)与防重底线
- **前提**PlayX 已承诺按 **`externalTransactionId` 严格幂等**(方案 A。在此前提下读超时后使用**同一** `externalTransactionId` 的有限次自动重试是安全的。
- **前提**playX 已承诺按 **`externalTransactionId` 严格幂等**(方案 A。在此前提下读超时后使用**同一** `externalTransactionId` 的有限次自动重试是安全的。
- 自动重试:
- 仅针对网络错误、Read Timeout读超时`PLAYX_UPSTREAM_ERROR` 等,且**尚未收到** HTTP 200 + `status="accepted"`
- 建议间隔1min / 5min / 15min最多 3 次;**每次重试必须使用原订单的同一** `externalTransactionId`,不得生成新单号冒充新单。
@@ -303,16 +303,16 @@
- 对账来源:
- 商城订单表(含 externalTransactionId、playx_transaction_id
- PlayX 提供的对账/流水查询(如有)。
- playX 提供的对账/流水查询(如有)。
- 常见问题场景:
- 商城显示 REJECTED 但会员反馈已收到红利:需检查是否在“发放后回滚积分”链路出错。
- 商城显示 PENDING 时间过长:需排查 PlayX 侧 10 分钟 Cron 是否正常。
- 商城显示 PENDING 时间过长:需排查 playX 侧 10 分钟 Cron 是否正常。
## 8. 与对外文档的关系
- 本文档:覆盖“能想到的所有对接与流程设计”,供产品、后端、运营、商务内部统一认识。
- `PlayX-对接文档(积分商城).md`
- 仅暴露 PlayX V1.0 必须提供/实现的部分。
- `playX-对接文档(积分商城).md`
- 仅暴露 playX V1.0 必须提供/实现的部分。
- 承诺最小闭环,不在主文中提及实时 webhook、同步按钮、拉取模式。
- **同步额度等能力**若产品仍要落地,以本文 **5.3** 与商务/PlayX 结论为准;对外文档不写不代表产品一定不做。
- **同步额度等能力**若产品仍要落地,以本文 **5.3** 与商务/playX 结论为准;对外文档不写不代表产品一定不做。