# Setting up Webhooks

Learn how to configure ODUS to receive webhook notifications from PayPal.

## Overview

Webhooks allow PayPal to notify ODUS about events that happen asynchronously, such as a payment PayPal denies after holding it for review, or a refund that fails. When properly configured, ODUS will automatically process these notifications and update the corresponding payment records.

note

ODUS currently processes the following PayPal webhook events:

| PayPal event                    | Description                                                                                        |
| ------------------------------- | -------------------------------------------------------------------------------------------------- |
| `PAYMENT.CAPTURE.DENIED`        | PayPal denied a payment it held for review. The payment fails                                      |
| `PAYMENT.CAPTURE.DECLINED`      | PayPal declined a payment it held for review. The payment fails                                    |
| `PAYMENT.CAPTURE.REFUNDED`      | A capture has been refunded (tracked if the status indicates failure)                              |
| `PAYMENT.CAPTURE.REVERSED`      | A capture has been reversed (tracked if the status indicates failure)                              |
| `PAYMENT.AUTHORIZATION.CREATED` | An authorization was created. The payment fails only if PayPal reports the authorization as denied |
| `PAYMENT.AUTHORIZATION.VOIDED`  | An authorization has been voided (tracked if the status indicates failure, or if PayPal denied it) |

warning

If your webhook listener was set up before `PAYMENT.CAPTURE.DENIED`, `PAYMENT.CAPTURE.DECLINED` and `PAYMENT.AUTHORIZATION.CREATED` were added, edit it in PayPal and select all three events. Until you do, a payment PayPal denies after review stays `succeeded` in ODUS.

## Payments PayPal holds for review

PayPal can hold a payment for review before it settles. ODUS reports a held payment as successful straight away: you receive `payment.succeeded`, and `payment.captured` if it was captured.

This covers a payment captured when it is made, and an authorization. A capture you make later, of an existing authorization, is not changed by these events.

When PayPal completes the payment, nothing changes.

When PayPal denies it, ODUS fails the payment:

* The payment returns to `open`, and its display status becomes `failed`.
* Its captured amount returns to 0, and the decline reason is recorded on the payment.
* You receive `payment.attempt_failed` for the payment.

If you fulfil orders on `payment.succeeded` or `payment.captured`, also handle `payment.attempt_failed` for the same payment, and stop or reverse the fulfilment.

warning

An invoice the payment had already paid stays `paid`, and a subscription the payment started stays active. Update them yourself when you receive `payment.attempt_failed` for a payment you had already fulfilled.

## Prerequisites

Before setting up webhooks, ensure you have completed the general [PayPal integration](https://docs.odus.com/docs/guides/integrations/gateways/paypal/.md) and have a working gateway profile in ODUS.

## Step 1 — Get the webhook URL from ODUS

When you create a new gateway profile in the ODUS Dashboard, a **Webhook Setup** dialog appears automatically after the profile is created. This dialog provides:

1. A **Webhook URL** — a read-only field with a copy button. This URL points to the ODUS webhook endpoint and includes your merchant and gateway profile identifiers as query parameters. Copy this URL; you will need it in the next step.
2. A **Webhook ID** field — you will fill this in after subscribing the webhook in PayPal (Step 3).

important

Unlike other payment providers, PayPal requires a **Webhook ID** instead of a webhook secret. The Webhook ID is not a secret value — it is a PayPal-assigned identifier for your webhook subscription that ODUS uses for certificate-based signature verification.

tip

If you skipped the webhook setup during gateway profile creation, you can still configure it later by editing the gateway profile in the ODUS Dashboard. The webhook URL and Webhook ID fields are available in the edit form.

## Step 2 — Subscribe a webhook listener in PayPal

1. Log in to the [PayPal Developer Dashboard](https://developer.paypal.com/dashboard/applications/).

2. Navigate to **Apps & Credentials**.

3. Select the **REST API app** that you are using for your ODUS integration.

4. Scroll down to the **Webhooks** section.

5. Click **Add Webhook** (or "Subscribe a listener URL").

6. Paste the **Webhook URL** you copied from the ODUS Dashboard into the **Listener URL** field.

7. Select the following **event types**:

   <!-- -->

   * `PAYMENT.CAPTURE.DENIED`
   * `PAYMENT.CAPTURE.DECLINED`
   * `PAYMENT.CAPTURE.REFUNDED`
   * `PAYMENT.CAPTURE.REVERSED`
   * `PAYMENT.AUTHORIZATION.CREATED`
   * `PAYMENT.AUTHORIZATION.VOIDED`

8. Click **Save**.

important

PayPal requires the webhook listener URL to use **HTTPS on port 443**. Ensure that your ODUS API is accessible over HTTPS.

## Step 3 — Copy the Webhook ID to ODUS

After subscribing the webhook listener:

1. In the **Webhooks** section of your PayPal app, locate the webhook you just created. PayPal assigns a **Webhook ID** to each listener upon creation.
2. Copy the Webhook ID.
3. Go back to the ODUS Dashboard — either in the Webhook Setup dialog (if still open) or by editing the gateway profile.
4. Paste the Webhook ID into the **Webhook Verification Key** field (labeled "Webhook ID" for PayPal integrations).
5. Click **Save**.

## Important notes

* PayPal retries webhook deliveries for up to **3 days**, making up to **25 retry attempts** on non-`2xx` responses.
* After 3 days of failed delivery, the event is marked as failed but can be resent manually from the [PayPal Webhook Events Dashboard](https://developer.paypal.com/dashboard/webhooksSimulator).
* You can subscribe up to **10 webhook URLs** per PayPal REST API app.
* Only events from the specific REST API app are delivered. If you have multiple apps, each requires its own webhook subscription.
* PayPal uses certificate-based signature verification (not HMAC). The Webhook ID you provide to ODUS is used as part of this verification process.
