Skip to main content

Overview

Webhooks deliver asynchronous notifications about the final result of a payment, so your internal transaction state stays accurate even if the authorization request times out or returns an ambiguous response. When an intent reaches a terminal state, Push sends a signed event — intent.approved or intent.declined — to an HTTPS endpoint you control. Push also emits ledger events as funds move through settlement. When a transaction reaches its terminal settled state, Push sends a transaction.settled event so you can confirm that funds have settled without polling. See the Ledger guide for the transaction lifecycle. Push emits a dispute.created event when a completed payment is challenged — a card chargeback or an ACH return — so you learn a payment is being reversed without polling. See Disputes for the dispute lifecycle. Events are delivered at-least-once and may arrive in any order relative to the authorization response, so your endpoint must verify each event, process it idempotently, and tolerate out-of-order delivery.

Integration overview

The steps below show an overview of how to receive and process webhooks.
  1. Configure webhook delivery. When calling authorize-payment, provide:
    • webhook_url — where Push delivers webhook events.
    • webhook_secret — used to sign each event so you can verify its authenticity (32 characters minimum).
    • tag — maps each event back to your internal transaction record.
  2. Expose an HTTPS endpoint. Create an endpoint at your webhook_url that accepts POST requests and is reachable over HTTPS from the Push IP addresses.
  3. Verify each event. Verify the request signature and timestamp before processing, and reject invalid requests with 401 Unauthorized. See Security.
  4. Update your record and acknowledge. Parse the payload (see Webhook types), update the matching transaction record (keyed on the tag or intent id), and return 200 OK. Your integration must tolerate out-of-order and duplicate deliveries — see Independent ordering and Idempotency.

Webhook types

Push sends the following events. Each event has a type, a data object with the fields below, and a timestamp (ISO 8601).

intent.approved

Triggered when an intent is successfully approved.

intent.declined

Triggered when an intent is declined.

transaction.settled

Triggered when a transaction reaches its terminal settled status — the funds have settled with the network. For cash_in the funds have been transmitted; for cash_out the network has confirmed the counterparty received the funds. The event is delivered to the same endpoint you configured for the originating payment. The data object is the settled transaction, including the transfer that settled it. To reconcile the event against your own records, match source_id (or the tag you set on the originating payment) to your internal record, and use the transfer object to identify the settlement it landed in. See the Ledger guide.

dispute.created

Triggered when a dispute is opened against one of your payments — a card chargeback or an ACH return reversing a completed cash_in. The event is delivered to the same endpoint you configured for the originating payment. The data object is the dispute. A dispute opens in the created status; its resolution to won or lost is not delivered as a webhook — refetch the dispute or intent to observe the outcome. See Disputes. To reconcile the event against your own records, match intent_id (or the tag you set on the originating payment) to your internal record. See Disputes.

Independent ordering

Webhook delivery and authorization responses are independent and may arrive in any order. Your system must handle both scenarios by ensuring that the internal transaction record is committed to the database before the call to the authorization endpoint:
  1. Webhook arrives first (before authorization response)
  2. Authorization response arrives first (before webhook)
Sequence diagram illustrates the two possible scenarios of ordering between webhook delivery and authorization results.Sequence diagram illustrates the two possible scenarios of ordering between webhook delivery and authorization results.

Idempotency

Push provides at-least-once delivery for webhooks. Your application must handle duplicate webhook deliveries gracefully using database transactions to ensure idempotency. In the case of a duplicated webhook delivery from Push either due to an error or timeout from your callback handler, you should discard the request and return a 200 OK. If Push does not receive a 200 OK response from your webhook endpoint, delivery will be retried with exponential backoff.

Security

Webhooks deliver data directly to an endpoint you control over the public internet. Because they are invoked automatically by Push, webhook endpoints must be explicitly secured to prevent unauthorized requests, data tampering, and replay attacks. Without proper verification, a malicious actor could spoof webhook requests and falsely mark payments as approved or declined in your system.
If your cloud data environment restricts network access from external IPs via a firewall, you may need to allow inbound traffic from Push IP addresses in order to receive webhook requests.
Production 44.238.180.175Sandbox 34.209.246.44

Signature verification

When a webhook_secret is provided, Push signs each webhook request using an HMAC-SHA256 signature derived from the raw request payload. This allows your application to verify that:
  • The request was sent by Push
  • The payload has not been modified in transit
Every webhook request must be verified before it is processed. Signature format
Verification steps
  1. Extract the signature from the X-Webhook-Signature header
  2. Read the raw request body as bytes (before parsing JSON)
  3. Compute an HMAC-SHA256 signature using your webhook_secret and the raw body
  4. Compare the computed signature to the received signature using constant-time comparison
  5. Reject requests with invalid signatures (401 Unauthorized)

Timestamp Verification

The timestamp field in the webhook payload indicates when the webhook was created. To prevent replay attacks, verify that the timestamp is recent (within 10 minutes).Verification Steps
  1. Parse the timestamp field from the payload (ISO 8601format)
  2. Compare with current time
  3. Reject requests older than 10 minutes (return401 Unauthorized)