先想清楚:注册码到底解决什么问题

很多独立开发者一开始只想「收钱解锁」,于是把注册码做成一串随机字符,写进数据库就算完事。真正上线后才发现问题一堆:客户换电脑了、卡密被盗用、退款怎么收回、老客户续费怎么算。

所以第一步不是写代码,而是确定规则:

  • 一张卡密只绑定一个账号;
  • 卡密有生命周期:未使用 → 已激活 → 已过期 / 已停用;
  • 每张卡密必须能追溯到具体的批次与订单。

数据模型

核心就四张表:商品、批次、卡密、订单。卡密表里保留 product_id 与 batch_id,这样无论是查库存、统计销量还是导出对账单,都能一步到位。

表 作用 关键字段
products 售卖单元 price、duration_days
batches 生成批次 product_id、count
licenses 卡密实体 code、status、expires_at
orders 交易记录 status、license_id

发放流程

用户下单后,订单处于「待支付」;管理员确认收款,系统从库存中取出一张未使用的卡密,写入用户与订单信息,同时计算到期时间。整个动作必须放在同一个事务里,避免出现「钱收了但没发卡」。

def fulfill_order(order_id):
    license_row = take_unused_license(product_id)
    activate_license(license_row, order.user_id, order.id)
    mark_order_paid(order.id, license_row.id)

容易被忽略的四个细节

  1. 库存为 0 也要能交付:允许系统兜底生成,事后补录;
  2. 停用而非删除:售后纠纷时,卡密的历史状态就是证据;
  3. 导出带 BOM 的 CSV:否则运营同学用 Excel 打开会乱码;
  4. 有效期按激活时间计算:而不是按下单时间。

写在最后

一套好的授权系统,用户几乎感知不到它的存在:付款、拿码、粘贴、激活,四步结束。把复杂度留给后台,才是产品该有的样子。