Idempotency keys are used on all state-changing charge requests
Why it matters
Without idempotency keys, a network timeout on a charge request leaves your app in an ambiguous state: the payment may or may not have succeeded, and a retry creates a second charge for the same order. This is a real operational failure — customers who retry a checkout after a timeout get double-charged, support costs spike, and refund rates increase. CWE-362 (Race Condition) captures the concurrent-retry scenario that idempotency keys prevent. Beyond customer impact, double charges on high-volume stores compound into significant financial reconciliation problems. An idempotency key ensures that Stripe treats any retry of the same logical transaction as a no-op, returning the original result instead of creating a new charge.
Severity rationale
High because missing idempotency keys on charge calls make double-charging customers a near-certainty under any network instability or client retry logic.
Remediation
Generate a unique idempotency key per logical transaction and pass it to every state-changing Stripe call. Derive it from your order ID for natural retry deduplication.
// app/api/create-payment-intent/route.ts
import { v4 as uuidv4 } from 'uuid'
// Stable key: reusing orderId means retries hit the same PaymentIntent
const idempotencyKey = `pi-${orderId}`
const paymentIntent = await stripe.paymentIntents.create(
{
amount: amountInCents,
currency: 'usd',
customer: stripeCustomerId,
},
{ idempotencyKey }
)
Apply the same pattern to stripe.refunds.create() and any other state-changing call. Store the idempotency key alongside the order record so that application-level retries always reuse the same key.
DetectionPro
The detection method for this pattern is part of AuditBuffet Pro.
The full method (what to look for, pass and fail conditions, and how results get reported) ships inside the Payment Security Audit. The pattern definition, severity rationale, and remediation remain openly licensed under CC-BY-4.0.
External references
- cwe · CWE-362 — Concurrent Execution Using Shared Resource with Improper Synchronization (Race Condition)
- iso-25010:2011 · reliability.fault-tolerance
Taxons
History
- 2026-04-18·v1.0.0·Initial import from ecommerce-payment-security·automated