1. 文档定位
本文说明 DGJ2.0 专属授信的资金池、授信活动、服务站额度、OA 审批、额度调整、采购占用/退款释放和专属返利规则。目标是让维护人员能回答:额度从哪里来、为什么某站不能申请、审批通过后为什么没有生效、采购或退款后哪一层额度应变化。
本文与《31_金融通道_银行支付与授信分期》的边界:第 31 篇负责银行和支付结果,第 32 篇负责额度来源、分配和权益约束。支付成功不代表额度计算正确,额度可用也不代表银行支付成功。
2. 业务边界
2.1 本文包含
- 资金池创建、编辑、OA 审核、生效、启停、共享和失效。
- 授信活动创建、服务站范围、额度分配、报名、OA 和启停。
- 服务站授信申请、自动申请、普通/专项调整、调增与调减。
- 外部风控剩余额度、本地已占用/待申请金额和活动剩余额度。
- 采购占用、关闭/退款释放、还款和逾期对额度的影响边界。
- 专属返利账户、允许商品、规则保存和物料导入。
- 表、状态、金额单位、排查、补偿、监控和回归。
2.2 本文不包含
- 银行注册、二维码、分期 token、还款支付和付款单落账细节,见第 31 篇。
- 普通返利、促销券和 C 端优惠券完整链路。
- 外部 OPS Manager/支付中心的额度账本物理表。
- OA 平台模板配置、审批人规则和生产组织架构。
- 真实资金清算、会计总账和银行对账。
3. 额度五层模型
| 层级 | 业务对象 | 主要限制 | 代表数据 |
|---|---|---|---|
| L1 资金池 | 某供货方/品牌的专项预算 | 总预算、供应商/快准出资、有效期 | total_quota、supplier_quota、kz_quota |
| L2 授信活动 | 从资金池划出的活动额度 | 活动总额、期限、免息、活动上限 | exclusive_id、total_quota、surplus_quota |
| L3 服务站分配 | 活动分给具体 sid 的额度 | 站点上限、活动剩余、黑名单 | relation/adjust 明细 |
| L4 外部风险额度 | 支付中心/风控认可的剩余额度 | 主体、逾期、总授信、其他占用 | availableCreditYuan 等外部返回 |
| L5 实际可用额度 | 页面和下单最终可用值 | 前四层最小值减待生效/订单占用 | Service 实时聚合 |
flowchart TD
P[资金池总预算] --> A[授信活动预算]
A --> S[服务站活动额度]
R[外部风控剩余额度] --> M{取规则允许的可用值}
S --> M
W[待审核/待生效调整] --> M
O[采购和预订单占用] --> M
M --> U[页面可申请/可支付额度]
不能只读取单一 surplus_quota 作为最终可用额度。共享资金池或不受活动上限约束时,代码会通过 CcStationAdjustSer 重新计算。
4. 参与角色
| 角色 | 动作 | 权限/上下文 | 最终责任 |
|---|---|---|---|
| OPS 授信运营 | 创建资金池、活动、站点范围和调整单 | Inspire-Api-User、组织信息 | 配置真实、额度不超预算 |
| OA 审批人 | 审核资金池、报名和调整 | OA 模板、单号 | 审批结论可追踪 |
| 服务站 | 查看活动、申请额度、采购使用 | sid、主账号、风控资格 | 资料和申请金额真实 |
| 供应商/货主 | 提供专项预算或授信 | shipper_code、协议附件 | 供货方与资金池关系正确 |
| 风控/支付中心 | 返回可用授信、处理占用/释放 | 客户编码、账单、订单 | 外部额度账本终态 |
| DGJ2 | 保存配置、发 OA、接回调、校验额度 | 本地表和业务单号 | 本地状态与外部账一致 |
5. 入口与代码地图
5.1 内部 API
主入口:application/controllers/inner/ExclusiveBaitiao.php。
| 业务组 | Controller 方法 | Service |
|---|---|---|
| 资金池 | addCashPool、getCashPool、cashPoolList、editCashPool、delCashPool | CashPoolSer |
| 资金池审批 | reviewCashPool、effectedCashPool | CashPoolSer |
| 资金池状态 | openCashPool、stopCashPool、switchShareStatus | CashPoolSer |
| 活动 | addActivity、getActivity、activityList、editActivity | ActivitySer |
| 活动状态 | openActivity、closeActivity | ActivitySer |
| 站点范围 | activityAddStations、activityAppendStations、activityGetStations、uploadExcel | ActivitySer |
| 限制名单 | addStationLimit、appendStationLimit、stationLimitList、clearStationLimitList、stationLimitUpload | ActivitySer |
| 活动报名 | addActivityApply、activityApplyList、getActivityApply、updateActivityApply、delActivityApply | ActivitySer |
| 报名审批 | reviewActivityApply | ActivitySer::submitReviewApply |
| 通用调整 | adjustCreate、adjustDetail、adjustList、submitOA、adjustExport | AdjustSer |
5.2 核心 Service
| Service | 职责 |
|---|---|
CashPoolSer | 资金池、共享额度、生效和 OA 状态 |
ActivitySer | 活动、服务站关系、报名和名单 |
StationApplySer | 服务站申请前校验、风控和可申请额 |
BaitiaoApplySer | 自动/产品授信申请单和 OA |
CcStationAdjustSer | 服务站活动额度调整、计划模板和剩余额度重算 |
AdjustSer | 通用调整单门面和 OA |
AdjustFactory | 按授信、活动、服务站三类分派 |
Adjust/BaitiaoAdjustSer | 资金池/授信总额调整 |
Adjust/ActivityAdjustSer | 活动额度调整 |
Adjust/StationAdjustSer | 服务站额度调整和自动调减 |
ExclusiveRebateSer | 专属返利账户、商品范围和规则导入 |
5.3 代表性接口请求合同
这些入口继承 BaseApiController,Controller 通过 getPageData() 读取业务参数,并从 Inspire-Api-User 或 apiUser 获得操作人。下面展示的是方法级请求体;生产网关前缀和服务间鉴权头由部署环境决定,不能仅凭仓库代码写死。
5.3.1 创建资金池 addCashPool
{
"name": "示例品牌专项资金池",
"shipper_code": "SHIPPER_CODE",
"supplier": "[{\"supplier_code\":\"SUPPLIER_CODE\",\"supplier_name\":\"示例供应商\"}]",
"brand_code": "BRAND_CODE",
"supplier_quota": "100000.00",
"kz_quota": "50000.00",
"begin_time": "2026-07-01 00:00:00",
"end_time": "2026-12-31 23:59:59",
"describe": "用于指定品牌和站点的专项授信",
"department_name": "示例部门",
"department_code": "DEPT_CODE",
"is_risk_control": 1,
"supplier_agreement_url": "脱敏后的文件标识",
"is_interest_free": 1
}
字段口径:
| 字段 | 是否必需 | Controller/Service 行为 | 重点校验 |
|---|---|---|---|
supplier | 是 | 必须是 JSON 字符串,不是直接嵌套数组 | ExclusiveBaitiaoValidate::isJson |
supplier_quota | 是 | 页面按元传入,CashPoolSer::add 保存时乘 100 | 不得为负;大于 0 时协议附件要求需一起验证 |
kz_quota | 是 | 页面按元传入,保存时乘 100 | 与供应商额度共同形成总额 |
shipper_code | 是 | Controller 会去掉首尾逗号 | 必须能映射实际货主/供应商 |
is_risk_control | 是 | 决定报名时是否查询外部风控额度 | 只能按当前枚举传值 |
is_interest_free | 是 | 决定活动利率来源 | 数字类型 |
Inspire-Api-User | 请求头 | URL decode 后取 userName 作为申请人 | 由内部网关注入,不应由普通前端任意伪造 |
成功响应由 R::success($res, '创建成功') 统一包装;失败统一进入 R::error(Code::ERROR_MISSING_PARAMS, message)。调用方不能只看 HTTP 200,必须检查统一响应中的业务码。
5.3.2 创建授信活动 addActivity
{
"exclusive_id": 10001,
"name": "示例站点授信活动",
"expire_type": 1,
"expire_time": "2026-12-31 23:59:59",
"is_interest_free": 1,
"total_quota": "20000.00",
"activity_limit": 1
}
exclusive_id 关联资金池;total_quota 按元传入、保存时转分;activity_limit 决定使用活动表内剩余额度,还是调用 CcStationAdjustSer 进行实时聚合。成功响应的业务数据为 {"id": 活动ID}。
5.3.3 指定服务站 activityAddStations
{
"post_data": "{\"activity_id\":10002,\"status\":0,\"entries\":[{\"sid\":20001,\"total_quota\":5000.00},{\"sid\":20002,\"total_quota\":3000.00}]}"
}
这里存在双层 JSON:外层字段名是 post_data,内层必须是可被 json_decode 解析的字符串。ActivitySer::addStations 会过滤 sid <= 1000 或 total_quota <= 0 的行,把有效行金额乘 100,并校验合计不能超过活动剩余额度。重新指定只允许草稿;追加入口 activityAppendStations 会跳过已存在的 sid。
5.3.4 创建活动报名 addActivityApply
{
"post_data": "{\"activity_id\":10002,\"remark\":\"示例报名\",\"entries\":[{\"sid\":20001,\"amount\":2000.00}]}"
}
Controller 解析 post_data 后,把 activity_id、remark、登录用户 apiUser.userName 和 entries 传给 ActivitySer::addApply。是否启用外部风控、明细实际额度字段及返回详情仍以 ActivitySer 当前实现和联调响应为准;调用方不能绕过 Service 在页面自行计算可申请额。
sequenceDiagram
participant O as OPS调用方
participant C as ExclusiveBaitiao
participant V as Validate
participant S as Domain Service
participant DB as 资金池/活动/关系表
participant X as OA或风控中心
O->>C: 业务参数 + 内部用户头
C->>V: 场景校验/双层JSON解析
V-->>C: 合法参数或业务错误
C->>S: 资金池/活动/站点/报名命令
S->>DB: 查询前置状态与额度
opt OA或风控场景
S->>X: 提交审批或查询外部额度
X-->>S: 外部结果
end
S->>DB: 写主表、关系表和金额状态
DB-->>C: ID或处理结果
C-->>O: R::success / R::error
6. 核心表与业务键
| 表 | 主业务键 | 作用 | 主要写入方 |
|---|---|---|---|
t_bs_exclusive_baitiao_cash_pool | id、number、oa_number | 资金池主表 | CashPoolSer |
t_bs_exclusive_baitiao_activity | id、number、exclusive_id | 授信活动 | ActivitySer |
t_bs_exclusive_baitiao_activity_relations | activity_id + sid | 活动分配到服务站 | ActivitySer |
t_bs_exclusive_baitiao_activity_apply | id、number、oa_number | 活动报名申请 | ActivitySer |
t_bs_baitiao_adjust_log | 调整单号、类型、OA | 通用额度调整记录 | AdjustSer 各实现 |
t_bs_baitiao_apply | id、申请单号、OA | 产品/自动授信申请主单 | BaitiaoApplySer |
t_bs_baitiao_apply_info | 申请主单、sid | 申请明细 | BaitiaoApplySer |
t_bs_cc_station_adjust | id、单号、OA | 服务站专项调整主单 | CcStationAdjustSer |
t_bs_cc_station_adjust_info | 调整单、sid、活动 | 调整明细 | CcStationAdjustSer |
t_bs_baitiao_station_limit | 活动/部门/站点 | 申请限制名单 | ActivitySer |
t_scm_repayment_order | bill_no、adjust_no | 授信还款映射 | 还款链 |
| 返利规则相关表 | 规则、账户、SKU | 专属返利范围 | ExclusiveRebateSer |
erDiagram
CASH_POOL ||--o{ ACTIVITY : allocates
ACTIVITY ||--o{ ACTIVITY_RELATION : assigns
ACTIVITY ||--o{ ACTIVITY_APPLY : enrolls
ACTIVITY_RELATION }o--|| STATION : belongs
ACTIVITY_APPLY ||--o{ APPLY_DETAIL : contains
CASH_POOL ||--o{ ADJUST_LOG : adjusts
ACTIVITY ||--o{ ADJUST_LOG : adjusts
STATION ||--o{ STATION_ADJUST_INFO : adjusts
STATION ||--o{ REPAYMENT_ORDER : repays
7. 金额单位
| 位置 | 输入/存储 | 单位处理 |
|---|---|---|
| 资金池 Controller | 页面 supplier_quota、kz_quota | Service 乘 100 后保存 |
| 资金池表 | 总额、剩余额度 | 分 |
| 资金池详情/列表 | 返回页面 | 多数字段除以 100 转元 |
| 活动 Controller | 页面 total_quota | Service 乘 100 |
| 活动关系 | total_quota、surplus_quota | 传入元,保存分 |
| 外部风险接口 | availableCreditYuan | 字段名明确为元 |
| 资金池生效调整 | Controller amount * 100 | Service 接收分 |
| 还款单 | amount、interest、late_fee | 分;财务落账时转元 |
金额判断前必须先画单位表。最常见错误是把外部 availableCreditYuan 与本地分字段直接比较,造成 100 倍误差。
8. 资金池字段口径
| 字段 | 含义 | 写入/计算 |
|---|---|---|
number | 专属授信预算编号 | buildNumber('ZSBT') |
shipper_code | 货主/供货方编码 | OPS 输入 |
brand_code | 品牌范围 | 逗号分隔,详情映射名称 |
supplier_quota | 供应商出资额度 | 页面元转分 |
kz_quota | 快准出资额度 | 页面元转分 |
total_quota | 资金池总额 | 初始为两类额度之和;生效时可调增/调减 |
surplus_quota | 表内剩余额度 | 非共享时直接扣活动;共享时需重算 |
is_risk_control | 是否受外部风控约束 | 决定报名是否查外部可用额度 |
is_interest_free | 是否免息 | 活动利率来源 |
begin_time/end_time | 有效期 | 过期不能生效或重新启用 |
supplier_agreement_url | 供应商协议附件 | 供应商授信大于 0 时必需 |
status/enable | 审批与启用状态 | 双字段共同判断 |
is_share_quota/batch | 共享额度组 | 多资金池合并计算 |
9. 资金池创建
sequenceDiagram
participant O as OPS
participant C as ExclusiveBaitiao Controller
participant S as CashPoolSer
participant DB as CashPoolModel
O->>C: addCashPool(货主/品牌/额度/日期/附件)
C->>C: ExclusiveBaitiaoValidate
C->>S: add(...)
S->>S: 供应商额度>0则必须有附件
S->>S: 元乘100转分
S->>S: total=供应商+快准, surplus=total
S->>DB: 新增草稿资金池
DB-->>O: 创建结果
创建前置:
shipper_code必须能映射供应商。- 时间范围合法且结束时间晚于开始时间。
- 供应商额度、快准额度均不可为负。
- 供应商额度大于零必须上传协议。
- 同一供货方、品牌和期间是否允许重复资金池,需用生产唯一规则确认。
10. 资金池状态机
| 值 | 状态 | 允许动作 |
|---|---|---|
0 | 草稿 | 编辑、删除、提交 OA |
1 | 待审核 | 等 OA 回调 |
2 | 待生效 | 人工生效 |
3 | 审核失败 | 当前代码需确认是否允许复制/重提 |
4 | 生效中 | 创建/开启活动、停用 |
5 | 已停用 | 有效期内重新启用 |
stateDiagram-v2
[*] --> 草稿
草稿 --> 待审核: submitReview
待审核 --> 待生效: reviewed(oa_number)
待审核 --> 审核失败: reviewFailed(oa_number)
待生效 --> 生效中: effect
生效中 --> 已停用: switch(5)
已停用 --> 生效中: switch(4)且未过期
草稿 --> [*]: 软删除
status 和 enable 是双重门槛。生效要求 enable == 0 且状态为待生效;切换启停又要求 enable == 1 且状态在生效/停用集合。
11. 资金池 OA 流程
CashPoolSer::submitReview 支持逗号分隔多个 ID,逐个:
- 查询资金池。
- 校验必须为草稿。
- 解析品牌名称、供货方名称和供应商 JSON。
- 调用
ExteriorProvider::oaSubmit。 - 保存 OA 返回 ID 到
oa_number。 - 状态改为待审核。
高风险窗口:OA 提交是外部调用,之后才更新本地状态。外部成功而本地更新失败时,OA 已有审批单,本地仍是草稿;直接再次提交可能重复建 OA。恢复必须先按 OA 业务内容和本地资金池编号核对。
12. 资金池生效
CashPoolSer::effect(id, type, amount, effectDesc):
type | 计算方式 |
|---|---|
0 或其他 | total = supplier_quota + kz_quota |
1 | 原 total_quota + amount |
2 | 原 total_quota - amount |
最终总额必须大于 0;生效后:
status = 4enable = 1surplus_quota = total_quota- 记录
effect_time和effect_desc
注意:生效时重置 surplus_quota。若错误地对已有占用资金池重复走生效,会覆盖剩余额度;状态校验是重要保护。
13. 共享额度
普通资金池用自身 surplus_quota;共享额度资金池按相同 batch 和 is_share_quota = 1 聚合。
flowchart LR
B[共享批次 batch] --> P1[资金池A]
B --> P2[资金池B]
B --> P3[资金池C]
P1 --> C[CcStationAdjustSer实时计算]
P2 --> C
P3 --> C
C --> S1[A可展示剩余]
C --> S2[B可展示剩余]
C --> S3[C可展示剩余]
共享切换风险:
- 共享组成员遗漏或批次错误。
- 表内
surplus_quota与实时聚合值不一致。 - 并发开启多个活动,各自都读到同一剩余值。
- 关闭活动是否释放共享池额度需要核对实际实现,不可凭状态推断。
14. 授信活动创建
ActivitySer::add 要求:
- 资金池存在。
- 资金池处于可用状态。
- 资金池未过期。
- 活动额度从页面元转分。
活动初始字段:
| 字段 | 来源 |
|---|---|
number | buildNumber('BTHD') |
exclusive_id | 所属资金池 |
expire_type | 固定日期或相对期限 |
expire_time | 固定日期转时间戳;相对期限保留数值 |
day_interest | 资金池免息则 0,否则 0.023 |
day_latefee | 0.046 |
total_quota | 页面元转分 |
surplus_quota | 初始等于活动总额 |
remaining_amount | 初始等于活动总额 |
activity_limit | 是否受活动上限约束 |
利率常量的单位和“0.023”代表百分比还是数值比例,必须以外部授信合同确认,不可自行换算。
15. 活动状态机
| 值 | 状态 | 说明 |
|---|---|---|
0 | 草稿 | 可编辑、重新指定服务站 |
1 | 开启 | 可报名/申请和使用 |
2 | 停用 | 不应新增申请 |
stateDiagram-v2
[*] --> 草稿
草稿 --> 开启: open且资金池额度足够
开启 --> 停用: close
停用 --> 开启: open的兼容行为需按代码验证
open 首次开启时在事务中扣减非共享资金池剩余额度。共享资金池不直接更新本行,而是通过聚合判断余额。
16. 活动开启扣额
sequenceDiagram
participant O as OPS
participant A as ActivitySer
participant DB as DB
participant Q as Quota Calculator
O->>A: open(activityId)
A->>DB: BEGIN并查活动/资金池
alt 共享额度
A->>Q: getCashPoolSurplusQuotaExceptBts
Q-->>A: 实时剩余
else 非共享额度
A->>DB: 读取cash_pool.surplus_quota
end
A->>A: 剩余 - 活动总额 >= 0
A->>DB: 非共享时条件更新资金池剩余
A->>DB: 活动enable=1,status=开启,effect_time
A->>DB: COMMIT/ROLLBACK
并发保护依赖条件更新:非共享分支更新条件包含原 surplus_quota,可避免部分丢失更新;共享聚合分支的并发原子性需要生产压测和索引/锁确认。
17. 服务站范围分配
ActivitySer::addStations 接收活动和 entries。每个有效 entry:
sid > 1000total_quota > 0- 元乘 100 保存
total_quota = surplus_quota
重新指定仅允许草稿;非草稿只能追加。追加时跳过已存在站点。
| 活动限制 | 额度来源 |
|---|---|
activity_limit = 1 | 使用活动表 surplus_quota |
activity_limit = 0 | 通过 getActivitySurplusQuota 实时计算 |
所有新增服务站额度之和不能超过活动可用额。
18. 名单与部门限制
授信申请限制支持:
- 单次覆盖站点名单。
- 追加站点名单。
- 查询和清空。
- Excel 导入。
- 部门/战区范围。
Excel 入口先从文件中心获取 OSS 文件地址,只允许 xls/xlsx。回归时需检查重复 SID、空行、文本数字、超大文件、跨活动覆盖和失败原子性。
19. 活动报名申请
报名主表保存 details JSON,每项通常包含服务站和额度。创建逻辑:
- 活动存在且已开启。
- 若资金池启用风控,批量调用外部接口查询各站剩余额度。
- 每个申请额度不能超过
availableCreditYuan。 - 查询该活动已有报名。
- 跳过当前编辑单和审核失败单。
- 同一
sid不能出现在另一份有效报名中。 - 生成
BM编号并保存草稿。
flowchart TD
A[提交报名明细] --> B{活动开启?}
B -- 否 --> X[拒绝]
B -- 是 --> C{资金池启用风控?}
C -- 是 --> D[批量查外部 availableCreditYuan]
D --> E{每站申请<=外部剩余?}
E -- 否 --> X
C -- 否 --> F[跳过外部上限校验]
E -- 是 --> G[查活动历史报名]
F --> G
G --> H{SID在其他有效报名中?}
H -- 是 --> X
H -- 否 --> I[生成BM草稿]
20. 报名状态机
| 值 | 状态 | 允许动作 |
|---|---|---|
0 | 草稿 | 编辑、删除、提交审核 |
1 | 审核中 | 等 OA |
2 | 审核通过 | 分配/生效额度 |
3 | 审核不通过 | 不占有效报名冲突 |
OA 模板和回调由 submitReviewApply、applyReviewed、applyReviewFailed 处理。回调必须按 oa_number 定位,重复回调应只接受与当前状态一致的结果。
21. 服务站申请前可用额
StationApplySer 同时计算:
- 外部风控额度。
- 本地已有额度。
- 活动剩余额度。
- 当前订单或预订单占用。
- 是否过期。
- 是否命中限制名单。
- 是否满足最低申请金额。
代码常量:
| 常量 | 值 | 说明 |
|---|---|---|
BT_MIN_AMOUNT | 200000 | 普通申请最低额,结合代码口径通常为分,即 2000 元 |
YUN_MIN_AMOUNT | 500000 | 运营授信最低额,通常为 5000 元 |
最终返回包含 canApply、isExpire、riskMsg、maxApplyAmount、hasAmount、actSurplusQuota、黑名单标志和本地明细。页面必须使用 Service 结论,不能自行只按最大额判断。
22. 自动/产品授信申请
BaitiaoApplyEnums:
| 值 | 状态 |
|---|---|
1 | 草稿 |
2 | 待审核 |
3 | 已生效 |
4 | 审核失败 |
5 | 已删除 |
BaitiaoApplySer 提供创建、详情、编辑、列表、删除、提交、OA 生效/驳回和导入。主单与明细表分离,适合批量服务站申请。
stateDiagram-v2
[*] --> 草稿
草稿 --> 待审核: submit
待审核 --> 已生效: effect(oaNumber)
待审核 --> 审核失败: noPass(oaNumber)
草稿 --> 已删除: delete
23. 服务站专项调整
CcAdjustEnums 状态同样为草稿、待审核、已生效、失败、删除;支持:
- 普通调整
SPEC_TYPE_NORMAL = 0 - 专项调整
SPEC_TYPE_SPEC = 1 - 来源渠道 OPS
0、APP1、DGJ2
CcStationAdjustSer 的职责包括活动列表、计划模板、创建前校验、活动/资金池剩余额度、品牌校验、创建/编辑/删除、提交 OA、特批提交、生效、驳回和创建即生效。
24. 通用调整单
BaitiaoAdjustEnums:
| 调整对象 | 值 | 实现 |
|---|---|---|
| 授信/资金池 | 1 | BaitiaoAdjustSer |
| 授信活动 | 2 | ActivityAdjustSer |
| 活动服务站 | 3 | StationAdjustSer |
| 调整方向 | 值 |
|---|---|
| 调增 | 1 |
| 调减 | 2 |
| 状态 | 值 |
|---|---|
| 待提交 OA | 0 |
| 已审核生效 | 1 |
| 审核失败 | 2 |
| 待审核 | 3 |
OA 模板:通用调整 callback_220301,授信申请 callback_22060801,服务站调整 callback_22070101,特批 callback_22072701,活动申请/换方案还有 callback_23111601/02。
25. 调整分派流程
flowchart TD
A[创建调整单] --> B{type}
B -- 1 授信 --> C[BaitiaoAdjustSer]
B -- 2 活动 --> D[ActivityAdjustSer]
B -- 3 服务站 --> E[StationAdjustSer]
C --> F[校验可调金额]
D --> F
E --> F
F --> G[保存待提交OA]
G --> H[提交OA]
H --> I{审批结果}
I -- 通过 --> J[effect并写调整后额度]
I -- 驳回 --> K[notPass不改变有效额度]
调减必须校验“可调余额”,不能把额度减到已占用金额以下。调增必须校验上级资金池/活动剩余和外部风险上限。
26. 采购占用与释放边界
专属授信参与采购时存在两套账:
- 支付中心的授信占用/账单。
- DGJ2 本地资金池、活动和服务站分配/调整数据。
sequenceDiagram
participant D as DGJ2采购
participant P as 支付中心
participant Q as 授信账本
participant L as 本地专属授信
D->>P: 用授信支付采购单
P->>Q: 预占/扣减额度
Q-->>P: 成功
P-->>D: 支付结果MQ
D->>L: 本地关联订单/活动口径
alt 订单关闭或退款
D->>P: 关闭/退款
P->>Q: 释放/返还额度
P-->>D: 退款结果
end
排查“额度没回来”要先确认采购订单是否真正关闭/退款成功,再确认支付中心是否释放,最后看本地展示缓存/聚合。直接改本地 surplus_quota 不能恢复外部授信。
27. 退款释放
PayCenterNotify::paycenterRefundResult 包含专属授信退款/额度返回分支。恢复原则:
- 以原采购单、原支付单和退款单为业务键。
- 同一退款成功事件只能释放一次。
- 部分退款按实际成功金额释放,不能按整单金额。
- 采购退货、未履约关闭和支付撤销的额度责任可能不同。
- 本地退款成功而外部额度未返还时,交由支付中心对账,禁止手改资金池代替。
28. 还款与额度
还款单和付款单记录“钱已还”,额度恢复由授信中心账本决定。正常链路:
flowchart LR
R[还款发起] --> P[支付成功]
P --> M[paycenter_baitiao_return_pay_result]
M --> F[DGJ2付款/还款单落账]
P --> C[授信中心恢复可用额度]
F --> V[本地财务可见]
C --> U[再次采购可用]
“本地还款单已成功但可用额度未增加”通常是授信账本或聚合延迟,不应重复还款。
29. 逾期与锁站
逾期会影响外部风险额度,并通过 paycenter_baitiao_service_overdue_change 控制菜单锁站:
01未锁定:解锁。02锁定中:10:00 后锁站。03延期锁定:当前代码解锁。
锁站是权限结果,不是额度字段。解锁后仍需重新查询外部风险额度,不能推断额度自动恢复。
30. 专属返利业务边界
专属返利是独立账户/权益,不是授信本金。AccountEnums::SYSTEM_EXCLUSIVE_REBATE_NUMBER = '15'。
ExclusiveRebateSer 主要能力:
| 方法 | 作用 |
|---|---|
getSumTotalAmount(sid) | 汇总站点专属返利 |
getAccountList(pageData, isEnableSearch, ruleCode) | 查询返利账户和规则 |
checkAllowSku(skuIds, sid) | 判断商品是否允许使用专属返利 |
formatMaterielList | 格式化返利物料展示 |
getMaterielList | 查询规则物料 |
saveExclusiveRebate | 保存返利规则 |
importErMateriel | 导入返利物料 |
flowchart TD
A[专属返利规则] --> B[关联账户/站点]
A --> C[允许品牌/SKU]
D[采购商品] --> E{checkAllowSku}
B --> E
C --> E
E -- 允许 --> F[支付时可选专属返利账户15]
E -- 不允许 --> G[隐藏或拒绝该支付账户]
返利可用需同时满足账户有余额、规则启用、站点匹配、商品允许和订单场景支持。
31. 返利导入风险
- SKU 文本被 Excel 转科学计数法。
- 重复 SKU、空 SKU、已停用物料。
- 导入是覆盖还是追加。
- 部分成功导致规则范围不完整。
- 导入后缓存未刷新。
- 返利规则删除后历史订单仍需保留支付快照。
32. 额度守恒关系
在单一非共享资金池、无历史迁移的理想情况下:
资金池总额 = 未分配资金池剩余 + 已开启活动分配额
活动总额 = 活动未分配剩余 + 服务站已分配额(受活动上限时)
服务站授信额 = 可用额 + 已占用/已出账未还 + 冻结/处理中金额
共享资金池、不受活动上限、外部风控和历史调整会让表字段不满足简单等式,应使用对应 Service 的实时聚合结果,并保留各组成项。
33. 异常分支矩阵
| 现象 | 第一检查 | 常见根因 |
|---|---|---|
| 资金池不能提交 OA | 状态是否草稿 | 重复提交、附件/供货方缺失 |
| OA 有单本地仍草稿 | oa_number 和提交日志 | 外部成功、本地更新失败 |
| 审批通过不能生效 | 状态、enable、结束时间 | OA 回调未落、已过期 |
| 活动不能开启 | 资金池剩余额度 | 活动超预算、共享计算差异 |
| 服务站看不到活动 | relation、状态、限制名单 | 未分配、活动关闭、部门限制 |
| 服务站申请额度为 0 | 外部风险、本地占用 | 逾期、订单占用、最小额 |
| 同一站点不能报名 | 历史有效报名 | 另一草稿/审核中申请已包含 |
| OA 通过额度未变 | 回调模板、effect 日志 | 模板路由错、状态不允许 |
| 退款后额度未恢复 | 支付中心退款终态 | 额度释放事件延迟/失败 |
| 返利不能选择 | 账户15、SKU规则 | 商品不允许、余额不足、缓存 |
34. 并发与幂等
| 场景 | 幂等键/保护 | 待确认风险 |
|---|---|---|
| 资金池提交 OA | 资金池 ID + 当前草稿状态 | 外部成功本地失败重复 OA |
| OA 回调 | oa_number + 审批结果 | 重复/乱序回调 |
| 活动开启 | 活动 ID + 当前状态;非共享条件更新余额 | 共享聚合并发超分 |
| 站点追加 | activity_id + sid | 数据库是否有唯一索引 |
| 报名 | 活动内代码查重 SID | 两请求并发穿透 |
| 调整生效 | 调整单号 + 待审核状态 | 重复 effect 双扣/双增 |
| 退款释放 | 原支付单 + 退款单 | 重复退款消息 |
| 返利导入 | 规则 + SKU | 覆盖/追加和批次原子性 |
35. 只读 SQL
35.1 资金池
SELECT id, number, shipper_code, brand_code, supplier_quota, kz_quota,
total_quota, surplus_quota, status, enable, is_share_quota,
batch, oa_number, begin_time, end_time, effect_time
FROM t_bs_exclusive_baitiao_cash_pool
WHERE id = 10001 OR number = 'ZSBT_DEMO';
35.2 活动
SELECT id, number, exclusive_id, total_quota, surplus_quota,
remaining_amount, status, enable, activity_limit,
expire_type, expire_time, day_interest, day_latefee
FROM t_bs_exclusive_baitiao_activity
WHERE id = 20001 OR exclusive_id = 10001;
35.3 服务站关系
SELECT id, activity_id, sid, total_quota, surplus_quota, create_time
FROM t_bs_exclusive_baitiao_activity_relations
WHERE activity_id = 20001 AND sid = 30001;
35.4 活动报名
SELECT id, number, activity_id, status, oa_number, create_user,
details, create_time, modify_time
FROM t_bs_exclusive_baitiao_activity_apply
WHERE activity_id = 20001
ORDER BY id DESC;
35.5 调整单
SELECT *
FROM t_bs_baitiao_adjust_log
WHERE sid = 30001
ORDER BY id DESC
LIMIT 100;
SELECT *
FROM t_bs_cc_station_adjust
WHERE id = 40001
ORDER BY id DESC;
SELECT *
FROM t_bs_cc_station_adjust_info
WHERE adjust_id = 40001 OR sid = 30001
ORDER BY id DESC;
35.6 还款结果
SELECT id, sid, bill_no, adjust_no, shipper_code,
amount, interest, late_fee, state, pay_time, create_time
FROM t_scm_repayment_order
WHERE sid = 30001
ORDER BY id DESC
LIMIT 100;
36. 排查步骤:可用额度不对
- 确认
sid、shipperCode、活动 ID 和资金池 ID。 - 查资金池状态、有效期、共享批次和总额。
- 查活动状态、上限模式、总额和剩余。
- 查服务站 relation 的分配额和剩余。
- 查报名、自动申请和调整单的草稿/审核中/生效状态。
- 查站点限制名单和部门范围。
- 调用只读外部风险查询,记录
availableCreditYuan。 - 查采购、预订单、待支付和已出账未还占用。
- 查退款/关闭是否已在支付中心终态成功。
- 使用 Service 返回的组成项重算,不直接修改任一余额字段。
flowchart TD
A[可用额度异常] --> B[资金池有效?]
B -- 否 --> X[修配置/审批/有效期]
B -- 是 --> C[活动开启且有额?]
C -- 否 --> Y[查活动扣额和共享组]
C -- 是 --> D[站点有关系且未受限?]
D -- 否 --> Z[查分配/黑名单/部门]
D -- 是 --> E[外部风险额度]
E --> F[待申请和订单占用]
F --> G[退款/还款释放]
G --> H[按Service口径重算]
37. 日志与代码定位
rg -n "addCashPool|reviewCashPool|effectedCashPool|openActivity|activityAddStations" \
application/controllers/inner/ExclusiveBaitiao.php
rg -n "function (submitReview|reviewed|reviewFailed|effect|switchShareStatus)" \
application/Services/ExclusiveBaitiao/CashPoolSer.php
rg -n "function (open|close|addStations|addApply|submitReviewApply|applyReviewed)" \
application/Services/ExclusiveBaitiao/ActivitySer.php
rg -n "getCashPoolSurplusQuota|getActivitySurplusQuota|getWaitAmount|beforeCreate|effectById" \
application/Services/ExclusiveBaitiao/CcStationAdjustSer.php
rg -n "checkAllowSku|getAccountList|saveExclusiveRebate|importErMateriel" \
application/Services/ExclusiveRebate
rg -n "paycenterRefundResult|exclusive|baitiao" \
application/controllers/tasks/PayCenterNotify.php application/controllers/tasks/OrderCenterNotify.php
38. 补偿与修复门槛
38.1 OA 外部成功、本地未更新
- 按资金池/申请/调整编号在 OA 查唯一审批单。
- 确认 OA 模板、审批状态和回调 payload。
- 确认本地仍处于回调允许的前置状态。
- 优先重放原 OA 回调,不新建审批单。
- 验证
oa_number、状态和额度只变化一次。
38.2 额度错账
- 冻结该活动新的调整和大额授信支付。
- 导出资金池、活动、站点、调整、订单和外部账本快照。
- 统一金额单位到分,建立差异表。
- 判断是展示聚合、外部账本还是本地有效额度错误。
- 由业务、财务和授信 Owner 审批修复方案。
- 修复后验收资金守恒、站点可用额和历史单据不变。
38.3 禁止动作
- 直接把
surplus_quota改成期望值而不核对上级和外部账本。 - 为了让页面可用直接把状态改为生效。
- OA 回调失败后重新建一张 OA 单。
- 删除有效调整单或历史报名。
- 通过修改返利 SKU 规则影响已支付历史订单。
39. 监控建议
| 指标 | 维度 | 告警条件 |
|---|---|---|
| OA 待审核时长 | 模板、单据类型 | 超 SLA |
| OA 已通过未生效 | 资金池/活动/调整 | 数量非零 |
| 资金池负剩余 | 共享批次、供货方 | 任一小于 0 |
| 活动分配超总额 | 活动 | 差额大于 0 |
| 站点重复有效报名 | 活动、sid | 数量大于 1 |
| 外部可用与本地展示差异 | sid、供货方 | 超容忍阈值 |
| 退款成功未释放额度 | 退款单 | 超 SLA |
| 已还款可用额未恢复 | 还款单 | 超 SLA |
| 调整重复生效 | 调整单 | 生效记录大于 1 |
| 返利规则无效 SKU | 规则 | 数量非零 |
40. 回归清单:资金池
- [ ] 供应商额度为 0/正数和附件必填。
- [ ] 元转分精度、超大金额和负数拒绝。
- [ ] 草稿编辑、删除和非草稿保护。
- [ ] 单笔/批量提交 OA。
- [ ] OA 通过、驳回、重复和乱序回调。
- [ ] 调增、调减、重置生效三种类型。
- [ ] 总额不能小于等于 0。
- [ ] 生效、停用、未过期重启、过期禁止重启。
- [ ] 共享批次创建、加入、退出和余额展示。
- [ ] 并发开启活动不超分。
41. 回归清单:活动与站点
- [ ] 仅有效资金池可创建活动。
- [ ] 固定日期和相对期限。
- [ ] 免息与日利率映射。
- [ ] 活动首次开启扣资金池额度。
- [ ] 共享/非共享扣额差异。
- [ ] 草稿重新指定站点、开启后仅追加。
- [ ] 重复 SID 跳过或明确报错。
- [ ] 服务站分配总额不超活动。
- [ ] 受活动上限和不受上限两种模式。
- [ ] 关闭后是否释放额度按当前实现验证。
- [ ] 限制名单覆盖、追加、清空和 Excel 导入。
42. 回归清单:申请与调整
- [ ] 风控开启/关闭两种报名。
- [ ] 外部可用额度为空、低于申请额和刚好相等。
- [ ] 同站点重复报名并发。
- [ ] 草稿编辑删除、审核失败后重新申请。
- [ ] 普通申请最低 2000 元边界。
- [ ] 运营申请最低 5000 元边界。
- [ ] 产品申请主明细一致。
- [ ] 授信、活动、服务站三类调增调减。
- [ ] 调减不低于已占用。
- [ ] 普通、特批和创建即生效。
- [ ] OPS、APP、DGJ 三来源渠道。
- [ ] 调整 OA 重复回调不重复变额。
43. 回归清单:支付、退款与返利
- [ ] 专属授信采购支付成功与失败。
- [ ] 待支付取消释放预占。
- [ ] 整单关闭、部分关闭和采购退货。
- [ ] 全额/部分退款只释放实际成功金额。
- [ ] 退款成功消息重复投递。
- [ ] 主动/自动还款后外部额度恢复。
- [ ] 本地还款成功但外部额度延迟。
- [ ] 逾期锁站、延期和解锁后额度重新查询。
- [ ] 专属返利账户余额。
- [ ] 允许/不允许 SKU、品牌和规则状态。
- [ ] 返利导入覆盖/追加、失败原子性和缓存刷新。
- [ ] 授信与专属返利混合支付金额守恒。
44. 改动风险
| 级别 | 文件/行为 | 回归要求 |
|---|---|---|
| P0 | CashPoolSer::effect/open、共享额度计算 | 全资金池、并发活动、守恒 |
| P0 | CcStationAdjustSer、三类调整 effect | 调增调减、重复 OA、占用保护 |
| P0 | 支付/退款回调的额度释放 | 重复、部分退款、乱序、外部对账 |
| P1 | 活动站点、报名和限制名单 | 全活动可见性和申请额 |
| P1 | 金额字段、元分转换、最低额 | 全额度边界 |
| P1 | 专属返利 SKU 规则 | 账户、商品、混合支付和历史兼容 |
| P2 | 列表筛选、名称映射和导出 | 页面与导出一致性 |
45. 已确认与待确认
45.1 已从代码确认
- 资金池、活动、报名和调整状态枚举。
- 资金池编号
ZSBT、活动编号BTHD、报名编号BM。 - 资金池和活动金额从页面元乘 100 保存。
- 供应商授信大于 0 时要求协议附件。
- 资金池 OA 提交后保存
oa_number。 - 生效支持原额、调增和调减,且重置剩余额度。
- 活动利率从资金池免息配置派生。
- 非共享活动开启在事务中条件扣减资金池余额。
- 共享额度通过 batch 和计算 Service 聚合。
- 活动站点分配和报名均校验额度。
- 风控开启时查询外部
availableCreditYuan。 - 同一站点不能出现在同活动其他有效报名中。
- 三类调整由 Factory 分派。
- 专属返利账户编码为
15。
45.2 待外部/环境确认
- 生产表 DDL、唯一索引和并发锁。
- OA 模板真实路由、回调重试和签名。
- 共享额度组的完整业务规则和退出策略。
- 活动关闭是否应释放资金池额度。
- 外部风控额度的组成、冻结和刷新 SLA。
- 利率常量的正式比例单位和计息规则。
- 支付中心额度占用/释放的消息合同和幂等键。
- 专属返利物理表、缓存 key 和导入原子性。
- 历史迁移数据是否满足额度守恒。
46. 证据来源
application/controllers/inner/ExclusiveBaitiao.phpapplication/Services/ExclusiveBaitiao/CashPoolSer.phpapplication/Services/ExclusiveBaitiao/ActivitySer.phpapplication/Services/ExclusiveBaitiao/StationApplySer.phpapplication/Services/ExclusiveBaitiao/BaitiaoApplySer.phpapplication/Services/ExclusiveBaitiao/CcStationAdjustSer.phpapplication/Services/ExclusiveBaitiao/AdjustSer.phpapplication/Services/ExclusiveBaitiao/Adjust/*application/Services/ExclusiveRebate/ExclusiveRebateSer.phpapplication/controllers/tasks/Baitiao.phpapplication/controllers/tasks/PayCenterNotify.phpapplication/controllers/tasks/OrderCenterNotify.phpapplication/KzData/Enums/ExclusiveBaitiaoEnums.phpapplication/KzData/Enums/BaitiaoAdjustEnums.phpapplication/KzData/Enums/BaitiaoApplyEnums.phpapplication/KzData/Enums/CcAdjustEnums.phpapplication/KzData/Enums/AccountEnums.phpapplication/config/tables.php
47. 一页式交接结论
- 专属授信可用额由资金池、活动、服务站、外部风控和订单占用共同决定。
- 本地额度多存分,页面和外部
availableCreditYuan用元,比较前必须统一单位。 - 资金池状态是草稿、待审、待生效、生效、停用;审批通过不等于自动生效。
- 活动开启才真正占用非共享资金池预算。
- 共享额度不能直接信单行
surplus_quota,要走聚合 Service。 - 同活动同站点只能有一份有效报名,但并发唯一性仍需数据库确认。
- 调整分授信、活动、服务站三层,调减不能侵入已占用额度。
- 支付、退款和还款的真实额度变化在外部授信账本,本地改字段不能代替。
- 专属返利是账户
15和 SKU 规则,不是授信本金。 - 任何额度修复都要导出上下级、本地订单和外部账本,按原业务单号验收守恒。
请求-日志-数据变更追踪卡
多入口请求链路
| 场景 | 调用方与入口 | 请求载荷/上下文 | Controller/Consumer | Service/Provider | 汇合点 | 最终业务事实 |
|---|---|---|---|---|---|---|
| 站点申请 | /inner/ExclusiveBaitiao | 站点、上级、申请类型、金额、资料 | Inner Controller | StationApplySer/BaitiaoApplySer | apply ID | 专属授信申请及审批状态 |
| 资金池/活动 | OPS/内部接口 | 资金池、活动、参与站点、额度 | ExclusiveBaitiao Controller | CashPoolSer/ActivitySer | pool/activity ID | 资金池总额与站点分配关系 |
| 额度调整/返利 | OPS/任务 | 站点、调整类型、原业务单、金额 | Controller/tasks/Baitiao | Adjust/ExclusiveRebate Service | adjust/rebate ID | 可用/冻结/已用额度与返利变化 |
| 支付/订单回调 | PayCenter/OrderCenter MQ | 支付/关闭/退款事件、来源单 | PayCenterNotify/OrderCenterNotify | 专属授信 Service | original order/pay ID | 占额转已用或关闭退款释放 |
日志证据矩阵
| 链路段 | 日志来源 | 可检索锚点 | 成功信号 | 失败信号 | 与下一段关联方式 | | --- | --- | --- | --- | --- | --- | --- | | 申请配置 | Inner/Service | request_id、站点、apply/pool/activity ID | 申请/配置 commit | 上下级关系、金额门槛、重复配置失败 | ID 查本地申请/资金池 | | 额度调整 | Adjust/Rebate Service | adjust/rebate ID、原业务单、站点、金额 | 调整流水一次写入 | 重复增减、余额不足、上下级不守恒 | 原业务单查额度流水 | | 支付关闭 | Pay/Order Consumer | message ID、pay/order ID、事件 | 状态与额度同步且 ACK | 回调乱序、已关后支付、重复释放 | 原订单关联占用/释放记录 | | 外部账本 | Provider/任务 | 外部 request/ledger ID、站点 | 本地与外部余额一致 | 一边成功一边失败 | ledger ID + 原业务单双向对账 |
环节数据变更台账
| 步骤 | 代码位置 | 事务 | 读取事实 | 写入表/缓存/MQ | 字段或数量变化 | 回查证据 |
|---|---|---|---|---|---|---|
| 建资金池/申请 | CashPool/Activity/Apply Service | 配置事务 | 上级、站点、总额、门槛 | 资金池/活动/申请/关系表 | total/allocated/available 初始化;status pending | pool/apply ID、上下级关系 |
| 审批分配 | Apply/Adjust Service | 额度事务 | 池可分配额、申请额 | 额度账户/调整流水 | pool available -n;station available +n;申请 approved | 调整 ID、双方前后余额 |
| 下单占额 | Baitiao Service | 订单事务/外部边界 | station available、订单金额 | 占额/订单关系、外部账本 | available -n、frozen +n | 原订单、额度流水 |
| 支付/完成 | PayCenterNotify | 回调事务 | frozen、支付成功 | 额度账户/流水 | frozen -n、used +n;支付一次 | payOrderNo、三类余额守恒 |
| 关闭退款返利 | OrderCenter/Refund/Rebate Service | 回调事务 | 原占额/已用/已返金额 | 调整/返利流水、外部账本 | frozen/used -n、available/rebate +n,不超过原额 | 原业务单、正反流水、上下级/外部余额 |
子模块追踪:exclusive-pool 专属授信资金池
| 环节 | 入口/触发 | 请求/业务键 | 代码链路 | 读取事实 | 写入与字段变化 | 日志证据 | 异常与补偿 |
|---|---|---|---|---|---|---|---|
| 建/调资金池 | 上级创建或调整池总额 | pool ID、owner、total、adjust ID | application/Services/ExclusiveBaitiao/CashPoolSer.php | 上级账户、原 total/allocated/available 和重复调整 | 额度本地事务 total/available old -> old +/- n,写调整流水 | request ID + pool/adjust ID + before/after | 不得小于已分配;重复调整键 0 增量 |
| 池对账 | 池余额或上下级不平 | pool ID、all allocations | application/KzData/Enums/ExclusiveBaitiaoEnums.php | total、allocated、available、子级余额和流水 | 查询只读;total=allocated+available | pool + adjustment/allocation IDs | 禁止只改汇总余额;通过反向调整补偿 |
子模块追踪:exclusive-activity 专属授信活动
| 环节 | 入口/触发 | 请求/业务键 | 代码链路 | 读取事实 | 写入与字段变化 | 日志证据 | 异常与补偿 |
|---|---|---|---|---|---|---|---|
| 配置活动 | 新建/启停授信活动 | activity ID、pool、time/rules | application/Services/ExclusiveBaitiao/ActivitySer.php | 资金池、活动冲突、门槛和原状态 | 配置本地事务 draft/disabled old -> enabled/new | request ID + activity/pool + status | 时间/池冲突零写入;停用不抹历史申请 |
| 资格查询 | 站点查看可申请活动 | sid、activity ID、time | application/Services/ExclusiveBaitiao/ActivitySer.php | 活动态、范围、站点资格和剩余额度 | 查询只读 不写 | request ID + sid/activity + eligibility | 页面可见不等于审批通过;提交时重验 |
子模块追踪:exclusive-station-apply 服务站授信申请
| 环节 | 入口/触发 | 请求/业务键 | 代码链路 | 读取事实 | 写入与字段变化 | 日志证据 | 异常与补偿 |
|---|---|---|---|---|---|---|---|
| 提交申请 | 服务站申请活动额度 | sid、activity/pool、apply ID、amount | application/Services/ExclusiveBaitiao/StationApplySer.php | 站点资格、活动、已有申请和池可分配额 | 申请本地事务 insert,status none -> pending | request ID + sid/apply/activity + amount | 重复站点活动键不重复申请;超额零写入 |
| 申请回查 | 提交后状态/金额异常 | apply ID、sid | application/KzData/Enums/BaitiaoApplyEnums.php | 申请、活动、池关系和审核记录 | 查询只读 不写 | apply + sid + status/history | 主单无关系按领域取消/重建,不手补额度 |
子模块追踪:exclusive-approve 申请审批与额度分配
| 环节 | 入口/触发 | 请求/业务键 | 代码链路 | 读取事实 | 写入与字段变化 | 日志证据 | 异常与补偿 |
|---|---|---|---|---|---|---|---|
| 审批分配 | 上级同意/拒绝站点申请 | apply ID、action、approved amount | application/Services/ExclusiveBaitiao/BaitiaoApplySer.php | pending、池 available、申请额和站点账户 | 额度本地事务通过时 pool available -n, station available +n、status approved;拒绝到 rejected | request ID + apply/adjust IDs + both balances | 并发用条件更新;任一余额/流水失败整事务回滚 |
| 审批回查 | 状态通过但额度未到 | apply/adjust ID、pool/station | application/Services/ExclusiveBaitiao/CcStationAdjustSer.php | 申请、双边账户和调整流水 | 查询只读;三方金额应一致 | apply + ledger/adjust + before/after | 已有流水只补状态;无流水重走幂等调整 Service |
子模块追踪:exclusive-order-hold 订单占额与冻结
| 环节 | 入口/触发 | 请求/业务键 | 代码链路 | 读取事实 | 写入与字段变化 | 日志证据 | 异常与补偿 |
|---|---|---|---|---|---|---|---|
| 下单占额 | 订单选择专属授信 | sourceOrderNo、sid、amount、hold ID | application/Services/ExclusiveBaitiao/BaitiaoApplySer.php | station available、订单状态和已有占额 | 订单/额度本地事务 available -n, frozen +n,写订单关系 | request ID + source/hold ID + balances | 额度不足/重复来源零写入;订单创建失败整事务释放 |
| 取消释放 | 未支付订单关闭/超时 | sourceOrderNo、hold ID、close fact | application/controllers/tasks/OrderCenterNotify.php | frozen、支付最终态和已释放流水 | 回调本地事务 frozen -n, available +n,重复 0 变化 | message ID + source/hold + ledger | 支付不确定不释放;迟到支付进入专项补偿 |
子模块追踪:exclusive-pay 支付后冻结转已用
| 环节 | 入口/触发 | 请求/业务键 | 代码链路 | 读取事实 | 写入与字段变化 | 日志证据 | 异常与补偿 |
|---|---|---|---|---|---|---|---|
| 支付转换 | 支付中心成功回调 | message ID、pay/source order、hold ID | application/controllers/tasks/PayCenterNotify.php | payStatus=02、frozen、已有支付和额度流水 | 回调本地事务 frozen -n, used +n,payment/order 到 confirmed | message ID + pay/source/hold + before/after | 重复 0 增量;额度转化失败只补额度段,不重扣款 |
| 余额守恒 | 支付后账户不平 | account/pool、ledger IDs | application/Services/ExclusiveBaitiao/CashPoolSer.php | total、available、frozen、used 和所有流水 | 查询只读;余额分类和等式守恒 | account/pool + ledger IDs | 禁止直改 used/frozen;用原支付键幂等补偿 |
子模块追踪:exclusive-adjust 上下级额度调整
| 环节 | 入口/触发 | 请求/业务键 | 代码链路 | 读取事实 | 写入与字段变化 | 日志证据 | 异常与补偿 |
|---|---|---|---|---|---|---|---|
| 上下调额 | 上级给站点增减额度 | adjust ID、parent/child、direction、amount | application/Services/ExclusiveBaitiao/AdjustSer.php、application/Services/ExclusiveBaitiao/CcStationAdjustSer.php | 双边 available/allocated、冻结/已用和限制 | 同一本地额度事务双边 old -> new 并写一组调整流水 | request ID + adjust + both accounts/balances | 减额不得侵占 frozen/used;双边任一失败整事务回滚 |
| 调整回调 | 外部账本确认调整 | message ID、external/local adjust ID | application/controllers/tasks/Baitiao.php | 本地 pending 调整、外部终态和幂等键 | 回调本地事务 pending -> success/failed,金额不再重复变化 | message ID + both adjust IDs | 外部成功本地缺失按 adjust ID 补;不生成新调整 |
子模块追踪:exclusive-refund-rebate 退款、返利与额度返还
| 环节 | 入口/触发 | 请求/业务键 | 代码链路 | 读取事实 | 写入与字段变化 | 日志证据 | 异常与补偿 |
|---|---|---|---|---|---|---|---|
| 退款返额 | 原订单退款/关闭 | source/pay/refundNo、used/frozen、amount | application/controllers/tasks/PayCenterNotify.php | 原占额/支付、已退已返和外部终态 | 反向额度本地事务 used/frozen -n, available +n,不超过原额 | message ID + original/refund + ledger | 重复退款 0 增量;先核资金退款再按合同返额 |
| 返利入账 | 专属返利任务/回调 | rebate ID、source order、station/pool | application/Services/ExclusiveRebate/ExclusiveRebateSer.php | 返利资格、已返金额、上下级关系和外部账本 | 返利本地事务 rebate/available old -> old+n,写唯一流水 | request/task + rebate/source + balances | 退款与返利规则分别计算;重复来源键不重复入账 |