Webhooks
Webhooks deliver real-time notifications to your server when a payment reaches a specific status. Instead of polling the API for updates, your system receives a POST request with the payment details.
Supported Events
| Event | Trigger | Typical Action |
|---|---|---|
AUTHORIZED | Payment successfully authorized (funds reserved) | Confirm payment method is valid |
CAPTURED | Payment captured and funds settled | Fulfill order, release goods |
CHALLENGE | 3DS challenge initiated; awaiting cardholder verification | Wait for follow-up (AUTHORIZED or DECLINED) |
DECLINED | Payment rejected by issuer or fraud rules | Prompt user for another method |
VOIDED | Authorization cancelled before capture | Update order as cancelled |
REFUNDED | Funds returned to cardholder (full or partial) | Confirm refund in your system |
Webhook Configuration
Webhook endpoints are configured during merchant onboarding. Contact the Inyo team to:
- Provide your webhook URL(s)
- Select which events you want to receive
- Configure authentication (Basic auth or Bearer token)
Webhook registration API: Webhooks can also be managed programmatically via the notification endpoints. See the OpenAPI spec for
POST,GET, andDELETE /notificationendpoints.
Webhook Payload
All webhook events deliver the same JSON structure — the full payment object at the time of the event:
{
"paymentId": "469670e2-31e3-4700-b9f2-abee99418dc4",
"parentPaymentId": "469670e2-31e3-4700-b9f2-abee99418dc4",
"externalPaymentId": "order-12345",
"redirectAcsUrl": "",
"amount": 95.00,
"created": "2025-01-21 16:31:02",
"approved": true,
"message": "Payment Approved",
"acquirerMessage": "IN_PROCESS_AUTHORISED",
"automaticReversed": false,
"status": "AUTHORIZED",
"captured": false,
"voided": false,
"authCode": "469670e2-31e3-4700-b9f2-abee99418dc4",
"issuerName": "BANK OF AMERICA",
"issuerCountry": "UNITED STATES",
"cvcResult": "NOT_SENT",
"avsResult": "NOT_SENT",
"aavAddressResult": "NOT_CHECKED",
"aavPostcodeResult": "NOT_CHECKED",
"aavCardholderNameResult": "N/A",
"aavTelephoneResult": "NOT_CHECKED"
}
Payload Fields
See Authorizing a Card Payment for a full description of all response fields. The webhook payload is identical to the payment response object.
Handling Webhooks
Best Practices
Return 200 quickly — Acknowledge receipt before doing heavy processing. Queue the event for async handling.
Verify the source — Validate that webhook requests come from Inyo's IP range or verify the authentication credentials.
Handle duplicates — Webhooks may be delivered more than once. Use
paymentId+statusas an idempotency key.Check
status, not justapproved— Thestatusfield (AUTHORIZED,CAPTURED,DECLINED, etc.) is the authoritative state of the payment.Don't rely solely on webhooks — Always confirm the payment status via the GET payment endpoint before fulfilling orders. Webhooks are notifications, not the source of truth.
Example Handler (Node.js)
app.post('/webhooks/inyo', (req, res) => {
// Acknowledge immediately
res.status(200).send('OK');
const payment = req.body;
const { externalPaymentId, status, paymentId } = payment;
switch (status) {
case 'AUTHORIZED':
// Payment authorized — ready to capture
markOrderAsAuthorized(externalPaymentId, paymentId);
break;
case 'CAPTURED':
// Funds settled — fulfill the order
fulfillOrder(externalPaymentId);
break;
case 'DECLINED':
// Payment failed — notify customer
notifyDecline(externalPaymentId, payment.message);
break;
case 'VOIDED':
// Authorization cancelled
cancelOrder(externalPaymentId);
break;
case 'REFUNDED':
// Funds returned
processRefund(externalPaymentId, payment.amount);
break;
}
});
Retry Policy
If your endpoint returns a non-2xx response or times out, Inyo will retry delivery with exponential backoff. Ensure your handler is idempotent to handle retries safely.
