Webhooks

Listen to webhooks so you can react to events from Finix.


Use webhooks to subscribe to automated notifications (also known as events) from Finix.

When an event is triggered, an HTTP POST payload gets sent to the endpoint URL configured in the webhook. So instead of manually pulling information from Finix's API, webhooks push notifications to the endpoint URL.

With webhooks, you can keep up with asynchronous state changes. These changes include:

  • Transfers are created.
  • Provisioning Merchant accounts.
  • Events for newly created Disputes .

Creating Webhooks

You can create webhooks using Finix's API.

When a webhook gets created, Finix sends an empty test event to the endpoint URL configured in the webhook.

The endpoint URL you use needs to respond to this empty event with a 200 HTTP code to let Finix know you received the event and the endpoint URL is valid. If the endpoint URL is validated, a successful response will return, and the webhook will be enabled.

For this example, we are going to Create a Webhook that is using basic authentication:

Copy
Copied
curl https://finix.sandbox-payments-api.com/webhooks \
    -H "Content-Type: application/json" \
    -H 'Finix-Version: 2022-02-01' \
    -u USsRhsHYZGBPnQw8CByJyEQW:8a14c2f9-d94b-4c72-8f5c-a62908e5b30e \
    -d '
    {
      "authentication": {
        "type": "BASIC",
        "basic": {
          "username": "basic-auth-username",
          "password": "basic-auth-password"
        }
      },
      "url": "https://httpbin.org/post"
    }'

A successful response returns 201 and the newly created Webhook.

Copy
Copied
{
    "id": "WH45nNmPR8LEETsregWNnHZz",
    "created_at": "2022-10-10T04:36:24.56Z",
    "updated_at": "2022-10-10T04:36:24.56Z",
    "application": "APgPDQrLD52TYvqazjHJJchM",
    "authentication": {
        "type": "BASIC"
    },
    "enabled": true,
    "enabled_events": [],
    "previous_secret_expires_at": null,
    "secret_signing_key": "56e4a45dee284e173f0468fc066d47090e436e60e8969bc850b5893174a81fba",
    "url": "https://httpbin.org/post",
    "_links": {
        "self": {
            "href": "http://finix.sandbox-payments-api.com/webhooks/WH45nNmPR8LEETsregWNnHZz"
        },
        "application": {
            "href": "http://finix.sandbox-payments-api.com/applications/APgPDQrLD52TYvqazjHJJchM"
        }
    }
}

Authenticating Webhooks

When creating a webhook, specify the Authentication Type Finix should use when sending events to the endpoint URL.

Including an Authentication type adds an Authorization header to every event sent to the configured endpoint URL. You can verify the Authorization header to ensure the event came from Finix.

There are two authentication types that Finix supports:

Basic Authentication

Finix uses the standard Basic authentication format. When this is enabled, each webhook event is sent with a Authorization header with the following format:

Authorization: Basic <formatted credentials>

The formatted credentials are calculated by the following:

  1. Combine the username and password with a colon: example_username:A1B2C3RANDOMPASSC3B2A1
  2. Base64 encode the resulting string: ZXhhbXBsZV91c2VybmFtZTpBMUIyQzNSQU5ET01QQVNTQzNCMkExCg==

The resulting Authorization header would look like: Authorization: Basic ZXhhbXBsZV91c2VybmFtZTpBMUIyQzNSQU5ET01QQVNTQzNCMkExCg==

Bearer Token

Finix supports sending OAuth 2.0 Bearer Tokens RFC 6750. These are opaque strings that is up to the server to interpret. When using Bearer token authentication, Finix sends a token exactly as you provided. Finix sends an Authorization header with the following format:

Authorization: Bearer <token you provided>

Because there are many variation on how Bearer tokens are sent, we can only send tokens as is. It is up to your system to perform any further calculation or validation of the value.

Delivery Attempts and Retries

Finix attempts to send individual webhook events ten times. However, the event won't get sent again after five attempts.

After an extended period, if an endpoint URL hasn't accepted any events or responded with a successful 2xx HTTP status code Finix will disable the webhook and proactively reach out to you about how the webhook is configured (sandbox only).

Verifying webhooks work in your sandbox environment helps you confirm your webhook implementation is working before moving it to your live environment. Please note that Finix will not disable webhooks configured in live environments.

Retry Count Minutes After Previous Attempt
1 1.5 minutes
2 2 minutes
3 3 minutes
4 5 minutes
5 9 minutes
6 17 minutes
7 33 minutes
8 65 minutes
9 129 minutes
10 257 minutes

Webhook Event Filtering

When accepting webhooks, commonly our customers will receive all webhooks and ignore the events they don't care about. We also offer the option to have Finix perform some up front filtering via the enabled_events parameter on the webhook.

To filter the events sent to a webhook, create or update the Webhook with the enabled_events you want to receive. Please note:

  • ROLE_PLATFORM credentials receive all the webhook events sent to onboarded Applications .
  • ROLE_PARTNER credentials only receive the webhook events related to the Application the credentials were created under.

This example updated a webhook to only receive created event for Transfers, and the created and underwritten event forMerchants .

Copy
Copied
curl https://finix.sandbox-payments-api.com/webhooks/WHtPXJnAjmusyobzpmQZeHvJ \
    -H "Content-Type: application/json" \
    -H 'Finix-Version: 2022-02-01' \
    -u  USsRhsHYZGBPnQw8CByJyEQW:8a14c2f9-d94b-4c72-8f5c-a62908e5b30e \
    -X PUT \
    -d '{
    "enabled_events": [
        {
            "entity": "transfer",
            "types": [
                "created"
            ]
        },
        {
            "entity": "merchant",
            "types": [
                "created",
                "underwritten"
            ]
        }
    ]
}'

The successful response returns the webhooks resource.

Copy
Copied
{
    "id": "WHtPXJnAjmusyobzpmQZeHvJ",
    "created_at": "2022-06-05T23:29:07.99Z",
    "updated_at": "2022-10-10T04:36:45.88Z",
    "application": "APgPDQrLD52TYvqazjHJJchM",
    "authentication": {
        "type": "NONE"
    },
    "enabled": false,
    "enabled_events": [
        {
            "entity": "transfer",
            "types": [
                "created"
            ]
        },
        {
            "entity": "merchant",
            "types": [
                "created",
                "underwritten"
            ]
        }
    ],
    "previous_secret_expires_at": null,
    "url": "https://eohzjuj2prziycz.m.pipedream.net",
    "_links": {
        "self": {
            "href": "http://finix.sandbox-payments-api.com/webhooks/WHtPXJnAjmusyobzpmQZeHvJ"
        },
        "application": {
            "href": "http://finix.sandbox-payments-api.com/applications/APgPDQrLD52TYvqazjHJJchM"
        }
    }
}

See Webhook events for a list of events.

Frequently Asked Questions

Can I manage Webhooks on the Finix Dashboard?

Yes, a Webhook log detailing all the events that have been received is available on the Finix Dashboard.

After logging in, click Developer > Webhook Logs.

Log

For more details, see Managing Webhooks.

Will I receive a request for each event, or will I receive them in batches?

You will receive a request for each individual event. Webhooks created at the Application level receive any state change under an Application. These changes include a change in state for a Transfer, Merchant account provisioning, and Disputes.

Is there a specific time when events get sent?

An event gets sent any time a state change occurs in our database; this helps make webhook events as real-time as possible.

What type of response should we send? Is there a way to notify Finix that an event got received successfully?

Any 2xx HTTP code will let Finix know the event got successfully received.

If we don't receive the event, will it be sent again? What type of response/exception should I send?

Yes, if no response gets received from the endpoint, the webhook automatically replays and re-sends the event.

Is Finix sending any confidential information? I’d like to know if using a public service, like https://pipedream.com, is an option to test webhooks.

Yes, you can use https://pipedream.com to test webhooks. We won’t ever send sensitive credit card data but will return DOBs and addresses. You can review our list of sample webhook events.

Is there a list of all the webhook events?

Yes, here’s a list of every webhook event Finix sends.

Does Finix release new events?

Occasionally Finix will release new events to ensure devs can receive alerts about any corner of our API. Webhooks subscribed to All Events automatically get subscribed to these new events.

See Webhook Events for a full list of every event Finix sends.

Is it possible to include a unique ID in each request? I want to make sure the same event isn't processed twice.

Every event your Webhook URL receives includes a unique event#id, which you can use to verify none of the events are duplicates.

Example Event
Copy
Copied
{
  "id": "event_cgGzzdKrV3fbsd74ugymaX",
  "type": "updated",
  "entity": "transfer",
  "occurred_at": "2023-01-05T21:58:48.022174",
  "_embedded": {
    "transfers": [
      {
        "fee": 0,
        "destination": null,
        "created_at": "2023-01-05T21:58:27.26Z",
        "failure_message": null,
        "source": "PI6fBxWjm2GfdhCughovSWQr",
        "type": "DEBIT",
        "additional_buyer_charges": null,
        "statement_descriptor": "FNX*FINIX FLOWERS",
        "additional_healthcare_data": null,
        "updated_at": "2023-01-05T21:58:28.21Z",
        "subtype": "API",
        "amount_requested": 662154,
        "currency": "USD",
        "id": "TR3CpnVVxM1iapJgxdyb5Hsz",
        "state": "SUCCEEDED",
        "idempotency_id": null,
        "amount": 662154,
        "failure_code": null,
        "trace_id": "97083fa0-712f-489d-bf38-bda18825f966",
        "address_verification": null,
        "security_code_verification": null,
        "raw": null,
        "merchant": "MU7cXuKj2xx41hhZZi6bZ13A",
        "merchant_identity": "IDvHGrfeVmB3i7uL78xjemNk",
        "tags": {},
        "ready_to_settle_at": null,
        "application": "APgPDQrLD52TYvqazjHJJchM",
        "externally_funded": "UNKNOWN",
        "messages": []
      }
    ]
  }
}

Is there a processor transaction ID that gets sent with each event? I need a way to consolidate our transactions using the information received from the event.

Use the resource ID’s in each response to consolidate events. For example:

  1. Authorization
  2. Transfer (e.g. debit, refund, credit)

Do we need to whitelist a specific IP address?

We submit requests from multiple IP addresses.

How do I verify the event is from Finix?

Authenticate your webhooks so events include an authorization header. Refer to the authorization header to confirm that events are from Finix.

If I change the endpoint URL of a webhook, will there be a delay before events get sent to the new URL? Can we deactivate the old endpoint URL immediately, or do we need to wait?

There shouldn’t be any delay. To prevent migration issues, you can enable multiple at the same time. You can immediately deactivate the old endpoint URL and disable the old webhook.

How many times will you try to send a webhook that fails?

Finix makes at least ten attempts to retry sending a Webhook event according to the schedule below. If your webhook destinations server is unavailable, or if the webhook fails after the multiple attempts, Finix will stop trying to deliver the webhook.

For more details, see Delivery Attempts and Retries.

Why do I receive so many/little events?

The events you receive depend on the credentials used to create the Webhook:

  • ROLE_PLATFORM credentials receive every webhook event sent to onboarded Applications .
  • ROLE_PARTNER credentials only receive the webhook events related to the Application the credentials were created under.

To change how many events you receive, you can either:

  • Create a new Webhook using the necessary credential level.
  • Use Webhook Event Filtering to filter out unnecessary events.