Create Checkout Session
Create a Stripe checkout session for initiating a subscription.
Create Checkout Session
Initiates a Stripe checkout session for subscribing to a plan.
Endpoint
POST /api/billing/checkoutAuthentication
Required. Bearer token in Authorization header.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
priceId | string | Yes | Stripe price ID for the plan |
successUrl | string | Yes | URL to redirect after successful checkout |
cancelUrl | string | Yes | URL to redirect if checkout is cancelled |
metadata | object | No | Additional metadata to attach to the session |
Example Request
curl -X POST https://api.example.com/api/billing/checkout \
-H "Authorization: Bearer <session_token>" \
-H "Content-Type: application/json" \
-d '{
"priceId": "price_1ABC123XYZ",
"successUrl": "https://app.example.com/dashboard?checkout=success",
"cancelUrl": "https://app.example.com/pricing?checkout=cancelled",
"metadata": {
"plan": "pro",
"referralCode": "FRIEND20"
}
}'TypeScript Example
const response = await fetch('/api/billing/checkout', {
method: 'POST',
headers: {
'Authorization': `Bearer ${sessionToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
priceId: 'price_1ABC123XYZ',
successUrl: `${window.location.origin}/dashboard?checkout=success`,
cancelUrl: `${window.location.origin}/pricing?checkout=cancelled`
})
});
const { data } = await response.json();
// Redirect to Stripe checkout
window.location.href = data.url;Response
Success Response (200)
{
"success": true,
"data": {
"sessionId": "cs_test_1234567890abcdef",
"url": "https://checkout.stripe.com/pay/cs_test_1234567890abcdef"
}
}| Field | Type | Description |
|---|---|---|
sessionId | string | Stripe checkout session ID |
url | string | URL to redirect the customer to |
Error Responses
Missing Price ID (400)
{
"success": false,
"error": {
"code": "BAD_REQUEST",
"message": "priceId is required"
}
}Invalid Price (400)
{
"success": false,
"error": {
"code": "BAD_REQUEST",
"message": "Invalid price ID"
}
}Unauthorized (401)
{
"success": false,
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication required"
}
}Flow Diagram
┌─────────────┐ POST /checkout ┌─────────────┐
│ Client │ ───────────────────────>│ Server │
│ │ │ │
│ │ <───────────────────────│ │
│ │ { sessionId, url } │ │
└─────────────┘ └─────────────┘
│
│ Redirect to Stripe
▼
┌─────────────┐
│ Stripe │
│ Checkout │
└─────────────┘
│
│ Return to successUrl/cancelUrl
▼
┌─────────────┐
│ Client │
│ Dashboard │
└─────────────┘Notes
- The checkout session is valid for 24 hours
- Customers without a Stripe customer ID will have one created automatically
- Metadata is passed through to the subscription for tracking
- Webhook events handle the actual subscription creation after checkout completes