Handle Stripe Webhook
curl --request POST \
--url https://api.devkit4ai.com/api/v1/payments/stripe/webhooks/{project_id}/{mode}import requests
url = "https://api.devkit4ai.com/api/v1/payments/stripe/webhooks/{project_id}/{mode}"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.devkit4ai.com/api/v1/payments/stripe/webhooks/{project_id}/{mode}', 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/webhooks/{project_id}/{mode}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.devkit4ai.com/api/v1/payments/stripe/webhooks/{project_id}/{mode}"
req, _ := http.NewRequest("POST", url, nil)
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/webhooks/{project_id}/{mode}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.devkit4ai.com/api/v1/payments/stripe/webhooks/{project_id}/{mode}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_body{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Stripe Webhooks
Stripe Webhook Handler
Receive and process webhook events from Stripe
POST
/
api
/
v1
/
payments
/
stripe
/
webhooks
/
{project_id}
/
{mode}
Handle Stripe Webhook
curl --request POST \
--url https://api.devkit4ai.com/api/v1/payments/stripe/webhooks/{project_id}/{mode}import requests
url = "https://api.devkit4ai.com/api/v1/payments/stripe/webhooks/{project_id}/{mode}"
response = requests.post(url)
print(response.text)const options = {method: 'POST'};
fetch('https://api.devkit4ai.com/api/v1/payments/stripe/webhooks/{project_id}/{mode}', 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/webhooks/{project_id}/{mode}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.devkit4ai.com/api/v1/payments/stripe/webhooks/{project_id}/{mode}"
req, _ := http.NewRequest("POST", url, nil)
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/webhooks/{project_id}/{mode}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.devkit4ai.com/api/v1/payments/stripe/webhooks/{project_id}/{mode}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
response = http.request(request)
puts response.read_body{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>"
}
]
}Receive and process webhook events from Stripe. This endpoint should be configured in your Stripe Dashboard to receive events for checkout completions, subscription changes, and payment updates.
Authentication
This endpoint does NOT use Bearer token authentication. Instead, it validates requests using the Stripe webhook signature.
Path Parameters
string (UUID)
required
The unique identifier of the project
string
required
Webhook mode:
test or liveHeaders
string
required
Stripe signature header for webhook verification
Request Body
Stripe sends event payloads as JSON. The body contains the event object with type and data.Response
Returns200 OK on successful processing.
Webhook URL Format
https://api.devkit4ai.com/api/v1/payments/stripe/webhooks/{project_id}/{mode}
| Mode | Description |
|---|---|
test | For test mode webhooks (development) |
live | For live mode webhooks (production) |
Use the Get Webhook URLs endpoint to get the correct URLs for your project.
Supported Events
The Cloud API processes these Stripe events:| Event | Action |
|---|---|
checkout.session.completed | Creates subscription and customer records |
customer.subscription.created | Records new subscription |
customer.subscription.updated | Updates subscription status/plan |
customer.subscription.deleted | Marks subscription as canceled |
invoice.paid | Records successful payment |
invoice.payment_failed | Marks subscription as past_due |
Event Processing Flow
Webhook Verification
All webhooks are verified using the signing secret configured in your Stripe settings:Security: Always use HTTPS for webhook endpoints. Never log or expose the webhook signing secret.
Configuring Webhooks
1
Get Webhook URLs
Call Get Webhook URLs to get your project’s webhook endpoints.
2
Create Endpoint in Stripe
Go to Developers > Webhooks in Stripe Dashboard and click Add endpoint.
3
Configure Events
Select the events to receive:
checkout.session.completed
customer.subscription.created
customer.subscription.updated
customer.subscription.deleted
invoice.paid
invoice.payment_failed
4
Save Webhook Secret
Copy the signing secret and save it using Update Stripe Config.
Local Development
Use Stripe CLI to forward webhooks to your local development server:# Install Stripe CLI
brew install stripe/stripe-cli/stripe
# Login to Stripe
stripe login
# Forward webhooks to local backend
stripe listen --forward-to localhost:8000/api/v1/payments/stripe/webhooks/{project_id}/test
# The CLI will display a webhook secret - use this for local testing
Event Payload Example
{
"id": "evt_1ABC123def456",
"type": "checkout.session.completed",
"data": {
"object": {
"id": "cs_test_a1b2c3d4",
"customer": "cus_XYZ789",
"subscription": "sub_ABC123",
"metadata": {
"user_id": "990e8400-e29b-41d4-a716-446655440000"
}
}
}
}
Error Responses
| Status | Description |
|---|---|
400 | Invalid signature or malformed payload |
404 | Project not found or Stripe not configured |
500 | Internal error processing event |
Retry Behavior
Stripe retries failed webhooks for up to 3 days with exponential backoff. Return200 OK quickly to acknowledge receipt - process data asynchronously if needed.
Related Pages
Get Webhook URLs
Get your webhook endpoint URLs
Update Stripe Config
Save webhook signing secret
List Project Subscriptions
View created subscriptions

