Stripe Integration
Accept credit cards, Apple Pay, Google Pay, and 40+ payment methods globally using Stripe as your payment provider.Prerequisites
Before you begin, make sure you have:- A Stripe account — sign up at stripe.com if you don’t have one
- Your Stripe API keys from the Stripe Dashboard
- A working Headless Commerce store with at least one product
Use test mode keys (
sk_test_... / pk_test_...) during development. Switch to live keys only when you’re ready to accept real payments.Environment Variables
Add the following environment variables to your API server:Checkout Flow
The complete Stripe checkout flow involves four steps: creating a cart, initiating checkout, confirming payment on the client, and handling the webhook confirmation.Call the checkout endpoint with
payment_method: 'stripe'. The API creates a Stripe PaymentIntent and returns a client_secret:import { loadStripe } from '@stripe/stripe-js';
const stripe = await loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY!);
const { error } = await stripe!.confirmPayment({
clientSecret: client_secret,
confirmParams: {
return_url: 'https://your-store.com/order/confirmation',
},
});
if (error) {
// Show error to the customer (e.g., insufficient funds, card declined)
console.error(error.message);
} else {
// Payment is processing — Stripe will redirect to return_url
}
import { useStripe, useElements, PaymentElement } from '@stripe/react-stripe-js';
function CheckoutForm({ clientSecret }: { clientSecret: string }) {
const stripe = useStripe();
const elements = useElements();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!stripe || !elements) return;
const { error } = await stripe.confirmPayment({
elements,
confirmParams: {
return_url: 'https://your-store.com/order/confirmation',
},
});
if (error) {
console.error(error.message);
}
};
return (
<form onSubmit={handleSubmit}>
<PaymentElement />
<button type="submit" disabled={!stripe}>
Pay now
</button>
</form>
);
}
Once the customer completes payment, Stripe sends a webhook event to your server. Headless Commerce processes this automatically and updates the order status to
confirmed.Webhook Setup
Headless Commerce listens for Stripe webhook events to keep order and payment statuses in sync. Configure webhooks in the Stripe Dashboard:- Go to Developers → Webhooks in the Stripe Dashboard
- Click Add endpoint
- Enter your webhook URL:
https://api.headlesscommerce.io/v1/webhooks/stripe - Select the following events:
payment_intent.succeededpayment_intent.payment_failedcharge.refundedcharge.dispute.created
- Copy the Signing secret and set it as
STRIPE_WEBHOOK_SECRET
Event handling
| Stripe Event | Headless Commerce Action |
|---|---|
payment_intent.succeeded | Order status set to confirmed, payment marked completed |
payment_intent.payment_failed | Payment marked failed, payment.failed webhook sent |
charge.refunded | Refund recorded, payment.refunded webhook sent |
charge.dispute.created | Order flagged for review |
Refunds
Issue full or partial refunds through the Admin API:Testing
Test mode keys
Always use test mode API keys during development. These keys create test-only transactions that never hit real payment networks.| Key type | Prefix | Example |
|---|---|---|
| Publishable key | pk_test_ | pk_test_51ABC... |
| Secret key | sk_test_ | sk_test_51ABC... |
Test card numbers
Use these card numbers in test mode:| Card Number | Scenario |
|---|---|
4242 4242 4242 4242 | Successful payment |
4000 0000 0000 3220 | 3D Secure authentication required |
4000 0000 0000 9995 | Payment declined (insufficient funds) |
4000 0000 0000 0002 | Generic card decline |
Testing webhooks locally
Use the Stripe CLI to forward webhook events to your local development server:Error Handling
Handle payment errors gracefully in your frontend:confirmPayment():
| Error Code | Description | Suggested Action |
|---|---|---|
card_declined | The card was declined | Ask customer to use a different card |
expired_card | The card has expired | Ask customer to update card details |
insufficient_funds | Insufficient funds | Ask customer to use a different card |
processing_error | Processing error at Stripe | Retry the payment |
incorrect_cvc | Incorrect CVC | Ask customer to re-enter CVC |
Next Steps
Webhooks
Learn about all webhook events and payload formats.
TossPayments
Set up TossPayments for Korean payment methods.
API Reference
Explore all checkout and payment endpoints.
SDKs
Full SDK reference with every resource and method.