Webhooks
TurnStay sends real-time notifications to your server when events occur — payment completions, transaction updates, refunds, and more.
Configure webhook endpoints in the TurnStay Dashboard under Settings > Webhooks.
Webhook payload format
Section titled “Webhook payload format”All webhooks follow this structure:
{ "type": "merchant_of_record.payment_intent.succeeded", "data": { "object": { "id": "45678", "object": "payment_intent", "status": "PROCESSED", "billing_amount": 100000, "billing_currency": "ZAR", "processing_amount": 5200, "processing_currency": "EUR", "merchant_reference": "BOOKING-2026-001", "company_id": 10, "account_id": 123 } }}Handling webhooks
Section titled “Handling webhooks”Your webhook endpoint must:
- Accept
POSTrequests with a JSON body. - Return HTTP
200to acknowledge receipt. - Be publicly accessible (not behind a VPN).
- Handle duplicate events gracefully (idempotency).
@app.route("/webhooks/turnstay", methods=["POST"])def turnstay_webhook(): event = request.get_json() if event["type"] == "merchant_of_record.payment_intent.succeeded": intent = event["data"]["object"] mark_booking_as_paid( reference=intent["merchant_reference"], amount=intent["billing_amount"], ) return jsonify({"ok": True}), 200Retry behaviour
Section titled “Retry behaviour”If your endpoint does not return HTTP 200, TurnStay retries delivery with exponential backoff. Ensure your handler is idempotent — the same event may be delivered more than once.
Error responses
Section titled “Error responses”When an API request fails, TurnStay returns a JSON error response:
{ "detail": "billing_amount is required"}| HTTP status | Meaning |
|---|---|
400 | Bad request — check the detail field for the cause. |
401 | Unauthorized — invalid or missing API key. |
404 | Resource not found. |
405 | Method not allowed — check the HTTP method. |
422 | Validation error — invalid field values. |
500 | Server error — retry the request or contact support. |
Callbacks (legacy)
Section titled “Callbacks (legacy)”If you set callback_url when creating a Payment Intent, TurnStay also POSTs to {your_callback_url}/callback/payment/intent. See Payment Events for the callback payload format.
Webhooks are recommended over callbacks for new integrations.