Production checklist

Stripe production checklist: 7 checks before launch

7 checks for running Stripe in production: 2 must-dos, 3 should-dos and 2 good-to-haves. Each one says why it matters, how to verify it and where the docs are.

Updated . Every check links the vendor’s own docs.

Check my repo

Must do (2)

  • Verify webhook signatures

    Without the signature check anyone can POST a fake "payment succeeded" event to your endpoint.

    Verify from the command line

    Send your webhook endpoint a request without a valid Stripe-Signature header; it must be rejected (400). Then use the Stripe CLI to send a real signed event and check it’s accepted.

    curl -i -X POST https://<your-app>/api/webhooks/stripe -H "Content-Type: application/json" -d '{"type":"checkout.session.completed"}'
    stripe listen --forward-to localhost:3000/api/webhooks/stripe
    stripe trigger payment_intent.succeeded

    Read more on docs.stripe.com

  • Set prices and amounts on the server, never from the client

    A tampered request can otherwise buy anything at any price. Send product or price ids from the browser and look the amount up on your server.

    Check the code

    Your checkout endpoint takes product or price ids from the browser and builds line items from Price ids on the server. A pass: no amount or price is read from the request body.

    line_items: [{ price: '<price_id>', quantity: 1 }]

    Read more on docs.stripe.com

Should do (3)

  • Send idempotency keys on create requests

    A retried request after a timeout otherwise charges the customer twice.

    Check the code

    Every create call passes an idempotency key derived from your own record (order or cart id), so a retry can’t charge twice.

    await stripe.paymentIntents.create(params, { idempotencyKey: `order-${order.id}` });

    Read more on docs.stripe.com

  • Handle duplicate and out-of-order webhook events

    Stripe delivers at least once; record processed event ids and don’t assume ordering.

    Verify from the command line

    Resend an event that was already processed. Your handler should recognise its id (stored in a processed-events table) and do nothing the second time.

    stripe events resend <evt_id>

    Read more on docs.stripe.com

  • Collect card details with Stripe Checkout or Elements, not your own form

    Card numbers then never touch your servers, which keeps your PCI DSS scope as small as it gets.

    Verify from the command line

    Search your frontend for your own card inputs; a pass finds none, because payment forms use Stripe Checkout or the Payment Element.

    grep -rniE "card.?number|cvc|cvv" --include=*.tsx --include=*.jsx --exclude-dir=node_modules .

    Read more on docs.stripe.com

Good to have (2)

  • Use restricted API keys per service

    Limits the blast radius if one key leaks.

    How to verify

    In the Stripe Dashboard under Developers → API keys, each service should use its own restricted key (rk_live_…) with only the permissions it needs, and the full secret key shouldn’t be deployed where it isn’t needed.

    Read more on docs.stripe.com

  • Work through Stripe’s go-live checklist

    Covers live keys, webhooks in live mode, receipts, statement descriptors and handling failed payments before real money moves.

    How to verify

    Tick off each item on the checklist before switching to live keys, then make one real low-value payment and refund it.

    Read more on docs.stripe.com

Get the checklist for your whole stack

Design your stack or map your repo in StackPrism, and the Improve panel lists the checks for every technology on it and keeps track of what you’ve done. Building with an AI app builder? Start with the vibe coding checklist.