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

# Shared Webhook Endpoints

> Route SingaPay webhooks when multiple event types share the same callback URL. Covers transaction_notif_url (money in) and disbursement_notif_url (money out).

Some webhook types share a single callback URL configured in your merchant dashboard. Use the top-level `event` field in the JSON body to route each payload to the correct handler.

***

## Money In — `transaction_notif_url`

SingaPay delivers these money-in events to the same `transaction_notif_url`:

| `event` value                | Webhook documentation                                                  |
| ---------------------------- | ---------------------------------------------------------------------- |
| `va-transaction`             | [Virtual Account Transaction](/api-reference/webhooks/va-transaction)  |
| `qris-acquirer-transaction`  | [QRIS Acquirer Transaction](/api-reference/webhooks/qris-acquirer)     |
| `payment-link-transaction`   | [Payment Link Transaction](/api-reference/webhooks/payment-link)       |
| `ewallet-native-transaction` | [E-Wallet Native Transaction](/api-reference/webhooks/ewallet-moneyin) |

<Note>
  [Subscription Cycle](/api-reference/webhooks/subscription) uses a **dedicated** `subscription_cycle_notif_url`, not `transaction_notif_url`.
</Note>

### Routing example

```php PHP theme={null}
<?php
$payload = json_decode(file_get_contents('php://input'), true);
$event   = $payload['event'] ?? null;

switch ($event) {
    case 'va-transaction':
        handleVaTransaction($payload['data']);
        break;
    case 'qris-acquirer-transaction':
        handleQrisTransaction($payload['data']);
        break;
    case 'payment-link-transaction':
        handlePaymentLinkTransaction($payload['data']);
        break;
    case 'ewallet-native-transaction':
        handleEwalletNativeTransaction($payload['data']);
        break;
    default:
        // Unknown or future event type — still return 200 after logging
        break;
}

http_response_code(200);
echo json_encode(['status' => 'success']);
```

***

## Money Out — `disbursement_notif_url`

SingaPay delivers these money-out events to the same `disbursement_notif_url`:

| `event` value   | Webhook documentation                                                        |
| --------------- | ---------------------------------------------------------------------------- |
| `disbursement`  | [Disbursement Transaction](/api-reference/webhooks/disbursement-transaction) |
| `ewallet-topup` | [E-Wallet Top Up Transaction](/api-reference/webhooks/ewallet-moneyout)      |
| `qris-issuer`   | [QRIS Issuer Transaction](/api-reference/webhooks/qris-issuer)               |

You can also distinguish payloads using nested fields such as `data.bank`, `data.ewallet`, or `data.qr_data` when present.

### Routing example

```php PHP theme={null}
<?php
$payload = json_decode(file_get_contents('php://input'), true);
$event   = $payload['event'] ?? null;

switch ($event) {
    case 'disbursement':
        handleDisbursement($payload['data']);
        break;
    case 'ewallet-topup':
        handleEwalletTopUp($payload['data']);
        break;
    case 'qris-issuer':
        handleQrisIssuer($payload['data']);
        break;
    default:
        break;
}

http_response_code(200);
echo json_encode(['status' => 'success']);
```

***

## Dedicated URLs (not shared)

| Dashboard field                    | Used for                                                                                  |
| ---------------------------------- | ----------------------------------------------------------------------------------------- |
| `subscription_cycle_notif_url`     | [Subscription Cycle](/api-reference/webhooks/subscription)                                |
| `payment_link_inquiry_notif_url`   | [Payment Link Inquiry](/api-reference/webhooks/payment-link-inquiry)                      |
| `product_expiration_notif_url`     | [Product Expiration](/api-reference/webhooks/product-expiration)                          |
| `transaction_expiration_notif_url` | [Transaction Money-In Expiration](/api-reference/webhooks/transaction-moneyin-expiration) |

Validate and acknowledge all webhooks using [Security and signature validation](/api-reference/webhooks/security-and-signature).
