feat(pay-v2): P8 Task4 续费入账 invoice.paid→renewal order + subscription.renewed
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
|
||||
"github.com/wangjia/pay/internal/model"
|
||||
)
|
||||
@@ -65,6 +66,35 @@ func (s *OrderStore) MarkAttemptPaid(outTradeNo, channel, providerRef string, at
|
||||
return flipped, nil
|
||||
}
|
||||
|
||||
// CreateRenewalPaid 幂等建一张已付 renewal order + attempt(续费不经收银台,建即 paid)。
|
||||
// 重复(invoice 重投)→ created=false。renewal order/attempt 均带唯一约束,ON CONFLICT DO NOTHING。
|
||||
func (s *OrderStore) CreateRenewalPaid(order *model.OrderV2, att *model.Attempt) (bool, error) {
|
||||
var created bool
|
||||
err := s.db.Transaction(func(tx *gorm.DB) error {
|
||||
ores := tx.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "out_trade_no"}}, DoNothing: true,
|
||||
}).Create(order)
|
||||
if ores.Error != nil {
|
||||
return ores.Error
|
||||
}
|
||||
if ores.RowsAffected == 0 {
|
||||
return nil // 已建过 → 幂等 no-op
|
||||
}
|
||||
ares := tx.Clauses(clause.OnConflict{
|
||||
Columns: []clause.Column{{Name: "channel"}, {Name: "provider_ref"}}, DoNothing: true,
|
||||
}).Create(att)
|
||||
if ares.Error != nil {
|
||||
return ares.Error
|
||||
}
|
||||
created = ares.RowsAffected > 0
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("store.CreateRenewalPaid: %w", err)
|
||||
}
|
||||
return created, nil
|
||||
}
|
||||
|
||||
func (s *OrderStore) CancelOrder(outTradeNo string) (bool, error) {
|
||||
res := s.db.Model(&model.OrderV2{}).
|
||||
Where("out_trade_no = ? AND status = ?", outTradeNo, model.OrderPendingV2).
|
||||
|
||||
Reference in New Issue
Block a user