Create a Stripe Checkout session to redirect users to Stripe’s hosted checkout page. Supports both subscription and one-time payment modes.
Authentication
This endpoint requires end user authentication via HTTP Bearer Token with project scope.
Query Parameters
Use test mode credentials. Set to false for production payments.
Request Body
Stripe Price ID for the product or subscription (e.g., price_1ABC...)
URL to redirect after successful payment. Include {CHECKOUT_SESSION_ID} placeholder.
URL to redirect if user cancels checkout
mode
string
default:"subscription"
Checkout mode: subscription or payment (one-time)
Quantity of items (minimum: 1)
Additional metadata to attach to the checkout session
allow_existing_subscription
If true, allows checkout even if user already has an active subscription
Response
Stripe Checkout Session ID
URL to redirect user to Stripe Checkout
Example Request
curl -X POST "https://api.devkit4ai.com/api/v1/payments/stripe/checkout-session?test_mode=true" \
-H "Authorization: Bearer {end_user_jwt}" \
-H "Content-Type: application/json" \
-d '{
"price_id": "price_1ABC123def456",
"success_url": "https://myapp.com/success?session_id={CHECKOUT_SESSION_ID}",
"cancel_url": "https://myapp.com/pricing",
"mode": "subscription"
}'
Example Response
{
"session_id": "cs_test_a1b2c3d4e5f6g7h8i9j0",
"checkout_url": "https://checkout.stripe.com/c/pay/cs_test_a1b2c3d4e5f6g7h8i9j0"
}
Checkout Flow
Integration Example
Frontend (React)
// Pricing button component
const SubscribeButton = ({ priceId }: { priceId: string }) => {
const handleSubscribe = async () => {
const response = await fetch('/api/checkout', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
price_id: priceId,
success_url: `${window.location.origin}/success?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `${window.location.origin}/pricing`
})
});
const { checkout_url } = await response.json();
window.location.href = checkout_url;
};
return <button onClick={handleSubscribe}>Subscribe</button>;
};
Backend (Next.js API Route)
// app/api/checkout/route.ts
export async function POST(request: Request) {
const body = await request.json();
const response = await fetch(
`${process.env.NEXT_PUBLIC_API_URL}/api/v1/payments/stripe/checkout-session?test_mode=${process.env.STRIPE_TEST_MODE}`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${getUserToken()}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(body)
}
);
return Response.json(await response.json());
}
Existing Subscription Handling
By default, users with active subscriptions cannot start a new checkout:
Set allow_existing_subscription: true for upgrade/downgrade flows, or use the Update Subscription endpoint instead.
Price IDs
Get Price IDs from your Stripe Dashboard:
- Navigate to Products > Pricing
- Click on a price to view its ID
(((REPLACE_THIS_WITH_IMAGE: stripe-dashboard-price-id.png: Stripe Dashboard showing a product’s pricing section with Price ID visible)))
Error Responses
| Status | Description |
|---|
400 | User already has active subscription (when allow_existing_subscription: false) |
401 | Unauthorized - Invalid or missing authentication |
404 | Project not found or Stripe not configured |
422 | Validation error - Invalid price_id or URLs |
Related Pages
The access token received from the authorization server in the OAuth 2.0 flow.
Use test mode credentials
Request to create a Stripe checkout session.
mode
string
default:subscription
Pattern: ^(subscription|payment)$
allow_existing_subscription
If true, allows checkout even if user has active subscription
Stripe checkout session response.