Inyo

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

EventTriggerTypical Action
AUTHORIZEDPayment successfully authorized (funds reserved)Confirm payment method is valid
CAPTUREDPayment captured and funds settledFulfill order, release goods
CHALLENGE3DS challenge initiated; awaiting cardholder verificationWait for follow-up (AUTHORIZED or DECLINED)
DECLINEDPayment rejected by issuer or fraud rulesPrompt user for another method
VOIDEDAuthorization cancelled before captureUpdate order as cancelled
REFUNDEDFunds 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:

  1. Provide your webhook URL(s)
  2. Select which events you want to receive
  3. 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, and DELETE /notification endpoints.

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

  1. Return 200 quickly — Acknowledge receipt before doing heavy processing. Queue the event for async handling.

  2. Verify the source — Validate that webhook requests come from Inyo's IP range or verify the authentication credentials.

  3. Handle duplicates — Webhooks may be delivered more than once. Use paymentId + status as an idempotency key.

  4. Check status, not just approved — The status field (AUTHORIZED, CAPTURED, DECLINED, etc.) is the authoritative state of the payment.

  5. 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.