Webhook Message
NetValve provides real-time webhook information about the status of your requests. Setting up a webhook means you automatically receive updates when there is a status change with your request.
There are two ways to receive webhooks:
- Configured webhooks — reach out to the NetValve team with your webhook URL. It is configured for your account, site or MID and receives events for all your transactions.
- Per-order webhooks — send a
webhookDataobject on the payment request to receive the events for that order at a URL of your choice. See Per-Order Webhooks.
Per-Order Webhooks
Add a webhookData object to any of these requests:
NetValve sends every webhook event for that order to webhookData.webhookUrl, including events from later transactions on the order such as capture, refund, cancel and rebill.
A per-order webhook is sent in addition to your configured webhooks, not instead of them. If you have a configured webhook, it still receives the same events.
| Field | Required | Description |
|---|---|---|
webhookUrl | Yes | Absolute http or https URL, up to 1024 characters. Must resolve to a public address. |
header | No | Name of a custom HTTP header to send with each webhook, up to 256 characters. |
headerValue | No | Value of the custom header, up to 512 characters. Stored encrypted. The header is only sent when both header and headerValue are set. |
curl -X POST https://payment-api.uat.sandbox-netvalve.com/sale \
-H "Content-Type: application/json" \
-H "netvalve-api-key: YOUR_API_KEY" \
-H "netvalve-client-id: YOUR_CLIENT_ID" \
-d '{
"amount": 1.00,
"currency": "USD",
"cardNumber": "4012000098765439",
"cardExpireMonth": "12",
"cardExpireYear": "2030",
"cardSecurityCode": "123",
"cardHolderName": "John Doe",
"customerEmail": "docs@netvalve.com",
"orderDesc": "Test order",
"netvalveMidId": "{{netvalveMidId}}",
"webhookData": {
"webhookUrl": "https://merchant.example.com/webhooks/netvalve",
"header": "X-Webhook-Token",
"headerValue": "your-shared-secret"
}
}'
Invalid webhook URL
An invalid webhookUrl does not decline the payment. The transaction is processed normally, no per-order webhook is sent, and both the API response and your configured webhooks include webhookFailureMessage:
{
"transactionID": 88852,
"responseCode": "GTW_1000",
"responseCodeType": "APPROVED",
"webhookFailureMessage": "Merchant provided webhook URL not valid"
}
webhookFailureMessage is omitted when the URL is valid or when webhookData is not sent.
Per-order webhooks use the same message format, timeout and retry schedule as configured webhooks.
Webhook Values
The NetValve transmits the webhook message to the client server in JSON format.
Event Name
- Possible event names
| Event | Description |
|---|---|
| AUTHORISED | Triggered when a payment has been authorized |
| AUTHORISATION_FAILED | Triggered when the authorization process has failed. |
| PURCHASED | Triggered when the Sale process has succeeded. |
| PURCHASE_FAILED | Triggered when Sale process has failed. |
| CAPTURED | Triggered when an AUTHORISED payment has been CAPTURED, in full. |
| CAPTURE_FAILED | Triggered when the CAPTURE process has failed. |
| CANCELLATION_FAILED | Triggered When the APM system declines or fails for a payment. |
| CANCELLED | Triggered when the transaction has been cancelled. |
| REFUNDED | Triggered when a CAPTURED payment has subsequently been refunded. |
| REFUND_FAILED | Triggered when a REFUND request has failed. |
| REBILLED | Triggered when a REBILL transaction is successful. |
| REBILL_FAILED | Triggered when a REBILL transaction has failed. |
| AUTHORISATION_PENDING | Triggered when the authorization process has PENDING as status. |
| PURCHASE_PENDING | Triggered when the Sale process has PENDING as status. |
| CAPTURE_PENDING | Triggered when the CAPTURE process has PENDING as status. |
| REBILL_PENDING | Triggered when a REBILL transaction has PENDING as status. |
| REFUND_PENDING | Triggered when a REFUND request has PENDING as status. |
| CANCELLATION_PENDING | Triggered when a CANCEL request has PENDING as status. |
| CHARGEBACK | Triggered when a CHARGEBACK is received. |
Webhook Response
Webhook Request Handling
For successful handling, your response to the POST request should be 200. OK.
Ensure that when consuming the webhook, the response is sent promptly to prevent a timeout.
The timeout period is set to 5 seconds.
Sample Webhooks
{
"eventName": "PURCHASED",
"data": {
"transactionType": "SALE",
"clientOrderId": "XXXXXXX",
"orderId": "111223",
"traceId": "8e86fd12-7314-4844-965e-f080ff599dee",
"midId": 111,
"netvalveMidId": "",
"responseTimestamp": "2025-10-30T06:52:46.440287045",
"transactionId": 12334,
"responseCode": "GTW_1000",
"responseMessage": "Transaction Approved/ Request Successful.",
"responseCodeType": "APPROVED",
"amount": 10.99,
"clientId": 123,
"callbackConfigurationId": 123,
"paymentType": "CARD",
"cardNumber": "555555******1234",
"cardType": "MASTERCARD",
"bankTransactionId": "1234356",
"schemeTransactionLinkIdentifier": "mastercard-tlid",
"authCode": "135226",
"cardExpiryMonth": "01",
"cardExpiryYear": "2029",
"paymentToken": "",
"siteId": "",
"paymentTokenType": ""
}
}
For Mastercard transactions, schemeTransactionLinkIdentifier contains the
Mastercard Transaction Link Identifier (TLID) when NetValve receives it from the
processor or when it was supplied in the original request. The field is optional
and may be omitted or returned as null when no TLID is available.
{
"eventName": "PURCHASE_FAILED",
"data": {
"transactionType": "SALE",
"clientOrderId": "12334",
"orderId": "111111",
"traceId": "f5b79bc9-2dc7-43a4-8159-93650ef69c81",
"midId": 111,
"netvalveMidId": "",
"responseTimestamp": "2025-11-04T11:45:00.74746222",
"transactionId": 12345,
"responseCode": "BNK_2011",
"responseMessage": "Insufficient Funds",
"responseCodeType": "SOFT DECLINE",
"amount": 21.99,
"clientId": 1,
"callbackConfigurationId": 1,
"paymentType": "CARD",
"cardNumber": "411111******1234",
"cardType": "VISA",
"bankTransactionId": "",
"cardExpiryMonth": "MM",
"cardExpiryYear": "YYYY"
}
}
{
"eventName": "CHARGEBACK",
"data": {
"transactionType": "SALE",
"clientOrderId": "XYZ",
"orderId": "1245",
"traceId": "8e86fd12-7314-4844-965e-f080ff599dee",
"midId": XX,
"netvalveMidId": "",
"responseTimestamp": "2025-11-03T13:40:14.217381437",
"transactionId": 5794411,
"responseCode": "GTW_1000",
"responseMessage": "",
"responseCodeType": "APPROVED",
"amount": 10.00,
"clientId": YY,
"callbackConfigurationId": 1234,
"cardNumber": "411111******1234",
"cardType": "VISA",
"bankTransactionId": "530306833326",
"authCode": "135226",
"chargebackTransactionType": "Ethoca",
"chargebackSource": "CB-Alert",
"cardExpiryMonth": "MM",
"cardExpiryYear": "YYYY"
}
}
Ethoca, RDR, Verify, TC40, InformAlert, Fraud, Chargeback
Handling Duplicates
You might get the same webhook event multiple times. This is normal because NetValve uses a special delivery method called "at-least-once delivery." This means, NetValve will keep sending the same event until your server successfully processes it and responds.
Even if your server accepts the event, it might not always respond in time (within 5 seconds). If this happens, NetValve will assume the event wasn't handled and send it again later.
Delivery Attempts and Retries
NetValve has two retry mechanisms when sending messages. The first retry mechanism is the instant retry. It is used when we are processing the message for the first time, and if its delivery fails, 3 more attempts will be made instantly. If the delivery still fails after all these attempts, the webhook message is then handled by the scheduled retry mechanism. It uses these intervals for delivery attempts:
- 15 minutes;
- 30 minutes;
- 1 hour;
- 2 hours;
- 4 hours;
- 8 hours;
- 16 hours;
- 24 hours.
Suspend/Disable
If the above attempts fail to deliver the webhook message after the first 24 hours, it will be moved to a suspend state. NetValve has multiple suspend intervals (1 day, 3 days, 5 days, 7 days); this means that after the first suspend state, the webhook message delivery will still be retried after 1, 3, 5 and 7 days. If after all these attempts the webhook message still remains undelivered, the callback configuration will be suspended and all the new webhook messages will be put on hold.
Events Order
Ideally, you should receive a webhook in the order in which the webhook events occur. However, you may not always receive the webhooks in this order.
Authentication
There are a couple of ways to verify the authentication of the webhook.
Custom Header / Custom Header Value
- When creating a new webhook, there is an option to provide authentication header name (
Custom Header) and value (Custom Header Value). - When the webhook request is sent to a given webhook URL, besides the request body with the transaction details, it also includes the provided custom header name and value.
- Based on those 2 parameters, it is possible to verify if the request is coming from a verified server machine.
- For per-order webhooks, set the header name and value on the request with
webhookData.headerandwebhookData.headerValue.
IP Address Restriction
Another mechanism of preventing requests from non-verified server machines is to allowlist the IPs of the NetValve webhook servers. See Environments & Identifiers for the full list of IPs for both production and sandbox.