Skip to main content

Set Up Card Payments

Configure keys, create a Checkout session, and verify webhooks.

C
Written by Catalin Fetean
Updated over 3 weeks ago

Audience: Developers, Finance Admins
Outcomes: Cards are enabled; webhooks verified; receipts flow into orders

Configure environment

STRIPE_SECRET_KEY=sk_live_xxx STRIPE_WEBHOOK_SECRET=whsec_xxx

Option A — Payment Intent (server‑controlled)

curl -X POST $API_BASE/api/payments/intents -b cookies.txt \ -H 'Content-Type: application/json' \ -d '{"orderId":"ord_123","amount":150000,"currency":"USD"}'

Use this when you want maximum control over the flow.

Option B — Hosted Checkout (fast)

curl -X POST $API_BASE/api/payments/stripe/checkout-session -b cookies.txt \ -H 'Content-Type: application/json' \ -d '{ "orderId":"ord_123", "amount":150000, "currency":"USD", "successUrl":"https://app.example.com/success", "cancelUrl":"https://app.example.com/cancel" }' # → returns { "url": "https://checkout.stripe.com/c/..." }

Webhook (Express)

app.post('/api/webhooks/stripe', express.raw({ type: 'application/json' }), (req, res) => { try { const event = stripe.webhooks.constructEvent( req.body, req.header('Stripe-Signature'), process.env.STRIPE_WEBHOOK_SECRET! ); handleStripeEvent(event); // mark order DepositPaid, refunds, etc. res.json({ received: true }); } catch (err) { res.status(400).send('Signature verification failed'); } });

3DS/SCA

  • Handled by Intents/Checkout. Ensure your UI shows the challenge modal when required.

Local testing

stripe listen --forward-to localhost:3000/api/webhooks/stripe

Idempotency & metadata

  • Send a stable reference with your requests.

  • Attach orderId in provider metadata for easy reconciliation.

Did this answer your question?