> ## Documentation Index
> Fetch the complete documentation index at: https://docs.moduluslabs.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> Receive real-time payment events when customers complete payments

## Overview

When a payment is completed on a payment link, Modulus delivers a webhook event to your configured endpoint. Events are delivered via HTTPS `POST` with a JSON body and are retried with exponential backoff on failure.

<Note>
  Webhook endpoint configuration is managed through your Modulus dashboard or by contacting your account manager.
</Note>

## Event types

| Event               | Triggered when                                       |
| ------------------- | ---------------------------------------------------- |
| `payment.succeeded` | A customer successfully completed a payment          |
| `payment.declined`  | A customer's payment was declined by the card issuer |
| `payment.failed`    | A payment failed due to a processing error           |
| `payment.expired`   | A payment link expired before any successful payment |

## Payload

```json theme={null}
{
  "event_type": "payment.succeeded",
  "payment_link_id": "550e8400-e29b-41d4-a716-446655440000",
  "payment_attempt_id": "660e8400-e29b-41d4-a716-446655440000",
  "amount": 150000,
  "currency": "PHP",
  "status": "SUCCEEDED",
  "card_brand": "VISA",
  "card_last_four": "4242",
  "merchant_branch_name": "SM City Angeles - Branch 1",
  "created_at": "2026-06-18T15:00:00Z"
}
```

| Field                  | Type    | Description                                                                                  |
| ---------------------- | ------- | -------------------------------------------------------------------------------------------- |
| `event_type`           | string  | One of the [event types](#event-types) above.                                                |
| `payment_link_id`      | string  | The payment link (UUID) the event belongs to. Match this to the `id` you stored at creation. |
| `payment_attempt_id`   | string  | Unique identifier (UUID) for this payment attempt.                                           |
| `amount`               | integer | Amount in the smallest currency unit (centavos for PHP).                                     |
| `currency`             | string  | ISO 4217 currency code.                                                                      |
| `status`               | string  | Outcome of the payment attempt.                                                              |
| `card_brand`           | string  | Card network used (e.g., `VISA`).                                                            |
| `card_last_four`       | string  | Last four digits of the card.                                                                |
| `merchant_branch_name` | string  | Display name of the branch.                                                                  |
| `created_at`           | string  | ISO 8601 timestamp of the event.                                                             |

## Reconciling payments

Match incoming events to your records using the `payment_link_id`, then look up the link with [Retrieve a Payment Link](/api-reference/ecom/retrieve-payment-link) to read the `order_reference` and `metadata` you set at creation.

<Tip>
  Respond with a `2xx` status as soon as you receive an event. Acknowledge first, then process asynchronously — slow responses count as failures and trigger retries.
</Tip>
