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
- Build an HTTPS endpoint on your server that accepts
POSTrequests. - 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:
| Status | Meaning |
|---|---|
INIT | Payment initiated |
AUTH3DSCHALLENGE | 3-D Secure challenge required |
AUTH3DSCHALLENGEFORM | Authentication form presented |
AUTH3DSRESULT | Authentication result received |
PAYING | Payment 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"
}
| Field | Description |
|---|---|
created | Event timestamp, in seconds |
uuid / id | Transaction identifiers |
famt | Payment amount |
currency | Currency code |
externalid | The identifier you set when creating the payment |
customerid | Your customer identifier |
status | Current status code |
statustext | Human-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.
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:
| Header | Description |
|---|---|
X-Timestamp | Current time in seconds, rounded down |
X-Signature | An 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.
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.