Webhooks

Mercuryo sends JSON POST notifications to the callback URL configured with your integration manager. Payment and refund notifications use the same envelope and signature. Notifications can also report an intermediate status; their status is a snapshot and may already be older than the current GET status response.

  • Signature. Verify the X-Signature header as the HMAC-SHA256 of the received JSON data object using your Sign Key. See Authentication & Signature. The content type is application/json.
  • Acknowledgement. Respond with any 2xx once you have processed the notification or stored it durably; answer duplicates the same way. On a delivery failure or a non-2xx response, delivery is retried with increasing delay.
  • Duplicates. The same notification can arrive more than once, with the same eventId when a delivery is retried. Process each operation and its status changes idempotently, including notifications received after your own timeout. Do not assume that a newly generated notification for the same operation will always reuse an earlier eventId.

Payment webhook

Use Payment statuses to handle final outcomes and required actions. For a Google Pay redirect_pending notification, query GET status to obtain the current state and redirect_data, then follow the 3DS flow if a redirect is still required. The webhook itself does not contain redirect_data.

Example of a completed Apple Pay payment (method_code is google for Google Pay):

{
  "data": {
    "amount": "10.00000000",
    "fiat_amount": "10.00",
    "id": "28a3c125a28075453",
    "type": "buy",
    "merchant_transaction_id": "order-8841",
    "currency": null,
    "network": null,
    "fiat_currency": "USD",
    "payment_method": "mobile_pay",
    "method_code": "apple",
    "status": "paid",
    "user": {
      "country_code": "",
      "email": "john.doe@example.com",
      "uuid4": "8eb1b522f60d11fa897de1dc6351b7e8"
    },
    "tx": {
      "id": "28a3c125a28075453"
    },
    "fee": null,
    "partner_fee": null,
    "rate": null,
    "card_masked_pan": null,
    "contract_address": null,
    "created_at": "2026-07-07 12:32:47",
    "created_at_ts": 1783427567,
    "updated_at": "2026-07-07 12:35:04",
    "updated_at_ts": 1783427704,
    "masked_dpan": "424242******4242"
  },
  "eventId": "3f9a1b2c4d5e6f78"
}

Refund webhook (type: refund)

A refund notification reports the refund operation's final status (succeeded or failed). data.id is the refund id and data.merchant_transaction_id is your merchant_refund_id. The tx.related_id and tx.related_merchant_trx_id fields identify the original payment. Field order is not guaranteed.

{
  "data": {
    "id": "c9051779-c818-4edb-8133-2e309f70f484",
    "type": "refund",
    "merchant_transaction_id": "refund-1",
    "status": "succeeded",
    "amount": "5.00000000",
    "fiat_amount": "5.00",
    "fiat_currency": "USD",
    "payment_method": "mobile_pay",
    "method_code": "apple",
    "user": {
      "email": "john.doe@example.com",
      "country_code": "",
      "uuid4": "8eb1b522f60d11fa897de1dc6351b7e8"
    },
    "tx": {
      "id": "c9051779-c818-4edb-8133-2e309f70f484",
      "related_id": "28a3c125a28075453",
      "related_merchant_trx_id": "order-8841"
    },
    "created_at": "2026-07-07 12:32:47",
    "created_at_ts": 1783427567,
    "updated_at": "2026-07-07 12:35:04",
    "updated_at_ts": 1783427704
  },
  "eventId": "f3a91c2b7d0e845a11"
}

If an expected result does not arrive, follow the timeout guidance or contact support with the refund id. A local timeout is not a failed-operation notification.