Skip to main content
礼品卡是除订阅和充值之外的第三条积分入口:买家付现金 → 支付成功后系统生成卡密 → 收卡人兑换 → 积分落进收卡人的个人积分账户

卡密长什么样

16 位十六进制字符,按 4 位分组:
兑换时输入不区分大小写,中间的连字符和空格会被自动清理——直接粘贴 a1b2c3d4e5f67890 也能识别。

两种拿到积分的方式

/redeem 页面输入卡密。系统先做一次预览(面额、状态、有效期、赠送人),确认后兑换。
1

打开兑换页

账单页面的「兑换礼品卡」入口,或直接访问 /redeem
2

输入卡密并预览

输入后能看到这张卡的面额、当前状态和有效期,确认是你要兑换的那张。
3

确认兑换

积分即时到账,同时在积分流水里生成一条 GIFT_CARD_REDEEM 记录。

卡密状态机

冻结与作废的差别就在可逆性:冻结是「先按住,可能还会放开」,作废是「这张卡不存在了」。已兑换的卡不能作废——积分已经发出去了,作废它只会让账对不上。

有效期

注意起算点:卡在支付成功的那一刻就开始计时。一张放了 80 天才转手的卡,收卡人只剩 10 天。 过期扫描每 5 分钟跑一次,所以「刚过期的卡」可能短暂还显示 unused——但兑换时会当场校验时间并标记过期,不会真的兑换成功。

每人限领(claimPerUser)

批次可以配置每个用户最多领几张,默认 1 张。这个限制在批次创建时冻结,之后不可改。 限领的判定用 PostgreSQL advisory lock 按 (批次号, 用户 ID) 串行化——这一点值得说明:Read Committed 隔离级别下两个并发请求会同时读到「已领 0 张」然后都放行,加锁才能保证计数是对已提交状态的计数。所以同时点两次领取按钮不会拿到两张。 输入卡密兑换和批次链接领取共用同一把锁、同一个计数,不存在「从链接领一张、再手输一张卡密」绕过限额。

购买

超过 3 笔待支付订单会被拒绝(GIFT_CARD_TOO_MANY_PENDING),先把旧订单付掉或让它过期。 买了 N 张就生成 N 张独立卡密,同属一个批次号。买家在「我的礼品卡」里能看到自己名下的卡:5 张及以上按批次聚合展示,不足 5 张展开成单卡列表——这条阈值在服务端,避免一次买 1000 张时把千行数据推给浏览器。 管理员赠送批次单批上限默认 1000 张(可由运营配置调整)。

失败与对策

兑换是幂等的:同一张卡的兑换请求重复到达时,系统靠积分流水的业务键识别出「这张卡已经给这个人加过分了」,直接返回成功而不会重复加分。

兑换的积分怎么算

礼品卡积分入账为 BONUS(赠送) 类型,业务类型 GIFT_CARD_REDEEM。入账后与其它赠送积分完全同质,遵循统一的消耗优先级和过期规则。
团队用户注意:礼品卡兑换的积分始终进入你的个人积分账户,不进团队积分池,不受当前计费主体设置影响。想给团队充值请走团队池充值,不要用礼品卡。

常见问题

不支持退款——代码里没有礼品卡退款路径。未兑换的卡密可以转赠他人,这是唯一的「反悔」方式。
从卡生成时算起(购买卡是支付成功那一刻,赠送批次是管理员发放那一刻),不是从你收到或领取时算起。
可以,链接本身不含身份信息。但每个领取的人都要登录,且受每人限领约束,所以转发到群里就是先到先得。
能。兑换预览和批次领取页都会显示买家名称。
账单页的积分流水里有 GIFT_CARD_REDEEM 记录,含兑换时间和积分数量;「兑换记录」列表按时间列出你兑换过的所有卡。

继续阅读

积分体系

六类积分的消耗优先级与过期规则

积分充值

直接充值与赠送比例

错误码

GIFT_CARD_* 全部错误码

团队计费

团队池与个人账户的分界