Webhooks
A Payment Orchestration integration involves two separate webhook registrations:
- Register Forter with your processors. Where your processor offers webhooks, add Forter's endpoint in the processor's dashboard. This lets Forter track asynchronous outcomes, such as captures and refunds that complete later.
- Register your endpoint with Forter. Subscribe to Payment Orchestration Update notifications, so Forter can tell your server when a payment or refund changes state.
Registering Forter with Your Processors
Forter relies on your processors' webhooks to learn about asynchronous outcomes. For each processor that supports webhooks, add a webhook endpoint in the processor's dashboard with this URL format:
https://payments.checkouttools.com/webhooks/{processor}/{siteId}/{accountId}- {processor}: stripe, braintree, airwallex or connexpay
- {siteId}: your Forter site ID
- {accountId}: the ID of the processor account configured for you in Forter. Your Forter contact provides it.
For sandbox, use https://payments-sandbox.checkouttools.com with your sandbox site ID.
Your Forter contact tells you which events to subscribe to for your processor. Requests are verified with the processor's own signing mechanism, so share the webhook signing secret with Forter when your processor account is configured.
If a processor doesn't offer webhooks, no registration is needed: Forter checks the status of pending operations with the processor directly.
Receiving Payment Orchestration Updates
Setup
Forter sends notifications as HTTPS POST requests with a JSON body to the endpoint you register for your site under the Payment Orchestration Update notification type. Endpoints are registered in the Forter Portal the same way as for other notification types (see the Notification Webhooks Overview), or your Forter contact can configure them for you.
When Notifications Are Sent
Notifications are triggered by events that your processors report to Forter, so they depend on the processor webhooks registered in the previous section. You receive them for:
- Asynchronous outcomes, such as a pending authorization, capture or refund completing.
- Changes made outside the Orchestration API, such as a refund issued from your processor's dashboard.
- Operations you initiated through the API, once the processor confirms them.
The synchronous API response is always the authoritative result of the call you made. Use notifications to learn about changes that happen afterwards.
Event Types
eventType | Description |
|---|---|
payment_authorized | The processor authorized the payment. |
payment_captured | Funds were captured. |
payment_canceled | The authorization was canceled or voided. |
payment_failed | The authorization or capture failed. |
payment_expired | The authorization expired before it was captured. |
refund_succeeded | A refund was processed. |
refund_failed | A refund failed. |
New event types may be added. Acknowledge events you don't recognize with a 2xx response and ignore them.
Payload
{
"eventType": "payment_captured",
"paymentIntentId": "pi_v1r1a3f9c2e4b5d6478a9b0c1d2e3f4a5b6c",
"status": "succeeded",
"amount": 1099,
"currency": "USD",
"connector": "stripe",
"connectorPaymentId": "pi_3PqLmK2eZvKYlo2C1abcDEFg",
"connectorChargeId": "ch_3PqLmK2eZvKYlo2C1xyzABCd",
"connectorRefundId": null,
"timestamp": 1730505600000
}Field | Description |
|---|---|
eventType | One of the event types above. |
paymentIntentId | The Forter payment ID (the id returned by POST /api/payments). |
status | For payment events, the payment's current status. For refund events, the refund's status (pending, succeeded, failed or voided). |
amount, currency | The amount of the payment or refund, in minor units, and its ISO 4217 currency code. |
connector | The processor that reported the event, for example stripe or braintree. |
connectorPaymentId, connectorChargeId, connectorRefundId | The processor's own identifiers for the payment, capture and refund. A field is null when it doesn't apply to the event. |
timestamp | When the processor reported the event, in milliseconds since the Unix epoch. |
Always base your logic on status rather than eventType. A processor can report several events for one state change. For example, an automatically captured payment can produce both payment_authorized and payment_captured, and both carry status: succeeded.
Verifying Requests
Every notification includes these headers:
Header | Value |
|---|---|
Authorization | Basic followed by the Base64 encoding of <your webhook secret key>: |
x-forter-notification-siteid | Your site ID. |
x-forter-notification-message-topic | payment orchestration update |
x-forter-notification-timestamp | When the notification was sent, in milliseconds since the Unix epoch. |
x-forter-notification-version | 1 |
x-forter-notification-retries | Present on redeliveries. The number of previous delivery attempts. |
Reject any request whose Authorization header doesn't match the value computed from your webhook secret key, and compare the values in constant time. For parent and child site setups, notifications are sent with the parent site's ID and secret key.
Responding and Retries
- Return any 2xx status within 5 seconds to acknowledge the notification. Do the actual processing asynchronously if it may take longer.
- Any other response, a redirect or a timeout counts as a failed delivery. Forter retries failed deliveries with increasing back-off.
Duplicates and Ordering
Delivery is at least once, and notifications are not guaranteed to arrive in order. Design your handler for both:
- Make processing idempotent. The same state change can arrive more than once.
- Don't assume order. Compare timestamp with the last event you processed for the payment, or retrieve the payment with GET /api/payments/{id} and act on its current state.
- Use the API to reconcile. If a payment or refund stays in processing or pending for longer than you expect, retrieve it rather than waiting for a notification.