Webhooks
Receive real-time payment status notifications
Webhooks allow Cost+ to notify your server in real time whenever an order's status changes. Instead of polling the API, you provide a URL and Cost+ sends an HTTP POST request to it whenever there is an update.
How Webhooks Work
- You specify a
webhook_urlwhen creating an order, or configure a default webhook URL at the project level. - When the order status changes (e.g., from
newtocompleted), Cost+ sends a POST request to your webhook URL. - Your server receives the webhook, then calls the Cost+ API to retrieve the full order details.
- You update your system based on the verified order status.
Never trust the webhook payload alone to fulfill an order. Always verify the order status by making a GET /v1/orders/{id}/ request after receiving a webhook. The webhook is a notification mechanism, not a source of truth.
Webhook Payload
The webhook body is a JSON object containing the event type and the order ID:
{
"event": "status_changed",
"order_id": "b9ae6...",
"project_id": "proj_abc123"
}| Field | Description |
|---|---|
event | The type of event. Currently status_changed for order updates. |
order_id | The unique identifier of the order whose status changed. |
project_id | The project that the order belongs to. |
Setting the Webhook URL
You can set the webhook URL in two ways:
Per-Order
Include the webhook_url field when creating an order:
{
"currency": "EUR",
"amount": 1295,
"webhook_url": "https://www.example.com/webhook"
}Project Default
Configure a default webhook URL in your Cost+ dashboard under project settings. This URL will be used for all orders that do not specify their own webhook_url.
Even if you have a project-level default, you can override it on a per-order basis by including webhook_url in the order creation request.
Retry Logic
If your server does not respond with a 2xx status code, Cost+ retries the webhook delivery:
- Maximum retries: 10 attempts
- Retry interval: 2 minutes between each attempt
- First attempt timeout: 4 seconds
- Subsequent attempt timeout: 10 seconds
If all 10 retry attempts fail, the webhook is marked as failed. You can still retrieve the order status at any time by polling the API.
Make sure your webhook endpoint responds quickly (within 4 seconds for the first attempt). Perform any long-running processing asynchronously after returning a 200 OK response.
Best Practices
- Always verify via API. Upon receiving a webhook, call
GET /v1/orders/\{order_id\}/to confirm the current status before taking action such as shipping goods or granting access. - Return 200 quickly. Acknowledge the webhook with a
200response immediately and process the order asynchronously to avoid timeouts. - Handle duplicates. Your webhook endpoint may receive the same event more than once. Ensure your processing logic is idempotent.
- Use HTTPS. Always use an HTTPS URL for your webhook endpoint to ensure the payload is transmitted securely.
- Log webhook payloads. Store incoming webhook data for debugging and audit purposes.
Related Endpoints
- Create Order — set the
webhook_urlper order - Update Order — update the webhook URL on an existing order
- Webhook Event Schemas — payload format for
OrderStatusChangedEventandTransactionStatusChangedEvent