Optimizing Webhook Integration: a new approach to accept events from the Adyen platform
Tags: webhooks, developer
Published: 2024-05-02 08:36:36

[Webhooks](https://docs.adyen.com/development-resources/webhooks/) are crucial for getting updates and notifications from the Adyen platform. Those events include confirmation about, e.g., payment authorizations, modifications of existing payments, changes in the account data, or the availability of a new report. For any developers integrating with the Adyen platform, it’s essential to receive, acknowledge, and consume this information stream and ensure their ecommerce or payment is always up to date.

Our teams also pay significant attention to keep improving the framework, ensuring reliability and performance meet the needs of our merchants and their use cases.

As part of this simplification effort, **we have introduced a different way** to acknowledge webhooks.

**In this article…** read how to accept webhooks delivered by Adyen, why we have changed the approach, the benefits, and the best practices we recommend for handling webhooks.

---

## Accepting webhooks
The Adyen platform requires the webhook handlers to accept explicitly when a webhook is received so that Adyen can mark it as delivered.

Webhooks that are not accepted end up in the [Retry Queue](https://docs.adyen.com/development-resources/webhooks/troubleshoot/#retry-queue): Adyen will progressively try to send those events again at predefined intervals until the applications can eventually consume them.

The receiving applications **must accept a webhook within 10 seconds**, implementing one of the two options available.

### Accept with ‘[accepted]’ response body
All integrations built with Adyen have been accepting webhooks by responding with a response body containing the string ‘[accepted]’. Applications failing to meet these specifications or taking longer than 10 seconds to do so would not successfully accept the webhook, triggering the retry process.

This approach, implemented for years, has now been revised.

### Accept with any 2XX HTTP status code
The **new approach** simplifies the acknowledgment of webhooks.
Whether you have built a custom integration or leveraged a middleware, all webhook handlers must respond only with a [successful HTTP status code](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#successful_responses) (2XX). Developers can choose any 2XX status code; providing a body with the HTTP response is unnecessary.

Let’s see an example of how you can do this with NodeJS:

```
// webhook handler implementation
app.post("/api/webhooks/notifications", async (req, res) => {

  // Notification Request JSON
  const notificationRequestItems =  req.body.notificationItems
  // fetch first (and only) NotificationRequestItem
  const notification = notificationRequestItems[0].NotificationRequestItem

  // perform basic auth and HMAC validation
  authorize();

   // consume event asynchronously (ie store in queue/db)
   store(notification);

   // accept the event
   res.status(202).send(); // Send a 202 response with an empty body
});
```

## Benefits and remarks
There are multiple reasons behind the change.

### Align with industry standards
As webhooks have become widely used in so many platforms and applications, there have been **emerging industry standards** and best practices that we want to align with.

Accepting webhooks by adopting the [HTTP status code 202](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/202) ("Accepted"), for example, makes clear the semantics of the interaction: the consumer has received the event and will eventually process the content.

### Better support for middleware
We have seen the adoption of middleware for ingesting webhooks. Although ensuring the reliability and performance of the ingestion of events at scale, they might lack the flexibility of **crafting custom response** bodies. 

Commercial services may also incur extra charges for delivering text within the response body, as this triggers an increased data transfer.

### Remove unnecessary ambiguity
Exclusively relying on the content of the response body has presented scenarios where webhooks were successfully acknowledged even when responding with status codes in the 4XX and 5XX ranges, conventionally used to report an error.

This has resulted in **false negatives**, which not only affect the accuracy of performance metrics but also require additional effort to verify those cases.

## New webhooks
Every newly created webhook on the Adyen platform will work with the **2XX HTTP status code** option. Developers should understand how the new approach works and make sure that their implementation, either a bespoke webhook handler or the middleware, supports it by returning a successful HTTP response status code.

If the 2XX HTTP status code option isn't compatible with your integration, reach out to the Adyen Support team, and we'll assist you in finding a suitable solution.

## Migrating existing webhooks
All existing webhooks, however, are not automatically updated and keep functioning as before, relying on the **'[accepted]' response body**. The migration is, however, straightforward and can be performed either in the Customer Area or programmatically using the Management API.

Start planning the migration of your existing webhooks now and don't miss out on the advantages highlighted above.

### Update Webhook configuration in the CA
In the Customer Area, go to the "Developers->Webhooks" page and choose the webhook that is ready to be migrated. As you edit the webhook, in the "Server configuration" section, you will see the picklist "Accept webhook."

![Webhook configuration screen](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/99rapyll317f6snb9s9s.png)

The picklist provides two choices:
- With '[accepted]'
- With HTTP 2XX

Change the preferred approach to "With HTTP 2XX" and confirm the choice. Note that **this change is permanent** and can't be reverted.

![Confirmation popup](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wtb5actur4qyzzvme97q.png)

### Update Webhook configuration using the Management API
The [Adyen Management API](https://docs.adyen.com/api-explorer/Management) allows to manage account and payment configuration programmatically. The API enables developers to perform and automate administrative tasks, configure settings and test webhooks.

In order to update the webhook configuration and change the 'accept' mechanism you can perform a PATCH request setting the `acceptHttp200Confirmation` property:

```
# example on TEST environment

PATCH https://management-test.adyen.com/v3/merchants/{merchantId}/webhooks/{webhookId}

{
   "additionalSettings": {
      "properties": {
          "acceptHttp200Confirmation": "true"
      }
   }
}
```

### Refactor webhook handlers
Developers should also refactor the applications consuming the webhook events: provide a successful response, preferably with the HTTP status code 202, and ensure the response body is empty.

When a middleware processes the webhooks, the configuration should also be updated to adopt the new approach.

## Best practices
Consuming the webhooks delivered by the Adyen platform requires understanding and adopting best practices. Let's summarize them again:

### Respond with 202 and empty body
Acknowledge the webhook with an [HTTP status code 202](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/202) ("Accepted") to indicate that the request has been successfully received, but the processing may not be complete.

Any successful 2XX HTTP status codes can be used. However, the recommendation is to use 202.

Returning an **empty response body** is also a good practice, as it keeps the response lightweight and avoids unnecessary data transfer.

### Respond within 10 seconds
The webhook handler must acknowledge the webhook within a 10-second window; failure to do so will prompt Adyen to retry sending the event later.

There are a variety of reasons that can make the acceptance of the webhook longer than for 10 seconds. The affecting factors typically are the application's architecture, the complexity of the integration process, and the dependency on other systems or components.

Consider therefore adopting an asynchronous approach:
- Store the event in a queue or database.
- Acknowledge the webhook with a response status code 202.
- Subsequently, process the event asynchronously.

This strategy allows for more efficient handling of events, ensuring smoother integration and a predictable outcome.

### Security (basic auth and HMAC)
Implement the required [security measures](https://docs.adyen.com/development-resources/webhooks/best-practices/#security) **before acknowledging a webhook**.

Enforce Basic Authentication (username and password) to ensure that only authorized parties can access the webhook endpoint.

Integrate Hash-based Message Authentication Code (HMAC) validation to verify the integrity and authenticity of the webhook payload before consuming it.

### Monitor event logs
Use the [Developer Dashboard](https://www.adyen.com/knowledge-hub/adyen-developer-dashboard) to monitor the health of your integration. The dashboard provides insights into the webhooks activity, aggregating valuable metrics like success rate and most frequent errors.

When troubleshooting becomes necessary, dive into the Event Logs to inspect the events' status, payload, and response time.

![Monitor webhook events](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ddyiu3fcfpz1b2ykune9.png)

## Conclusion
The article outlines the new approach for accepting Adyen webhooks. We've compared the different methods, outlined the migration steps, and explained the rationale behind adopting any 2XX HTTP status code for webhook acknowledgment.

Now it's time to plan your migration! Follow the recommended best practices, and don't hesitate to reach out if we can help you in any way with the transition.