# Webhooks

## Use incoming webhooks to get real-time updates

Listen for events on your [Blockchain.com Pay](https://docs.blockchain.com/pay/welcome-to-blockchain.com-pay) account so your integration can automatically trigger reactions.

### Why to use webhooks <a href="#webhooks-def" id="webhooks-def"></a>

You might want your applications to receive events as they occur in [Blockchain.com Pay](https://docs.blockchain.com/pay/welcome-to-blockchain.com-pay) accounts, so that your backend systems can execute actions accordingly.

### Setup

To enable webhook events, you need to register webhook endpoints. This is now setup manually by the account manager, but it will soon be possible to manage it via Partner Dashboard.&#x20;

Do you want to setup your webhook endpoint? [Get in touch](https://docs.blockchain.com/pay/welcome-to-blockchain.com-pay#getting-started-with-blockchain.com-pay) with an account manager by emailing [pay@blockchain.com.](mailto:pay@blockchain.com)

## Events

After you register webhooks endpoint, [Blockchain.com Pay](https://docs.blockchain.com/pay/welcome-to-blockchain.com-pay) can push real-time event data to your application’s webhook endpoint when events happen in [Blockchain.com Pay](https://docs.blockchain.com/pay/welcome-to-blockchain.com-pay) accounts. [Blockchain.com Pay](https://docs.blockchain.com/pay/welcome-to-blockchain.com-pay) uses HTTPS to send webhook events to your app as a `POST` request with JSON payload that includes an [Event object](#events).

Receiving webhook events are particularly useful for listening to asynchronous events, such as when a customer’s bank confirms a payment or crypto transaction bas been initiated to move funds to your customer's address.

Webhook events are delivered as HTTP `POST` request with JSON payload.

### Payload

Event object JSON payload will be as follows:

```json
{
  "eventId": "6733fc68-0dcb-421d-9bef-a50753853b67",
  "orderId": "f6fa33d1-b62c-4d59-8cbc-8e610020d635",
  "externalReference": "your-order-reference",
  "subPartnerId": "3rd-party-ref",
  "orderType": "BUY",
  "createdAt": "2023-11-15T14:43:06.894070237Z",
  "orderState": "COMPLETED",
  "orderStateUpdatedAt": "2023-11-15T14:44:06.894070237Z",
  "paymentMethod": "CARD",
  "inputCurrency": "EUR",
  "inputAmount": "100.00",
  "outputCurrency": "BTC",
  "outputAmount": "0.00000924",
  "processingFee": "0.10",
  "processingFeeUsd": "0.11",
  "partnerFee": "0.20",
  "partnerFeeUsd": "0.12",
  "networkFee": "1.50",
  "networkFeeUsd": "1.65",
  "network": "BTC",
  "userId": "16f59173-0607-40ed-92e2-6d4fc46d372c",
  "userCountry": "US",
  "userState": "US-FL",
  "targetWalletAddress": "bc1q6rru2g8w3r2ufxe76dal820tul5uhm7esystsv",
  "transactionHash": "385d7ec2e3be6650d487d7ede35e8ea33b889b49d2e04a522bce86608c1130dd"
}
```

Event payload will conform to [JSON schema](https://json-schema.org/) listed [at the bottom of the page](#event-payload-json-schema).

### States

Please refer to below diagram to understand order state transitions:

<figure><img src="https://3847274351-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfFgi7ALs9ucQXxMhB7PS%2Fuploads%2FVMuHmrr9b5i1IXiZLLyK%2Fimage.png?alt=media&#x26;token=9ff80c89-0487-45eb-831e-db5a849deb4c" alt="Order state transitions" width="188"><figcaption><p>Order state transitions</p></figcaption></figure>

Order state definitions:

* `PENDING` Order has been created and the payment is being processed.
* `WITHDRAWING` Order is in progress. Payment has completed and crypto transaction is in progress.
* `COMPLETED` Order successfully executed. Payment has been processed and crypto transaction has been confirmed with at least 1 confirmation.
* `FAILED` Order failed. The payment was rejected or never completed by the user.

### Delivery behaviour

#### Quick processing

Your [endpoint](https://stripe.com/docs/webhooks#example-endpoint) must quickly return a successful status code (`2xx`) prior to any complex logic that could cause a [timeout](#timeouts).

#### Timeouts

Webhook events that take longer than 5 seconds before returning a successful HTTP response are considered not delivered and will be subject to [retry mechanism](#retries).

#### Retries

If the webhook event fails delivery, it’s scheduled for retry for up to 3 days with an exponential back off. Other events won't be affected and will be delivered regardless of that.

#### Events ordering

Events for specific order will be delivered in the order of state changes. If there is a failed delivery in between, eg. event with `PENDING` state failed delivery, it will be scheduled for later retry. It may happen, that the order moves to `COMPLETED` state in the meantime. In this case, the `COMPLETED` state change webhook will be sent and you might observe `PENDING` state update to be delivered after `COMPLETED`.

Your endpoint shouldn’t expect delivery of webhooks events in order, and needs to handle delivery accordingly.

#### Duplicates

Webhook endpoints might occasionally receive the same event more than once. You can guard against duplicated event receipts by making your event processing [idempotent](https://en.wikipedia.org/wiki/Idempotence). One way of doing this is logging the events you’ve processed, and then not processing already-logged events.

Example scenario is when webhook delivery is partially successful (recorded on partner side but timed out on [Blockchain.com Pay](https://docs.blockchain.com/pay/welcome-to-blockchain.com-pay) side). In such a case, webhook is marked as undelivered and will be scheduled for delivery again.

#### Receive events with an HTTPS server <a href="#receive-events-with-an-https-server" id="receive-events-with-an-https-server"></a>

If you use an HTTPS URL for your webhook endpoint, [Blockchain.com Pay](https://docs.blockchain.com/pay/welcome-to-blockchain.com-pay) validates that the connection to your server is secure before sending your webhook data. For this to work, your server must be correctly configured to support HTTPS with a valid server certificate.

#### Verify events are sent from Blockchain.com <a href="#verify-events" id="verify-events"></a>

[Blockchain.com Pay](https://docs.blockchain.com/pay/welcome-to-blockchain.com-pay) sends webhook events from a set list of IP addresses. Only trust events coming from below list of IP addresses:

* `34.76.54.194`
* `34.77.167.89`
* `35.187.43.203`
* `35.241.153.74`
* `35.241.224.80`

### Event payload JSON schema

```json
{
  "$schema": "http://json-schema.org/draft-06/schema#",
  "$ref": "#/definitions/webhook-event-payload",
  "definitions": {
    "webhook-event-payload": {
      "type": "object",
      "title": "webhook-event-payload",
      "additionalProperties": false,
      "properties": {
        "eventId": {
          "type": "string",
          "format": "string",
          "description": "Unique identifier of the event"
        },
        "orderId": {
          "type": "string",
          "format": "string",
          "description": "Unique identifier of the order"
        },
        "externalReference": {
          "type": "string",
          "description": "An optional external order reference set by the partner. It is limited to 100 characters."
        },
        "subPartnerId": {
          "type": "string",
          "description": "An optional 3rd party reference set by the partner. It is limited to 50 characters."
        },
        "orderType": {
          "enum": [
            "BUY",
            "SELL"
          ],
          "description": "Type of the order. BUY for on-ramp, SELL for off-ramp"
        },
        "createdAt": {
          "type": "string",
          "format": "date-time",
          "description": "Timestamp of the event creation"
        },
        "orderState": {
          "enum": [
            "PENDING",
            "WITHDRAWING",
            "COMPLETED",
            "FAILED"
          ],
          "description": "Current state of the order"
        },
        "orderStateUpdatedAt": {
          "type": "string",
          "format": "date-time",
          "description": "Timestamp of the last order state change"
        },
        "paymentMethod": {
          "enum": [
            "CARD",
            "APPLE_PAY",
            "GOOGLE_PAY"
          ],
          "description": "Payment method used for the order"
        },
        "inputCurrency": {
          "type": "string",
          "description": "Currency code used for funding the order"
        },
        "inputAmount": {
          "type": "number",
          "description": "Amount of the input currency used for the order"
        },
        "outputCurrency": {
          "type": "string",
          "description": "Currency code of the output currency"
        },
        "outputAmount": {
          "type": "number",
          "description": "Amount of the output currency"
        },
        "amountUsd": {
          "type": "number",
          "description": "Amount of the transaction denominated in USD. Will be an approximate value in case of `inputCurrency` different than USD."
        },
        "processingFee": {
          "type": "number",
          "description": "Blockchain.com Pay processing fee denominated in `inputCurrency`"
        },
        "processingFeeUsd": {
          "type": "number",
          "description": "Blockchain.com Pay processing fee denominated in USD. Will be an approximate value in case of `inputCurrency` different than USD."
        },
        "partnerFee": {
          "type": "number",
          "description": "Partner fee denominated in `inputCurrency`"
        },
        "partnerFeeUsd": {
          "type": "number",
          "description": "Partner fee denominated in USD. Will be an approximate value in case of `inputCurrency` different than USD."
        },
        "networkFee": {
          "type": "number",
          "description": "Transaction network fee denominated in `inputCurrency`"
        },
        "networkFeeUsd": {
          "type": "number",
          "description": "Transaction network fee denominated in USD. Will be an approximate value in case of `inputCurrency` different than USD."
        },
        "network": {
          "type": "string",
          "description": "Blockchain network code used for the cryptocurrency transaction (e.g., BTC, ETH, BASE, MATIC, etc.)"
        },
        "userId": {
          "type": "string",
          "description": "Unique identifier of the user"
        },
        "userCountry": {
          "type": "string",
          "description": "Country code of the user address (2 letter ISO 3166-1 alpha-2 code). Example: US, GB, FR, DE, etc."
        },
        "userState": {
          "type": "string",
          "description": "State code of the user address (2 letter code prefixed with 2 letter country code and a hyphen). Will only be present for users in the US. Example: US-FL"
        },
        "targetWalletAddress": {
          "type": "string",
          "description": "Target wallet address of the crypto transaction"
        },
        "transactionHash": {
          "type": "string",
          "description": "Transaction hash of the crypto transaction. Will only be present for orders in COMPLETED state"
        }
      },
      "required": [
        "eventId",
        "orderId",
        "externalReference",
        "orderType",
        "createdAt",
        "orderState",
        "orderStateUpdatedAt",
        "paymentMethod",
        "inputCurrency",
        "inputAmount",
        "outputCurrency",
        "outputAmount",
        "processingFee",
        "processingFeeUsd",
        "partnerFee",
        "partnerFeeUsd",
        "networkFee",
        "networkFeeUsd",
        "userId",
        "targetWalletAddress"
      ]
    }
  }
}

```
