Configure and verify webhooks
Each merchant can configure one webhook per environment. LirPay stores test and live secrets and event journals separately.
https://lirpay.org/api/v2/integration/webhookRead the current environment webhook without exposing its secret.
https://lirpay.org/api/v2/integration/webhookCreate or update the webhook URL, subscriptions, and enabled state.
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
| url | URL | body | yes | HTTPS endpoint in live mode. Test mode also accepts HTTP. |
| event_types | string[] | body | yes | Non-empty list of supported events. |
| enabled | boolean | body | no | Delivery state. Defaults to true. |
Request
{
"url": "https://merchant.example/webhooks/lirpay",
"event_types": [
"payment.succeeded",
"balance.updated",
"withdrawal.completed"
],
"enabled": true
}The first PUT response includes a new secret. Store it because later GET responses expose only has_secret.
https://lirpay.org/api/v2/integration/webhookDisable webhook delivery for the current environment.
https://lirpay.org/api/v2/integration/webhook/testSend and record a signed test event.
https://lirpay.org/api/v2/integration/webhook/rotate-secretReplace the signing secret and return the new value once.
https://lirpay.org/api/v2/integration/webhook-eventsList event payloads and delivery state.
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
| page | integer | query | no | Page number. Defaults to 1. |
| limit | integer | query | no | Items per page. Maximum 100. |
https://lirpay.org/api/v2/integration/webhook-events/{id}Read one payload and its delivery history.
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
| id | uuid | path | yes | Resource identifier returned by a list or create operation. |
The delivery_history array includes attempt number, status, error, and timestamp.
https://lirpay.org/api/v2/integration/webhook-events/{id}/redeliverDeliver an existing event again.
| Parameter | Type | In | Required | Description |
|---|---|---|---|---|
| id | uuid | path | yes | Resource identifier returned by a list or create operation. |
| Idempotency-Key | string | header | yes | Unique key for this monetary operation. Maximum 255 characters. |
Allowlist source IPs
Production webhook deliveries come from payment-core egress. Allowlist 2.27.27.132 for both test and live events.
2.27.27.132— webhook source IP- Do not allowlist
2.27.27.134. That address is HTTPS ingress forlirpay.orgonly. - Deliveries currently use IPv4 only. Verify the HMAC signature even if you filter by IP.
Verify each signature
Compute a hexadecimal Hash-based Message Authentication Code using SHA-256 (HMAC-SHA256) over the untouched request body.
import { createHmac, timingSafeEqual } from "node:crypto";
const expected = createHmac("sha256", webhookSecret)
.update(rawBody)
.digest("hex");
const valid = timingSafeEqual(
Buffer.from(expected, "hex"),
Buffer.from(signature, "hex"),
);- Read the event identifier from
X-Lirpay-Event-Id - Read the environment from
X-Lirpay-Mode - Return a
2xxresponse after persisting the event - Deduplicate processing by event identifier
- Live deliveries are retried up to eight times. Test-mode events are never retried
Subscribe to supported events
payment.succeeded,payment.failed,payment.expired,payment.refund_required,payment.refunded,payment.chargebackbalance.updatedwithdrawal.processing,withdrawal.completed,withdrawal.failedconversion.completed