Balance 服务

充值单与流水

充值不是直接改余额,而是先创建充值单,再在确认到账时真正入账。

@downcity/services 里,充值和流水是分开的。

为什么不能把“用户点充值”直接等同于“余额到账”

因为这两件事常常不是同一步:

  • 用户先发起充值
  • 之后可能由 admin 确认
  • 或者由 Stripe webhook / 自定义支付回调确认
  • 最后才真正入账

所以更稳定的模型是:

  • createTopup():创建待处理充值单
  • finishTopup():确认到账并真正加余额
  • cancelTopup():取消未完成充值单

用户侧怎么发起充值

const topup = await user.service("balance").action("topups/create").invoke({
  amount: 500,
  note: "manual recharge",
});

这一步返回的是 pending 充值单,不会立刻改余额。

管理侧怎么确认到账

await admin.service("balance").action("topups/finish").invoke({
  topup_id: topup.topup_id,
});

确认时服务会做两件事:

  • 把充值单标记为 paid
  • 给用户余额增加对应金额

同时还会写一条 topup 流水。

流水里记录什么

最常见的流水类型有:

  • init
  • add
  • sub
  • topup

这让你可以快速回答:

  • 余额最开始从哪来
  • 是系统赠送、手动加款还是业务扣费
  • 某笔充值什么时候到账

用户侧常用入口

  • GET /v1/balance/me
  • GET /v1/balance/history/me
  • GET /v1/balance/topups/me
  • POST /v1/balance/topups/create
  • POST /v1/balance/redeem-codes/redeem

管理侧常用入口

  • GET /v1/balance/users
  • GET /v1/balance/history
  • GET /v1/balance/topups
  • GET /v1/balance/redeem-codes
  • POST /v1/balance/add
  • POST /v1/balance/sub
  • POST /v1/balance/topups/finish
  • POST /v1/balance/topups/cancel
  • POST /v1/balance/redeem-codes/create
  • POST /v1/balance/redeem-codes/disable