Skip to main content

Endpoint URL

The webhook subscription endpoint URL configured to receive the webhooks should be a HTTPS endpoint that supports TLS 1.2. Please ensure your Web Application Firewall (WAF) does not block the webhook requests.

Webhook logic

  • Response time: The endpoint URL configured to receive the webhooks should return an HTTP response in the 200-299 range within 5000 milliseconds.
  • Retry: The webhook event is retried if the merchant endpoint does not respond with a 2XX or times out. Retries are made with an exponential delay for a maximum of 7 days from the point of creation. If the request is not successful after this period then it is dropped and lost.
  • Delivery promise: Currently no guarantee is provided as to the delivery time between an event occurring in the system and it being delivered via a webhook to the merchant.
  • Caching: Webhook settings may be cached for a short period so changes may not be reflected immediately.

Acknowledging webhooks

When you receive a webhook event, you should always acknowledge its receipt, even if it contains additional information. To acknowledge a webhook, an HTTP response in the 200-299 range within 5000 milliseconds is expected. Any unacknowledged webhooks are retried and might cause delay in further webhook delivery.
Please note that the content of a webhook event can change as more features are added. The addition of additional fields or enum values is not considered a backwards incompatible change. Setting any JSON parser to ignore any unrecognized fields and values is recommended.

Split authorization and capture

In certain scenarios, when the intent for a transaction is set to capture, the system splits the operation into a separate authorization and capture. This means the payment is first authorized with the payment service, and then captured in a subsequent request. A capture is split into two operations when all of the following conditions are met:
  1. The transaction intent is set to capture.
  2. The payment service (connector) supports delayed captures.
  3. The payment method is a card and is not using an alternative payment scheme.
  4. At least one of the following is true:
    • The payment service does not support direct capture (sale).
    • The anti-fraud decision for the transaction was review.
    • Gift cards were used as part of the transaction (multi-tender).
When a transaction is split, the authorization is performed first because it is the most likely step to fail. If the authorization succeeds, the capture follows automatically. If any additional step fails (for example, gift card redemption), the authorization is voided instead of requiring a refund. As a consequence, this sometimes results in multiple webhooks per transaction. In a normal situation, you would only receive a transaction.captured event, but when a capture is split you may receive a transaction.authorized webhook first, followed by a transaction.captured event. This same order of events happens when the async_capture property is set to true in the transaction request, as this always handles the capture asynchronously. If a capture request to the payment service times out, Gr4vy can retry the capture in the background, depending on the connection. See capture timeouts.

Missed webhooks

Gr4vy retries a webhook only until your endpoint acknowledges it. Once your endpoint responds with a 2XX status, the delivery is complete and Gr4vy can’t send that webhook again. Gr4vy doesn’t provide a delivery log or a way to replay webhooks. If you think you missed an event, fetch the current state of the resource from the API. For example, get the transaction or list its refunds. Every webhook request includes an X-Gr4vy-Webhook-ID header. Its value matches the id in the payload and stays the same across retries and across your webhook subscriptions. Use it to search your own logs and to ignore duplicate deliveries.
The Webhook processed entries in a transaction’s events in the dashboard are notifications that Gr4vy received from the payment service. They don’t show deliveries to your webhook endpoint.

Refunds

A refund doesn’t change the transaction’s status. Gr4vy sends refund.* events for a refund but no transaction.* event, so the refunded_amount in the last transaction webhook you received doesn’t reflect the refund. To get the current refunded_amount, fetch the transaction from the API. A refund isn’t always final when you first receive it.
  • Some payment services complete a refund asynchronously. Gr4vy sends refund.pending, and the refund keeps the processing status until the payment service confirms it. Gr4vy then sends refund.succeeded, refund.declined, or refund.failed.
  • Some payment services report a refund as succeeded and later report that it failed, for example when the issuer rejects it. The refund’s status then changes to failed, and Gr4vy sends a refund.failed event after the earlier refund.succeeded.
A declined refund was refused by the payment service. A failed refund couldn’t be completed because of an error, or failed after the payment service first accepted it. Create refunds through the Gr4vy API or dashboard. A refund made directly in the payment service’s dashboard isn’t recorded in Gr4vy, so the transaction’s refunded_amount doesn’t change and Gr4vy sends no refund.* event for it. To help a buyer trace a refund, share the refund’s payment_service_refund_id. This is the payment service’s own ID for the refund. The refund id is only known to Gr4vy and to you.

Captured transactions

Once a transaction reaches capture_succeeded, its status doesn’t change again. Later notifications from the payment service, such as a pending or error notification for the same payment, don’t move the transaction back to an earlier status. Refunds don’t change the status either.

Transaction sync

When you sync a transaction and the sync changes its status, Gr4vy sends the matching transaction webhook, for example transaction.captured. A sync that doesn’t change the status doesn’t send a webhook.

Modifying webhooks

If you need to change a webhook subscription, for example the endpoint or authentication, it is strongly recommended that you allow for the processing of both the new and old values so that no messages are dropped. For example, if you were to update the endpoint;
  1. Merchant updates their server to process webhooks on https://new.webhooks.com
  2. Merchant updates the webhook subscription settings from https://old.webhooks.com to https://new.webhooks.com
  3. Merchant processes webhooks on https://old.webhooks.com & https://new.webhooks.com
  4. Merchant removes https://old.webhooks.com once all messages have been processed