Payment security and repeat safety
Protects payment operations with server-owned amounts, verified events and deduplication across uncertain retries.
payment-security-idempotency
Team members using this skill
When is it useful?
Use when checkout or webhook retries could charge or fulfill twice.
What does it help you do?
- Calculates authoritative prices and ownership on the server.
- Uses stable operation keys and verifies provider signatures.
- Separates event acknowledgement from reliable processing without storing raw card data.
Try asking this
Test a timeout after payment submission and a duplicate webhook; fulfill once after confirming provider outcome. Alter the browser-supplied price and repeat the original payment identity. The server must retain authoritative pricing and one confirmed fulfillment despite repeated notifications.
Detailed documentation
Read the skill’s original instructions, examples and checks in their authored language.
Show less
Payment Security & Idempotency
Financial integrations operate across unreliable networks and untrusted client browsers. Every payment flow must guarantee that clients cannot tamper with prices, duplicate network requests never double-charge, and forged or replayed webhooks are rejected.
1. Server-Side Authority (Zero Client Trust)
- Never accept price, currency, discount, tax rate or entitlement flags from the client: the client sends only a
planId/priceKey, quantity, and optional coupon code. The server resolves the authoritative price, currency, eligibility and tax rules from trusted server config or the provider catalog. - Return URLs are UI hints, never proof of payment: a user reaching
/checkout/success?session_id=...does not prove payment succeeded (URLs can be visited directly, and async methods like SEPA or wire transfer may still beprocessing). Provision entitlements only after verifying server-to-server provider state or receiving a verified webhook. - Bind checkout sessions to the authenticated tenant/user: store internal
userId/workspaceId/orderIdin provider metadata or a server-side checkout record and verify ownership before fulfilling.
2. Outbound Idempotency (Preventing Double Charges)
When calling a provider API to create a charge, payment intent, subscription, refund or invoice, a network timeout leaves the outcome unknown:
- Deterministic Idempotency Keys: generate and persist a stable idempotency key tied to the business operation (
idempotency_key = "charge:${orderId}:attempt:${attemptNo}"or"invoice:${paymentId}") before making the HTTP call. - Safe retry rule: if a request times out or returns
5xx/429, retry with the exact same idempotency key (or query the provider by external reference ID first). Never generate a fresh random UUID on retry — that causes a second charge! - Never auto-failover and re-charge on a second PSP when the first PSP returned an ambiguous timeout without first reconciling whether the first charge settled.
3. Webhook Verification & Inbound Deduplication
Every incoming provider webhook must pass three gates before mutating domain state:
- Cryptographic Signature Verification:
- Read the raw, unparsed request body bytes (do not let JSON middleware re-serialize the payload before checking the HMAC/signature).
- Verify the provider signature header (
Stripe-Signature, PayPal transmission signature, Barion/SimplePay HMAC, Paddle/Lemon Squeezy HMAC) and enforce timestamp tolerance against replays.
- Idempotent Event Deduplication:
- Store the provider's unique
event_idinprocessed_webhook_eventswith aUNIQUE(provider, event_id)constraint. - Process and mark completed atomically (or lock rows by state) so concurrent duplicate deliveries never execute side effects twice.
- Store the provider's unique
- Fast Acknowledgement & Reliable Processing:
- Persist the verified event and acknowledge
2xxwithin the provider's timeout window; if downstream fulfillment (such as PDF invoice generation or email delivery) fails, retry that step independently without losing the payment record.
- Persist the verified event and acknowledge
4. PCI DSS & Secret Hygiene
- Never touch, log or store raw PAN (card numbers), CVV/CVC or magnetic stripe data; use provider-hosted checkout or tokenized payment elements exclusively.
- Redact API secret keys, webhook signing secrets, client tokens and personal billing addresses from application logs and error trackers.
- Separate sandbox/test credentials and webhook endpoints strictly from live production credentials.
Included files 1
SKILL.md
