Payment security and repeat safety
Protects payment operations with server-owned amounts, verified events and deduplication across uncertain retries.
payment-security-idempotency
See how it helpsWhen 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.
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
