Working with Webhooks
Implement simple, real-time, event notifications regarding account and transaction status, and more.
Overview
A webhook is a means of notifying your application of the occurrence of an event with some relevant information. Events are created each time a resource is created or updated in Dwolla. For example, when a Customer is created or a Funding Source is removed, a customer_created
and customer_funding_source_removed
event will be created, respectively. These events are what trigger HTTP webhook requests to your subscribed URL if you have an active webhook subscription. It is important to note that a single API request can trigger multiple webhooks to be fired, e.g. initiating a transfer from an Account to Customer can create the events transfer_created
and customer_transfer_created
.
API Reference
Check out our API reference for an exhaustive list of all possible events.
Webhook Event
Each webhook contains an Event with _links
to the following resources:
- The unique event itself
- The Dwolla Account associated with the event
- The Resource associated with the event
- The Customer that the resource relates to (if applicable)
Example webhook payload:
Webhook Events
For detailed information on Dwolla’s webhook request structure, refer to the Webhook Events resource.
What to Know About Dwolla Webhooks
- Each application can have multiple webhook subscriptions associated with it. While one subscription is sufficient, you can create up to five in Production and ten in for redundancy.
- Webhooks are sent asynchronously and are not guaranteed to be delivered in order. We recommend that applications protect against duplicated events by making event processing idempotent.
- Your application will need to respond to Dwolla webhook requests with a 200-level HTTP status code within 10 seconds of receipt. Otherwise, the attempt will be counted as a failure and Dwolla will retry sending the webhook according to the back-off schedule.
- If there are 400 consecutive failures, and it has been 24 hours since your last success, your webhook subscription will be automatically paused and an email will be sent to the Admin of the Dwolla account. After fixing the issue that is causing the failures, you can unpause the webhook subscription either via your Dashboard or Dwolla’s API in order to continue receiving new webhooks and to retry failed webhooks.
Getting Started
In this guide we will walk through creating a webhook subscription along with validating and processing webhook requests.
You will need to have a Sandbox account already set up. Although not required, this guide assumes that you have some familiarity with Amazon Web Services (AWS); specifically Lambda and SQS, or other similar services.
Step 1 - Create a Webhook Subscription
First, you will need to have a URL that is publicly accessible where Dwolla can send webhooks in the form of HTTP requests. This also means that anyone on the Internet can hit your endpoint. As such, here are some security concerns:
- Your webhook endpoint should only be accessible over TLS (HTTPS) and your server should have a valid SSL certificate.
- Your subscription should include a random, secret key, only known by your application. This secret key should be securely stored and used later when validating the authenticity of the webhook request from Dwolla.
Request Parameters
Parameters | Required | Type | Description |
---|---|---|---|
url | yes | string | The publicly-accessible URL where Dwolla should deliver the webhook notification. |
secret | yes | string | A random, secret key, only known by your application. This secret key should be securely stored and used later when validating the authenticity of the webhook from Dwolla. |
Request and Response
When the webhook subscription is created, you will receive a 201 Created
HTTP response with an empty response body. You can refer to the Location
header to retrieve a link to the newly-created subscription.
Webhook Subscription Resource
Parameter | Description |
---|---|
id | Unique webhook subscription identifier assigned by Dwolla. |
url | Subscribed URL where Dwolla will deliver webhook notifications. |
paused | A boolean true or false value indicating if a webhook subscription is paused. A webhook subscription will be automatically paused after 400 consecutive failures. In addition, a subscription can be paused or unpaused by calling this endpoint in our API. |
created | ISO-8601 timestamp this webhook subscription was created |
Request and Response
Step 2 - Processing and Validating Webhooks
Before we begin, although not required, please note that many of the snippets we use include Amazon Web Services (AWS) as a dependency — specifically, Lambda and SQS. We will use AWS’ v2 Node SDK; however, v3 is also currently available.
Now that you have created a webhook subscription in the previous step, we will work on creating a webhook listener/handler. In order to asynchronously process webhooks, we recommend implementing the four following steps: ingestion, authentication, queueing and processing.
Ingestion
Receive the Webhook
At its core, a webhook listener is an HTTP endpoint that Dwolla will call. As such, your endpoint must:
- Be publicly accessible (Dwolla cannot send requests to
localhost
) - Be able to receive
POST
HTTP requests (Dwolla will not sendGET
,PUT
,PATCH
, etc.) - Have TLS enabled (with a valid SSL certificate issued to your domain)
- Be able to handle at least 10 concurrency requests, unless a lower value has otherwise been configured for your application by Dwolla
Return HTTP 2xx Status Code
Once a webhook has fired to your endpoint (and you have received it), in order to fully “ingest” the webhook, you must respond to Dwolla with a 200-level status code (e.g., 200 OK
). Additionally, Dwolla must receive your response within 10,000 milliseconds (or, in other words, 10 seconds). If a response is not received in the allotted time, Dwolla will retry the request up to 8 times over the next 72 hours, according to our back-off schedule. Finally, if your application fails to response after 400 consecutive attempts and 24 hours has passed since the last success, your webhook subscription will automatically pause.
Authentication
When you set up your webhook subscription, you sent over a secret
value to Dwolla. This value is a shared secret that only your application and Dwolla should have access to. Before Dwolla sends a webhook, the JSON-encoded payload is used in conjunction with the shared secret
to create the X-Request-Signature-SHA-256
header value, which is sent with the webhook request.
When a webhook request is received, Dwolla recommends creating a SHA-256 HMAC signature of the JSON-encoded payload that your application receives with the shared secret
as the key, and checking its value against the signature that Dwolla generated and supplied in the X-Request-Signature-SHA-256
header.
Considerations and Limitations
When implementing webhook authentication in your application, please consider the following:
- Dwolla uses a highly dynamic and wide range of IP addresses, meaning that your application cannot use IP whitelisting to authenticate webhook requests.
- The request body is already JSON-encoded prior to being sent. As such, the JSON body should never be re-encoded! If it is, the signatures will not match and authentication will fail, even if the request came from Dwolla.
- Your webhook endpoint must have access to the request body in order to authenticate the request. This means that some services, such as AWS Lambda Authorizers, are unable to authenticate a webhook Dwolla.
Queueing
Once you ingest the webhook and authenticate that it is from Dwolla, instead of handling the business logic within the listener, we recommend passing the webhook off to a queue to be picked up by another Lambda function. By doing this, your webhook listener takes on the minimum amount of responsibility necessary, enabling your application to scale quickly and easily based on the volume of concurrent requests.
Which messaging broker you use is up to you; however, we recommend using AWS SQS or GCP Pub/Sub if your application resides in a serverless environment. If your application is self-hosted, Redis is also a good alternative to the options listed above.
As an example, the following snippet will demonstrate how a webhook could be placed on an AWS SQS queue. In it QueueUrl
would be the URL of your SQS queue, whereas MessageBody
would be the “stringified” body of the webhook that Dwolla sends. (For more information on sending a message using AWS SQS, we recommend checking out their official documentation.)
Processing
Now that the webhook has been ingested, authenticated, and queued, once the webhook has been fetched from the queue, we recommend checking for duplicate events and then handling any application-specific business logic.
Check for Duplicate Events
Although Dwolla tries to only send a webhook once, it is possible that the same webhook may be sent more than once. Because of this, it is recommended to check an internal database against the webhook’s Event ID to ensure that the same business logic is not processed multiple times.
In other words, we recommend maintaining an internal database that keeps track of all of the events that are processed. Then, when a new webhook is received, your application ensures that the event (checked against its ID) has not already been processed previously. Additionally, once your application finishes processing an event, its ID is appended to your database, ensuring that if your application receives another webhook with the same event ID, it will not get processed a second time.
Finally, when checking if an event has already been processed, it’s important to note that multiple events can fire for the same resource while still remaining unique. For example, when a transfer is created, there may be cases where you receive customer_transfer_created
twice with a different event ID but the same resource ID. This is because when a transfer is created, an event is triggered for both the sender and the receiver. It is for this reason that we recommend checking webhooks against their event ID, not by their resource ID or topic.
When your application detects that you received an event that has already been
processed, it is imperative that it returns with a 200-level status, such as
200 OK
. If it responds with another value like
409 Conflict
, this simply propagates irrelevant information and
may result in your webhook getting automatically paused.
Handle Business Logic
Once you reach this point, you’re finally ready to handle any business logic related to the webhook — for example, creating or updating a database entry, sending a notification email or triggering an alert.
Although business logic will vary case by case based on your application’s specific needs, in this final section, we will demonstrate how you can use an AWS Lambda function to pull the webhook off an SQS queue, and print it to the console.
Conclusion
We hope that this guide is helpful in getting your webhook listener/handler set up and configured for use with Dwolla! If you would like to take a closer look at the code that we used (or give it a try using your own account), check out our webhook-receiver repository on GitHub.
Frequently Asked Questions
What is an Event vs Webhook Subscription vs Webhook?
What is an Event vs Webhook Subscription vs Webhook?
Event — An event is a unique resource that gets created whenever an action occurs in Dwolla that changes the state of an API resource like a Customer being created or a funding source being verified.
Webhook Subscription — A webhook subscription is a resource in the API that you can create in order to subscribe to Dwolla webhooks.
Webhook — A webhook is an HTTP request that Dwolla sends to your subscribed URL to notify your app of an event. In order to get webhook notifications, you will need to have an active webhook subscription.
Is a webhook subscription required to integrate with the Dwolla API?
Is a webhook subscription required to integrate with the Dwolla API?
While a webhook subscription is not required for you to integrate with the API, Dwolla requires all applications to have one in production for automated notifications of events to your application. Webhooks provide automatic near real-time status updates to your application versus polling the API which causes unnecessary load on your application and the API.
How to validate that a webhook is coming from Dwolla? Is there a list of IP addresses that I can limit webhook requests from?
How to validate that a webhook is coming from Dwolla? Is there a list of IP addresses that I can limit webhook requests from?
Dwolla includes a X-Request-Signature-SHA-256
header on each
webhook request which is a SHA-256 HMAC hash of the request body with the
key being the webhook secret
you passed in when you created the
webhook subscription. As a best practice, we recommend validating webhooks
by generating the same SHA-256 HMAC hash and comparing it to the signature
sent with the payload.
We do not recommend nor support relying on IP whitelisting as a method of validating webhooks. Dwolla’s IPs are dynamically allocated with no defined range and are subject to change. Refer to the Processing/Validating section for a more detailed guide.
Can I subscribe to certain event topics?
Can I subscribe to certain event topics?
Dwolla sends webhooks for all events that occur in your platform and there isn’t a way to filter what events you subscribe to.
My webhook subscription was paused. Why?
My webhook subscription was paused. Why?
Dwolla automatically
pauses a webhook subscription
after 400 consecutive failed delivery attempts and sends an email to notify the Admin of the Dwolla account. While it’s paused, Dwolla isn’t able to send webhooks for new events to your URL. To resume webhooks, you need to
address the issue that’s causing failures
Will webhooks be automatically retried if my subscription was previously paused or unavailable?
Will webhooks be automatically retried if my subscription was previously paused or unavailable?
How do I know if a webhook request failed and needs to be retried?
How do I know if a webhook request failed and needs to be retried?
When
listing all webhooks by webhook subscription
, an embedded attempts
array will include a
response
object that includes a statusCode
property indicating the
HTTP status code that Dwolla received when the webhook attempt was made. If the
status code that Dwolla received was >=300, then the attempt was considered to
have failed.
Can I create more than one webhook subscription?
Can I create more than one webhook subscription?
Yes. You can create up to 5 webhook subscriptions in Production and 10 in Sandbox. While only one subscription is needed to be notified of all events, you can have multiple in case one or more of your URLs becomes unreachable.