钱包与礼品卡
dujiao-shop 用户体系自带钱包余额 + **礼品卡(充值码)**机制。
钱包
每个注册用户都有一个钱包,字段:
| 字段 | 类型 | 说明 |
|---|---|---|
balance | decimal(20,2) | 当前余额 |
total_recharged | decimal(20,2) | 累计充值金额 |
total_spent | decimal(20,2) | 累计消费金额 |
后台:会员管理 → 用户详情 → 钱包 → 可查流水。
充值方式
1. 直接充值
用户前台个人中心 → 钱包 → 充值 → 选金额 + 支付通道 → 跳转支付 → 到账。 跟商品下单走同一套订单流程,订单类型为 recharge。
2. 礼品卡兑换
发行批量充值码给用户兑换。后台:优惠券与礼品卡 → 礼品卡 → 新建批次:
| 字段 | 说明 |
|---|---|
| 批次名 | 2026-Q1-vip |
| 面额 | 单张面值,如 ¥100 |
| 数量 | 生成多少张 |
| 有效期 | 不填 = 永久;否则到期后兑换提示已过期 |
| 限会员等级 | 仅 ≥ X 级会员可兑换 |
兑换码 16 位 base32,长这样:GC-J3KX7HP9MZ4VPQ8R。
用户兑换:个人中心 → 礼品卡 → 输入码 → 面额加到钱包。一码只能兑一次,数据库强制 unique。
用余额支付
结账页 → 支付方式选 "钱包余额"。条件:
- 余额 ≥ 订单总额
- 未达到 / 不需要支付通道路由
支付时事务里扣余额 + 写消费流水,失败回滚。
退款时钱包流转
- 订单全额退款 → 余额加回
- 部分退款 → 仅退实退金额
- 礼品卡充的钱退款 → 一样退到余额(不退回原礼品卡)
排查
| 现象 | 排查 |
|---|---|
| 兑换码提示"无效" | 后台批次列表看是否真的存在 / 是否已被使用 / 是否过期 |
| 充值成功但余额没增加 | 看 wallet_recharge_orders 表 status;如果 paid 但 balance 未更新 → 后台手动触发"重新结算" |
| 用余额下单失败"余额不足" | 后台用户钱包页面看实际余额(可能跟前端显示有延迟) |
SQL 速查
sql
-- 看某用户的钱包流水
SELECT created_at, type, amount, balance_after, note
FROM wallet_transactions
WHERE user_id = 42
ORDER BY id DESC LIMIT 30;
-- 批量礼品卡未兑换数
SELECT batch_id, count(*) FROM gift_cards WHERE used_at IS NULL GROUP BY batch_id;