mirror of
https://github.com/marcusDenslow/terminalShop.git
synced 2026-10-25 10:02:21 +01:00
fix(cards): dedupe saved cards via local-db last4+brand+exp match in checkout.sessions.completed webhook
This commit is contained in:
@@ -228,27 +228,24 @@ func (h *WebhookHandler) handleCheckoutSessionCompleted(ctx context.Context, eve
|
||||
return
|
||||
}
|
||||
|
||||
// Fingerprint deduplication. if the customer already has another card
|
||||
// with the same fingerprint (same underlying card re-tokenized), detatch
|
||||
// the new pm and skip the local insert. Mirrors SaveCards check.
|
||||
if pm.Card != nil && pm.Card.Fingerprint != "" {
|
||||
listParams := &stripe.PaymentMethodListParams{
|
||||
Customer: stripe.String(user.StripeCustomerID),
|
||||
Type: stripe.String("card"),
|
||||
}
|
||||
iter := paymentmethod.List(listParams)
|
||||
for iter.Next() {
|
||||
other := iter.PaymentMethod()
|
||||
if other.ID == pm.ID || other.Card == nil {
|
||||
continue
|
||||
}
|
||||
if other.Card.Fingerprint == pm.Card.Fingerprint {
|
||||
if _, err := paymentmethod.Detach(pm.ID, nil); err != nil {
|
||||
webhookLog().Warn("failed to detach duplicate pm", "user_id", user.ID, "error", err)
|
||||
}
|
||||
webhookLog().Info("skipped duplicate card via fingerprint", "user_id", user.ID, "fingerprint", pm.Card.Fingerprint)
|
||||
return
|
||||
// dedup against local cards table, matching last4 + brand + expiry means
|
||||
// the user is re-adding the same physical card. detach the new pm from
|
||||
// stripe and skip the local insert. Local DB is the source of truth
|
||||
// the stripe customers paymentmethods list may contain orphans from before
|
||||
// this fix, which would cause false-positive dedup hits
|
||||
if pm.Card != nil {
|
||||
var dup models.Card
|
||||
err := db.Where(
|
||||
"user_id = ? AND last4 = ? AND brand = ? AND exp_month = ? AND exp_year = ?",
|
||||
user.ID, pm.Card.Last4, string(pm.Card.Brand),
|
||||
int(pm.Card.ExpMonth), int(pm.Card.ExpYear),
|
||||
).First(&dup).Error
|
||||
if err == nil {
|
||||
if _, derr := paymentmethod.Detach(pm.ID, nil); derr != nil {
|
||||
webhookLog().Warn("failed to detach duplicate pm", "user_id", user.ID, "error", derr)
|
||||
}
|
||||
webhookLog().Info("skipped duplicate card via local-db match", "user_id", user.ID, "existing_card_id", dup.ID)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user