Create Checkout Session
curl --request POST \
--url https://api.devkit4ai.com/api/v1/payments/stripe/checkout-session \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"price_id": "<string>",
"success_url": "<string>",
"cancel_url": "<string>",
"mode": "subscription",
"quantity": 1,
"metadata": {},
"allow_existing_subscription": false
}
'import requests
url = "https://api.devkit4ai.com/api/v1/payments/stripe/checkout-session"
payload = {
"price_id": "<string>",
"success_url": "<string>",
"cancel_url": "<string>",
"mode": "subscription",
"quantity": 1,
"metadata": {},
"allow_existing_subscription": False
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
price_id: '<string>',
success_url: '<string>',
cancel_url: '<string>',
mode: 'subscription',
quantity: 1,
metadata: {},
allow_existing_subscription: false
})
};
fetch('https://api.devkit4ai.com/api/v1/payments/stripe/checkout-session', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.devkit4ai.com/api/v1/payments/stripe/checkout-session",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'price_id' => '<string>',
'success_url' => '<string>',
'cancel_url' => '<string>',
'mode' => 'subscription',
'quantity' => 1,
'metadata' => [
],
'allow_existing_subscription' => false
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.devkit4ai.com/api/v1/payments/stripe/checkout-session"
payload := strings.NewReader("{\n \"price_id\": \"<string>\",\n \"success_url\": \"<string>\",\n \"cancel_url\": \"<string>\",\n \"mode\": \"subscription\",\n \"quantity\": 1,\n \"metadata\": {},\n \"allow_existing_subscription\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.devkit4ai.com/api/v1/payments/stripe/checkout-session")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"price_id\": \"<string>\",\n \"success_url\": \"<string>\",\n \"cancel_url\": \"<string>\",\n \"mode\": \"subscription\",\n \"quantity\": 1,\n \"metadata\": {},\n \"allow_existing_subscription\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.devkit4ai.com/api/v1/payments/stripe/checkout-session")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"price_id\": \"<string>\",\n \"success_url\": \"<string>\",\n \"cancel_url\": \"<string>\",\n \"mode\": \"subscription\",\n \"quantity\": 1,\n \"metadata\": {},\n \"allow_existing_subscription\": false\n}"
response = http.request(request)
puts response.read_body{
"session_id": "<string>",
"checkout_url": "<string>"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Stripe Checkout
Create Checkout Session
Create a Stripe checkout session for subscription or one-time payment
POST
/
api
/
v1
/
payments
/
stripe
/
checkout-session
Create Checkout Session
curl --request POST \
--url https://api.devkit4ai.com/api/v1/payments/stripe/checkout-session \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"price_id": "<string>",
"success_url": "<string>",
"cancel_url": "<string>",
"mode": "subscription",
"quantity": 1,
"metadata": {},
"allow_existing_subscription": false
}
'import requests
url = "https://api.devkit4ai.com/api/v1/payments/stripe/checkout-session"
payload = {
"price_id": "<string>",
"success_url": "<string>",
"cancel_url": "<string>",
"mode": "subscription",
"quantity": 1,
"metadata": {},
"allow_existing_subscription": False
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
price_id: '<string>',
success_url: '<string>',
cancel_url: '<string>',
mode: 'subscription',
quantity: 1,
metadata: {},
allow_existing_subscription: false
})
};
fetch('https://api.devkit4ai.com/api/v1/payments/stripe/checkout-session', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.devkit4ai.com/api/v1/payments/stripe/checkout-session",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'price_id' => '<string>',
'success_url' => '<string>',
'cancel_url' => '<string>',
'mode' => 'subscription',
'quantity' => 1,
'metadata' => [
],
'allow_existing_subscription' => false
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.devkit4ai.com/api/v1/payments/stripe/checkout-session"
payload := strings.NewReader("{\n \"price_id\": \"<string>\",\n \"success_url\": \"<string>\",\n \"cancel_url\": \"<string>\",\n \"mode\": \"subscription\",\n \"quantity\": 1,\n \"metadata\": {},\n \"allow_existing_subscription\": false\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.devkit4ai.com/api/v1/payments/stripe/checkout-session")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"price_id\": \"<string>\",\n \"success_url\": \"<string>\",\n \"cancel_url\": \"<string>\",\n \"mode\": \"subscription\",\n \"quantity\": 1,\n \"metadata\": {},\n \"allow_existing_subscription\": false\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.devkit4ai.com/api/v1/payments/stripe/checkout-session")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"price_id\": \"<string>\",\n \"success_url\": \"<string>\",\n \"cancel_url\": \"<string>\",\n \"mode\": \"subscription\",\n \"quantity\": 1,\n \"metadata\": {},\n \"allow_existing_subscription\": false\n}"
response = http.request(request)
puts response.read_body{
"session_id": "<string>",
"checkout_url": "<string>"
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}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
boolean
default:"true"
Use test mode credentials. Set to
false for production payments.Request Body
string
required
Stripe Price ID for the product or subscription (e.g.,
price_1ABC...)string
required
URL to redirect after successful payment. Include
{CHECKOUT_SESSION_ID} placeholder.string
required
URL to redirect if user cancels checkout
string
default:"subscription"
Checkout mode:
subscription or payment (one-time)integer
default:"1"
Quantity of items (minimum: 1)
object
Additional metadata to attach to the checkout session
boolean
default:"false"
If
true, allows checkout even if user already has an active subscriptionResponse
string
Stripe Checkout Session ID
string
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
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
Get My Subscription
Check user’s subscription status
Stripe Webhook
Handle checkout completion
Update Subscription
Change subscription plans
Authorizations
The access token received from the authorization server in the OAuth 2.0 flow.
Query Parameters
Use test mode credentials
Body
application/json
Request to create a Stripe checkout session.
Minimum string length:
1Minimum string length:
1Minimum string length:
1Pattern:
^(subscription|payment)$Required range:
x >= 1If true, allows checkout even if user has active subscription

