# Integrating into Webhooks Use webhooks to subscribe to automated notifications (also known as events) from Finix. When an event is triggered, Finix sends an HTTP `POST` request to the endpoint URL configured in the webhook. Rather than requiring your servers manually poll Finix's API to learn about changes to your resources, webhooks ***push*** notifications to the endpoint URL to notify you proactively. With webhooks, you can keep up with asynchronous state changes. Examples of changes include: - `Transfer` is created. - `Merchant` is approved. - `Disputes` are won. ## Managing Webhooks via API Finix lets you create and update webhooks with Finix's API. This can be helpful for companies that want to manage webhook through their own dashboard or developer tools. When you create a webhook via API, Finix will send an empty test event to the endpoint URL configured in the webhook. The configured URL must respond to this event successfully to let Finix know the URL is valid, at which point Finix will enable the webhook. See [Validating Webhooks](#validating-webhooks) for more information. ### Creating Webhooks To create a webhook, send a `POST` request to Finix's `/webhooks` endpoint. ```json Request to Create Webhook curl "https://finix.sandbox-payments-api.com/webhooks" \ -u USsRhsHYZGBPnQw8CByJyEQW:8a14c2f9-d94b-4c72-8f5c-a62908e5b30e \ -H 'Accept: application/hal+json' \ -H 'Content-Type: application/json' \ -H 'Finix-Version: 2022-02-01' \ -X POST \ -d '{ "url": "https://webhook.site/73b2d0d3-8cc3-4003-857d-2e3a137887ce" }' ``` ```json Created Webook { "id": "WHid2GDsvQaHhnLQa1HCjNiR", "created_at": "2024-12-31T15:11:43.41Z", "updated_at": "2024-12-31T15:11:43.41Z", "application": "APgPDQrLD52TYvqazjHJJchM", "authentication": { "type": "NONE" }, "enabled": true, "enabled_events": [], "is_accepting_events": true, "nickname": null, "previous_secret_expires_at": null, "secret_signing_key": "1676b0aa7f96e7f2cb3ef92ea266a13a534ad06593e930152343a36d14bdc3c5", "url": "https://webhook.site/************************************", "_links": { "self": { "href": "https://finix.sandbox-payments-api.com/webhooks/WHid2GDsvQaHhnLQa1HCjNiR" }, "application": { "href": "https://finix.sandbox-payments-api.com/applications/APgPDQrLD52TYvqazjHJJchM" } } } ``` ### Authenticating Webhooks When creating a webhook, specify the authentication type (`authentication.type`) that Finix should use when sending events to the endpoint URL. When you add an authentication type, Finix will add an Authorization header to events sent to the configured endpoint URL. Your server can use the Authorization header to verify that the event came from Finix. Finix supports two authentication types: 1. **Basic Authentication:** Finix will send the webhook event with [Basic Authentication](#basic-authentication). 2. **Bearer Token Authentication:** Finix will send the webhook with a [Bearer Token](#bearer-token). #### Basic Authentication Finix uses the standard [Basic authentication](https://en.wikipedia.org/wiki/Basic_access_authentication) format. When you set `authentication.type` to `BASIC`, each webhook event is sent with a `Authorization` header formatted as `Authorization: Basic `. When creating the webhook, you will include `username` and `password` values that Finix will use for the `Authorization` header. ```json Request to Create Webhook with Basic Authentication curl "https://finix.sandbox-payments-api.com/webhooks" \ -u USsRhsHYZGBPnQw8CByJyEQW:8a14c2f9-d94b-4c72-8f5c-a62908e5b30e \ -H 'Accept: application/hal+json' \ -H 'Content-Type: application/json' \ -H 'Finix-Version: 2022-02-01' \ -X POST \ -d '{ "authentication": { "type": "BASIC", "basic": { "username": "USsRhsHYZGBPnQw8CByJyEQW", "password": "8a14c2f9-d94b-4c72-8f5c-a62908e5b30e" } }, "url": "https://webhook.site/73b2d0d3-8cc3-4003-857d-2e3a137887ce" }' ``` To create the `Authorization` header included in events sent to that URL, Finix: 1. Combines the `username` and `password` with a colon (e.g., `USsRhsHYZGBPnQw8CByJyEQW:8a14c2f9-d94b-4c72-8f5c-a62908e5b30e`) 2. Base64-encodes the string (e.g., `VVNzUmhzSFlaR0JQblF3OENCeUp5RVFXOjhhMTRjMmY5LWQ5NGItNGM3Mi04ZjVjLWE2MjkwOGU1YjMwZQ==`) 3. Adds the value to the Authorization Header with the Basic scheme (e.g, `Authorization: Basic` `VVNzUmhzSFlaR0JQblF3OENCeUp5RVFXOjhhMTRjMmY5LWQ5NGItNGM3Mi04ZjVjLWE2MjkwOGU1YjMwZQ==`) #### Bearer Token Authentication Finix supports sending [OAuth 2.0 Bearer Tokens RFC 6750](https://www.rfc-editor.org/rfc/rfc6750). These are opaque strings that is up to the server to interpret. When you set `authentication.type` to `BEARER`, each webhook event is sent with a `Authorization` header formatted as `Authorization: Bearer `. With Bearer Token-authenticated webhooks, Finix sends events with tokens exactly as you provided. It is up to your system to perform any further calculation or validation of the value. ```json Request to Create Webhook with Basic Authentication curl "https://finix.sandbox-payments-api.com/webhooks" \ -u USsRhsHYZGBPnQw8CByJyEQW:8a14c2f9-d94b-4c72-8f5c-a62908e5b30e \ -H 'Accept: application/hal+json' \ -H 'Content-Type: application/json' \ -H 'Finix-Version: 2022-02-01' \ -X POST \ -d '{ "authentication": { "type": "BEARER", "bearer": { "token": "U3VwZXIgc2VjcmV0IGVuY29kZWQgdG9rZW4=" } }, "url": "https://webhook.site/73b2d0d3-8cc3-4003-857d-2e3a137887ce" }' ``` From this example, your server will receive events with the header `authorization: Bearer U3VwZXIgc2VjcmV0IGVuY29kZWQgdG9rZW4=`. ### Filtering Webhooks When configuring webhooks, it is common for customers to subscribe to ***all*** event types and ignore those they do not care about. However, Finix does support subscribing to only specific webhook events through the Webhook's `enabled_events` field. To filter the events sent to a webhook, create or update the `Webhook` with the `enabled_events` you want to receive. In this example, we'll update an existing webhook to receive 3 events: Transfer Created, Merchant Created, and Merchant Underwritten. ```json Filtering Webhooks curl "https://finix.sandbox-payments-api.com/webhooks/WHid2GDsvQaHhnLQa1HCjNiR" \ -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"] } ] }' ``` ```json Webhook with Enabled Events Set { "id": "WHid2GDsvQaHhnLQa1HCjNiR", "created_at": "2024-12-31T15:11:43.41Z", "updated_at": "2024-12-31T15:12:13.22Z", "application": "APgPDQrLD52TYvqazjHJJchM", "authentication": { "type": "NONE" }, "enabled": true, "enabled_events": [ { "entity": "transfer", "types": ["created"] }, { "entity": "merchant", "types": ["created", "underwritten"] } ], "is_accepting_events": true, "nickname": null, "previous_secret_expires_at": null, "url": "https://webhook.site/************************************", "_links": { "self": { "href": "https://finix.sandbox-payments-api.com/webhooks/WHid2GDsvQaHhnLQa1HCjNiR" }, "application": { "href": "https://finix.sandbox-payments-api.com/applications/APgPDQrLD52TYvqazjHJJchM" } } } ``` See [Webhook Events](/additional-resources/developers/webhooks/webhook-events) for the full list of events you can subscribe to. ### Validating Webhooks When you create a webhook via API, Finix will send an empty test event to the endpoint URL configured in the webhook. The configured URL must respond to this event successfully to let Finix know the URL is valid, at which point Finix will enable the webhook. If your URL does not respond to the event successfully, Finix will synchronously respond to your webhook creation request with an error. ```json Unsuccessful Webhook { "total": 1, "_embedded": { "errors": [ { "logref": "b3abf6fae189d7ce", "message": "Failed to create webhook. Unable to call the configured URL with an empty payload. Received Response Code: {404}", "code": "INVALID_FIELD", "_links": { "self": { "href": "https://finix.sandbox-payments-api.com/notification/webhooks" } } } ] } } ``` ### Disabling Webhooks You can disable existing webhooks by setting `enabled: false` in `PUT` requests. ```json Update an Existing Webhook curl "https://finix.sandbox-payments-api.com/webhooks/WHLvrRTUcHYReDCMuuvKLxj" \ -H "Content-Type: application/json" \ -H 'Finix-Version: 2022-02-01' \ -u USsRhsHYZGBPnQw8CByJyEQW:8a14c2f9-d94b-4c72-8f5c-a62908e5b30e \ -X PUT \ -d '{ "enabled": false }' ``` ## Managing Webhooks via Dashboard Finix also supports creating and updating webhooks through the Finix Dashboard. The dashboard provides the same webhook configuration options as you get [via API](#managing-webhooks-via-api): - **Set URL**: Set the URL you'd like Finix to send webhooks to. - **Set Authentication**: Choose between Basic, Bearer, or no authentication. - **Filter Events**: Subscribe to all events, or choose the specific events you'd like to subscribe to. - **Update Webhooks**: Update existing webhooks (e.g., change the URL or events). - **Disable Webhooks**: Disable existing webhooks you no longer use. ### Viewing Webhooks To create or update webhooks in the dashboard, navigate to **Developer > Webhooks**. There, you will see a list of all webhooks you have created. You will be able to create new webhooks as well as update existing ones. ![Webhooks List](/assets/webhooks-list-page.38212d74a4e118f096a0542920c4e28fd362298d084ef14f2cf007f35028b133.08ff7529.png) ### Creating Webhooks Click **Create Webhook** to create a new webhook. You'll set the URL, Authentication Type, and Events you'd like to subscribe to. For the full list of events, see [Webhook Events](/additional-resources/developers/webhooks/webhook-events) or create your own webhook with the dashboard. ![Webhooks Create](/assets/webhooks-create.55a2eb9be0986741c30664addba75c4cfaf4568100c3c0bd4bd1ccbe39b8e1f0.08ff7529.png) ![Webhooks Events](/assets/webhooks-create-events.4aaa357be40a4828c5a3661eceee7450ae148dfcec76bfc59c07dde77bc8e98d.08ff7529.png) ### Editing Webhooks Under **Developer > Webhooks**, navigate to one of your webhook events to view it's current settings. On that page, you can also **Edit** or **Disable** the webhook (for example, to update the events the webhook subscribes to). ![Webhooks Edit](/assets/webhooks-edit.1a6dffa88a244fdfd6e318a8311052ad7ed40a9f974d7653344b8254f7bb2773.08ff7529.png) ## Delivery Attempts and Retries Finix attempts to send individual webhook events 10 times. However, the event won't get sent again after 5 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). Disabling Webhooks in Sandbox 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 Schedule | 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 | ## Frequently Asked Questions ### Can I view all the webhook events Finix has sent? Yes, the Finix Dashboard offers a Webhooks Log that lists all the webhook events Finix has sent in the past 30 days. For more information, see [Webhook Logs](/additional-resources/developers/webhooks/webhook-logs). ### Can I manage webhooks on the Finix Dashboard? Yes, the Finix dashboard lets you view, create, update, and disable webhooks. For more information, see [Managing Webhooks via Dashboard](#managing-webhooks-via-dashboard). ### 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. See [Delivery Attempts and Retries](#delivery-attempts-and-retries) for more information. ### Is Finix sending any confidential information? I’d like to know if using a public service, like [https://pipedream.com](https://pipedream.com), is an option to test webhooks Yes, you can use public services like [https://pipedream.com](https://pipedream.com) to test webhooks. We won’t ever send sensitive credit card data, but will return less sensitive PII such as birthdates and addresses. For additional details on the specific data sent back, you can review our list of [sample webhook events](/additional-resources/developers/webhooks/webhook-events#sample-payloads). ### Is there a list of all the webhook events? Yes, see [Webhook Events](/additional-resources/developers/webhooks/webhook-events) to view the full list of webhook events Finix offers. #### 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](/additional-resources/developers/webhooks/webhook-events) to view the full list of webhook events Finix offers. ### 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. ```json Example Webhook { "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](/additional-resources/developers/webhooks/webhook-events#authorization-created) 2. [Transfer (e.g. debit, refund, credit)](/additional-resources/developers/webhooks/webhook-events#transfer-updated) ### 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](#authenticating-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](#delivery-attempts-and-retries). ### Why do I receive so many or so few 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](/additional-resources/developers/webhooks/integrating-into-webhooks#filtering-webhooks) to filter out unnecessary events.