feat(server): 到账通知四接缝(邀请注册/首充/TG/购买开通)——与发放同事务零孤儿
This commit is contained in:
@@ -36,6 +36,7 @@ type WebhookHandler struct {
|
||||
nonceTTL time.Duration
|
||||
now func() time.Time // 测试注入
|
||||
rewarder Rewarder // 可选:首充邀请奖励钩子(nil 则跳过)
|
||||
noticer Noticer // 可选:购买开通到账通知钩子(nil 则跳过)
|
||||
}
|
||||
|
||||
func NewWebhookHandler(store *Store, granter Granter, db *sql.DB, rdb *redis.Client,
|
||||
@@ -52,6 +53,14 @@ type Rewarder interface {
|
||||
// SetRewarder 挂载首充邀请奖励钩子(reward.Service 满足此接口)。
|
||||
func (h *WebhookHandler) SetRewarder(r Rewarder) { h.rewarder = r }
|
||||
|
||||
// Noticer 抽象 notices.Store 的事务内插入入口(测试可替身;生产传 notices.NewStore(db))。
|
||||
type Noticer interface {
|
||||
InsertNoticeTx(ctx context.Context, tx *sql.Tx, userID int64, typ, titleZH, titleEN, bodyZH, bodyEN, link string, now time.Time) error
|
||||
}
|
||||
|
||||
// SetNoticer 挂载购买开通到账通知钩子;为 nil 时跳过(装配前兼容)。
|
||||
func (h *WebhookHandler) SetNoticer(n Noticer) { h.noticer = n }
|
||||
|
||||
// webhookEvent 对应 pay settle.go::enqueuePaymentSucceeded 的 payload
|
||||
// (注意:payment.succeeded 无 refund_id 字段)。
|
||||
type webhookEvent struct {
|
||||
@@ -186,5 +195,12 @@ func (h *WebhookHandler) settle(ctx context.Context, ev *webhookEvent) error {
|
||||
return err // 同事务:发奖失败则整笔回滚,webhook 重试
|
||||
}
|
||||
}
|
||||
if h.noticer != nil {
|
||||
zh := fmt.Sprintf("已开通 Pro · %d 天", item.Days)
|
||||
en := fmt.Sprintf("Pro activated · %d days", item.Days)
|
||||
if err := h.noticer.InsertNoticeTx(ctx, tx, userID, "reward", zh, en, "", "", "", h.now().UTC()); err != nil {
|
||||
return err // 同事务:通知插入失败则整笔回滚,webhook 重试
|
||||
}
|
||||
}
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user