文档目录
钱包系统表

简介

本文件面向支付系统开发者与财务人员,系统化梳理 DouPHP 钱包系统的数据库表结构设计,重点围绕以下目标展开:

  • 钱包主表 dou_money 与资金流水表 dou_money_log(以 money 表为核心)的字段设计、约束与索引策略。
  • 余额管理、充值套餐、交易记录、冻结解冻、资金限额、交易安全等能力的数据模型支撑。
  • 钱包与订单、提现、分销等模块的关联关系与资金流转路径。
  • 基于代码与 SQL 的实际实现,给出可落地的数据建模参考与最佳实践。

项目结构与范围

  • 钱包核心表定义来源于模块级备份脚本与系统表结构导出,确保与实际部署一致。
  • 钱包业务逻辑由 WalletService 统一封装,提供带行锁的余额写入与校验。
  • 订单支付通过 PaymentService 接入钱包“余额支付”腿,保证幂等与事务一致性。
  • 提现流程通过 WithdrawService 调用钱包扣款,并维护提现单状态机。
graph TB
A["用户/商户"] --> B["订单模块"]
A --> C["钱包模块"]
A --> D["提现模块"]
B --> E["支付网关层"]
E --> F["钱包余额支付腿"]
F --> G["钱包流水表(money)"]
D --> G
B --> H["订单支付记录表(order_payment)"]

核心数据模型

本节聚焦钱包主表与流水表的字段设计与用途说明,并结合实际 SQL 与模型映射进行解释。

钱包流水表(dou_money)

  • 作用:记录每一笔余额变动,包含变动金额、变动后余额、价格快照、来源单号、来源用户、业务来源类型与ID等,用于对账、审计与报表。
  • 关键字段要点:
    • user_id:账户主体(会员ID)。
    • operator_type/operator_id:操作者类型与ID(admin/user/work/system),便于区分人工、系统或业务方操作。
    • action:动作标识(如充值、消费、退款、奖励等),配合筛选查询。
    • money:本次变动金额(可为负数表示扣减)。
    • total:变动后的余额快照,便于快速读取最新余额。
    • price/sale_price/sale_price_type:价格快照,用于对账与追溯。
    • item_id/from/from_user_id:关联的业务对象与来源用户。
    • source_type/source_id:业务来源类型与ID(如 order_pay/order_refund/recharge/withdraw),用于跨模块溯源。
    • remark/ip/created_at:备注、IP、时间戳。
  • 索引策略:
    • 按 operator_type/operator_id 索引,支持运营侧批量处理。
    • 按 source_type/source_id 索引,支持按业务单号反查流水。
    • 按 user_id/action 索引,支持用户维度与动作维度的统计与过滤。
    • from_user_id 索引,支持分销返利等来源用户维度统计。

充值套餐表(dou_money_package)

  • 作用:配置充值套餐,包括充值金额、售价、等级价、促销价、有效期、图片与排序等。
  • 关键字段要点:
    • name/money/price:套餐名称、充值金额、售价。
    • level_price/promote_price/promote_start_at/promote_end_at:等级价与促销价及有效期。
    • brief/image/sort:简介、图片、排序。

订单支付记录表(dou_order_payment)

  • 作用:记录各支付渠道的支付流水,包括支付网关、金额、状态、第三方交易号、凭证、原始报文、过期时间等。
  • 与钱包的关系:当使用余额支付时,会生成 gateway='wallet' 的成功支付记录,并与钱包流水对应。

提现表(withdraw)

  • 作用:记录用户提现申请与处理状态,支持字符串化状态机(pending/approved/paid/rejected)。
  • 与钱包的关系:提交提现申请时会调用钱包扣款,生成负向流水;后续打款完成更新状态。

架构总览

钱包系统通过统一的 WalletService 提供余额写入与校验,结合 PaymentService 将余额作为支付渠道之一,形成“订单-支付-钱包-流水”的闭环。提现流程则通过 WithdrawService 触发钱包扣款并维护提现单状态。

sequenceDiagram
participant U as "用户"
participant O as "订单模块"
participant P as "支付服务(PaymentService)"
participant W as "钱包服务(WalletService)"
participant DB as "数据库"
U->>O : 下单并选择余额支付
O->>P : 发起余额支付
P->>DB : 开启事务
P->>W : 扣款(createMoney, FOR UPDATE)
W->>DB : 计算total并校验>=0
W-->>P : 返回成功/失败
alt 成功
P->>DB : 写入order_payment(gateway=wallet)
P->>DB : 累计订单已付金额
P->>DB : 推进订单状态
P->>DB : 提交事务
P-->>O : 支付成功
else 失败
P->>DB : 回滚事务
P-->>O : 支付失败
end

详细组件分析

钱包流水写入(createMoney)

  • 行为:在事务内对当前用户最新余额行加 FOR UPDATE 锁,计算新余额并校验非负,随后插入流水行。
  • 安全性:避免并发超扣;若余额不足直接返回失败,不产生流水。
  • 扩展性:通过 source_type/source_id 与 from_user_id 支持多业务场景(订单、退款、充值、提现、分销奖励等)。
flowchart TD
Start(["开始"]) --> Lock["锁定用户最新余额行(FOR UPDATE)"]
Lock --> Calc["计算新余额 = 旧余额 + 变动金额"]
Calc --> Check{"余额 >= 0 ?"}
Check -- 否 --> Fail["返回失败(余额不足)"]
Check -- 是 --> Insert["插入流水行(money)"]
Insert --> End(["结束"])

订单余额支付(markSucceededByWallet)

  • 行为:在同一事务中完成余额扣款、写入支付记录、累计订单已付金额、尝试推进订单收尾。
  • 幂等:同一订单已有成功钱包腿则不重复扣款。
  • 容差:使用金额比较容差避免 decimal 浮点误差导致判定异常。

余额支付回调(balancepay)

  • 行为:校验订单状态与金额合法性,调用 create_money 扣款,设置支付方式为 balancepay,切换订单状态为已付款。
  • 安全:CSRF 校验、订单归属校验、状态前置检查。

提现申请与扣款

  • 行为:创建提现单后调用钱包扣款,生成负向流水;后续审核打款更新提现单状态。
  • 状态机:历史 tinyint 状态迁移为字符串化状态(pending/approved/paid/rejected)。

充值套餐与展示

  • 行为:后台维护充值套餐,前端展示套餐列表与价格信息,支持等级价与促销价。
  • 模型:MoneyPackage 提供排序、批量赋值白名单与图片附件解析。

依赖关系分析

钱包模块与订单、提现、分销等模块存在紧密耦合:

  • 订单模块:通过 PaymentService 调用钱包扣款,并在 order_payment 表记录支付腿。
  • 提现模块:通过 WithdrawService 调用钱包扣款,维护 withdraw 表状态。
  • 分销模块:通过 money 表的 action(如 direct_reward/indirect_reward)与 from_user_id 追踪推广收益。
graph LR
Order["订单模块"] --> Pay["支付服务"]
Pay --> Wallet["钱包服务"]
Wallet --> Money["钱包流水表(money)"]
Withdraw["提现模块"] --> Wallet
Distribution["分销模块"] --> Money

性能与并发特性

  • 行锁防并发超扣:createMoney 使用 FOR UPDATE 锁定用户最新余额行,确保并发安全。
  • 事务内一致性:余额扣款、支付记录写入、订单累计在同一事务中完成,避免部分成功。
  • 索引优化:
    • money 表按 user_id/action、source_type/source_id、operator_type/operator_id 建立索引,提升查询与统计效率。
    • order_payment 表按 status/gateway/add_time 等组合索引,支持超时清理与对账查询。
  • 金额容差:PaymentService 使用 AMOUNT_EPSILON 避免 decimal 精度问题导致的边界判断错误。

故障排查指南

  • 余额不足:
    • 现象:createMoney 返回失败,未写入流水。
    • 排查:检查 user_id 是否正确、action 是否为预期、money 正负是否合理、是否存在并发竞争。
  • 重复扣款:
    • 现象:同一订单多次扣款。
    • 排查:确认 markSucceededByWallet 的幂等逻辑是否生效,检查 order_payment 是否已有 gateway='wallet' 的成功记录。
  • 提现失败:
    • 现象:提现申请后无扣款或状态异常。
    • 排查:核对 WithdrawService 扣款调用、withdraw 状态迁移脚本执行结果、钱包开关 features.money 是否启用。
  • 对账不一致:
    • 现象:order_amount 与 wallet_paid 不一致。
    • 排查:检查 PaymentService 的事务完整性、order_payment 记录、money 流水是否与订单号关联。

结论

DouPHP 钱包系统以 money 表为核心,通过 WalletService 提供安全的余额写入与校验,结合 PaymentService 与 WithdrawService 实现订单余额支付与提现扣款的完整闭环。表结构设计兼顾了可追溯性(source_type/source_id)、可审计性(operator_type/operator_id)与高性能查询(多维索引)。建议在扩展新功能时遵循现有模式,保持事务一致性与幂等性,确保财务数据的准确性与安全性。

附录:字段字典与索引建议

  • dou_money(钱包流水)
    • 关键字段:user_id、operator_type、operator_id、action、money、total、price、sale_price、sale_price_type、item_id、from、from_user_id、source_type、source_id、remark、ip、created_at。
    • 索引:idx_operator(operator_type, operator_id)、idx_source(source_type, source_id)、idx_user(user_id, action)、idx_from_user(from_user_id)。
  • dou_money_package(充值套餐)
    • 关键字段:name、money、price、level_price、promote_price、promote_start_at、promote_end_at、brief、image、sort。
  • dou_order_payment(订单支付记录)
    • 关键字段:payment_sn、order_id、order_sn、gateway、amount、status、transaction_id、pay_evidence、raw_request、raw_callback、paid_at、expired_at、add_time。
  • withdraw(提现单)
    • 关键字段:withdraw_sn、user_id、money、card_number、card_bank、card_name、card_status、status、handle_record、handled_at、created_at。
添加日期:2026-10-05