Collect Webhooks

Collect Webhooks

Webhooks notify your server when events happen in your account. You configure an event destination with a URL, and Synapto sends HTTP POST requests to that URL when subscribed events occur.

Event types

Event TypeDescription
payment_intent.succeededA payment intent has been successfully confirmed and charged
checkout_session.paidA checkout session has been paid
setup_intent.succeededA setup intent has been confirmed and a payment method saved
invoice.paidAn invoice has been paid
invoice.finalizedAn invoice has been finalized and is ready for payment
invoice.settledAn invoice's funds have settled into the account's balance
charge.failedA charge has failed
account.updatedAn account's details or capabilities have changed
account.external_bank_account.createdAn external bank account has been added to an account
refund.updatedA refund's status has changed

Event payload

Events are delivered as JSON with the following structure:

{
  "name": "accounts/acct_YOUR_ACCOUNT/events/evt_EVENT_ID",
  "type": "payment_intent.succeeded",
  "event_time": "2025-11-17T16:49:42Z",
  "payment_intent": {
    "name": "accounts/acct_YOUR_ACCOUNT/payment-intents/pi_PAYMENT_INTENT_ID",
    "amount": "10000",
    "currency": "GBP",
    "state": "SUCCEEDED"
  }
}

The payload field varies by event type:

Event TypePayload Field
payment_intent.succeededpayment_intent
checkout_session.paidcheckout_session
setup_intent.succeededsetup_intent
invoice.paidinvoice
invoice.finalizedinvoice
invoice.settledinvoice
charge.failedcharge
account.updatedaccount
account.external_bank_account.createdexternal_bank_account
refund.updatedrefund

Configuring webhooks

Webhook endpoints are managed in the Dashboard under Settings > Developer. To set up a webhook:

  1. Go to Settings > Developer in the Dashboard
  2. Under Webhook Endpoints, click Create
  3. Enter a name, your HTTPS endpoint URL, and select the event types to subscribe to
  4. Copy the signing secret — it's only shown once (you can rotate it later)

Webhook endpoints must use HTTPS.

Event destinations

Each event destination has:

FieldDescription
display_nameA human-readable label for the destination
event_typesThe event types to subscribe to
webhook_endpoint.urlThe HTTPS URL to receive events
webhook_endpoint.signing_secretSecret used to verify signatures (generated automatically, prefixed with whsec_)
stateACTIVE or SUSPENDED

Verifying webhook signatures

Every webhook request includes a Synapto-Signature header that you should verify to ensure the request came from Synapto.

Header format

Synapto-Signature: t=1759581623,v1=f0c3e10b74a338ef0fa494da0613853a7ca6062be6c885f797256df31125737b
  • t — the UNIX timestamp (seconds) when the signature was generated
  • v1 — the HMAC-SHA256 signature

Verification steps

  1. Extract the t and v1 values from the header
  2. Construct the signed payload: {t}.{request_body} (the timestamp, a dot, then the raw request body)
  3. Compute the HMAC-SHA256 of the signed payload using your signing secret
  4. Compare the hex-encoded result to the v1 value using a constant-time comparison to prevent timing attacks

Example (Node.js)

const crypto = require("crypto");

function verifyWebhookSignature(requestBody, signatureHeader, signingSecret) {
  const [tPart, v1Part] = signatureHeader.split(",");
  const timestamp = tPart.replace("t=", "");
  const signature = v1Part.replace("v1=", "");

  const payload = `${timestamp}.${requestBody}`;
  const expected = crypto
    .createHmac("sha256", signingSecret)
    .update(payload)
    .digest("hex");

  return crypto.timingSafeEqual(
    Buffer.from(signature, "hex"),
    Buffer.from(expected, "hex")
  );
}

Delivery details

  • Method: POST
  • Content-Type: application/json
  • User-Agent: synapto-webhook
  • Expected response: Return HTTP 200 to acknowledge receipt. Any other status code is treated as a failure.

Retry behavior

Failed deliveries are retried up to 2 times with increasing delays:

AttemptDelay
1~30 seconds
2~2 minutes

A small amount of jitter (up to 60 seconds) is added to each delay.

After all 3 attempts are exhausted, the delivery is marked as failed. Each attempt is recorded with full request/response details.

Parent account events

If the event occurs on a sub-account, the event is delivered to both the sub-account's destinations and the parent account's destinations. This lets platform accounts receive events from all their sub-accounts with a single webhook endpoint.