Skip to main content

Webhooks

Switch sends outbound HTTP callbacks for transaction lifecycle events. A single transaction can produce up to two webhook deliveries:
  • a receiver webhook to the receiving application’s transactionWebhookUrl
  • a sender callback to the sender’s callbackUrl (or sender app transactionWebhookUrl fallback)

1) Receiver webhook

Sent when a transaction is initiated and addressed to a tag owned by the receiving application.
  • Target: transactionWebhookUrl on the receiving app
  • Event name: TRANSACTION_INITIATED
  • Purpose: notify the receiver that a payment request needs acceptance or rejection
Example payload:
This is the webhook the receiving app should act on. After validating it, the app calls the accept or reject endpoint for that transaction.

2) Sender callback

Sent after the transaction reaches a terminal outcome.
  • Target: sender’s callbackUrl, or if not supplied, the sender app’s transactionWebhookUrl
  • Event names:
    • TRANSACTION_COMPLETED
    • TRANSACTION_REJECTED
    • TRANSACTION_EXPIRED
  • Purpose: inform the sender of the final result
The payload shape is the same as the receiver webhook, with a different event value and the same transaction metadata. Example:

Payload rules

All delivery payloads include:
  • event: one of TRANSACTION_INITIATED, TRANSACTION_COMPLETED, TRANSACTION_REJECTED, TRANSACTION_EXPIRED
  • transaction: the transaction snapshot with:
    • reference
    • sender and receiver tag names
    • sender and receiver app IDs/names
    • amount, currency, narration
    • createdAt and expiresAt

Encryption

If the target application has JWE encryption enabled, the body may be sent as a JWE compact string rather than raw JSON.
  • Header: Content-Encryption: JWE
  • Decrypt using the application’s own private key after validating the webhook signature
  • The signature is still computed over the raw HTTP body that was delivered

Signature verification

Every outbound webhook includes:
  • X-Switch-Timestamp
  • X-Switch-Signature
Signature format:

Verification flow

  1. Read the raw request body exactly as received.
  2. Reject stale timestamps.
  3. Recompute the HMAC with your webhookSecret.
  4. Compare signatures in constant time.
  5. If encryption is enabled, decrypt the payload next.
  6. Return a 2xx response promptly.

Delivery expectations

  • Switch retries failed webhook deliveries up to 3 times.
  • Retry backoff is exponential.
  • Failed deliveries can be inspected later through webhook-related endpoints.

Operational recommendations

  • Treat webhook handling as idempotent.
  • Persist delivery attempts by transaction/reference.
  • Verify the signature before parsing business data.
  • Decrypt only after signature validation when encryption is enabled.

Typical flow