Docs

Webhooks

Webhooks let SecurePayAPI notify your server in real time as a payment moves through its lifecycle — so you can fulfill orders, update your records, or alert a customer without polling the API.

Set up an endpoint

  1. Build an HTTPS endpoint on your server that accepts POST requests.
  2. Add its URL in the Developer section of your dashboard.

SecurePayAPI will start posting events to that URL right away.

When webhooks fire

A webhook is sent on every change to a payment's status, from initiation through to its final state. Typical transitions you'll receive:

StatusMeaning
INITPayment initiated
AUTH3DSCHALLENGE3-D Secure challenge required
AUTH3DSCHALLENGEFORMAuthentication form presented
AUTH3DSRESULTAuthentication result received
PAYINGPayment is being processed

You keep receiving events until the payment reaches a final status.

Payload

Each webhook is a JSON POST describing the payment's current state:

{
  "created": 1717000000,
  "uuid": "a1b2c3d4-…",
  "id": "abcdef0123456789abcdef01",
  "famt": 2000,
  "currency": "USD",
  "externalid": "order_123",
  "customerid": "cus_8842",
  "status": "PAYING",
  "statustext": "Payment is being processed"
}
FieldDescription
createdEvent timestamp, in seconds
uuid / idTransaction identifiers
famtPayment amount
currencyCurrency code
externalidThe identifier you set when creating the payment
customeridYour customer identifier
statusCurrent status code
statustextHuman-readable description of the status

Acknowledge receipt

Return HTTP 204 as soon as you've stored the event. A 204 confirms delivery and stops further redelivery for that event. If your endpoint returns anything else — or times out — SecurePayAPI retries.

Note

Acknowledge first, process later. Return 204 quickly, then run any heavy work (order fulfillment, emails) asynchronously so the delivery doesn't time out.

Verify the signature

Every request carries two headers so you can confirm it genuinely came from SecurePayAPI:

HeaderDescription
X-TimestampCurrent time in seconds, rounded down
X-SignatureAn HMAC-SHA256 signature of the request

Recompute the signature with your secret key and compare it to X-Signature:

const crypto = require('crypto');

function isValidWebhook(req, apiSecret) {
  const timestamp = req.headers['x-timestamp'];
  const expected = crypto
    .createHmac('sha256', apiSecret)
    .update(timestamp + JSON.stringify(req.body))
    .digest('hex');
  return expected === req.headers['x-signature'];
}

Reject any request whose signature doesn't match.

Caution

Always verify the signature before trusting a webhook. Don't act on an event you can't authenticate.

Allowlist our IP

Webhook requests are sent from 157.230.218.195. If your infrastructure filters inbound traffic, allow this address.

© SecurePayAPI · Built with Markdoc