Skip to main content

Payment Link Webhooks

This page covers the seven webhook events triggered across a payment link's lifecycle. For payment lifecycle events, see Payment Webhooks. For refund events, see Refund Webhooks.

Each event below shows its v3 and v4 payload. v3 sends the full payload as-is; v4 encodes and signs the same payload before sending it, with the signature carried in a field named signature (the same field name used on every webhook type). Unlike payment/refund events, payment link events don't carry a top-level nimbbl_signature or transaction.signature_version to begin with — but the decoded v4 payload does drop payment_link.signature, since the whole payload is signed instead. See Webhook Payloads for how retries, idempotency, and payload versions work, and Validating Payment Response with Signature for signature validation logic.

Payment-link Signing String Differs From the Transaction One

The v1–v3 payment_link.signature is an HMAC-SHA256 of invoice_id|status|currency|amount_paid|payment_link_hash (amount formatted to 2 decimals) — a different field set from the transaction-level signature used elsewhere.

Your endpoint receives this over HTTPS POST:

{
"payload": "<base64>",
"signature": "<hmac-sha256-hex>",
"sub_merchant_id": "<sub_merchant_id>",
"version": "v4"
}
Decoded payload
{
"event_type": "payment_link_created",
"status": "created",
"message": "Payment link created",
"payment_link": {
"status": "created",
"currency": "INR",
"amount_paid": 0.0,
"hash": "8KpOZpXA3yXvzPzl",
"id": "pl_8KpOZpXA3yXvzPzl",
"invoice_id": "ae5ee6d6b0f9415a972a7bf7a4d088f6_f2aa77a602224bcea9cf3227d41f121a",
"url": "https://pages.nimbbl.tech/Omkar34/8KpOZpXA3yXvzPzl",
"quantity": 0,
"tax": 0.0,
"amount_before_tax": 0.0
},
"is_webhook": true
}

Your endpoint receives this over HTTPS POST:

{
"payload": "<base64>",
"signature": "<hmac-sha256-hex>",
"sub_merchant_id": "<sub_merchant_id>",
"version": "v4"
}
Decoded payload
{
"event_type": "payment_link_sent",
"status": "sent",
"message": "Payment link sent",
"payment_link": {
"status": "sent",
"currency": "INR",
"amount_paid": 0.0,
"hash": "PJ77Qlx1y407W964",
"id": "pl_PJ77Qlx1y407W964",
"invoice_id": "169853f9944a4a22a6e5b4a0b199e374_8a4eb5a157fb415798b703fab4635844",
"url": "https://pages.nimbbl.tech/Omkar34/PJ77Qlx1y407W964",
"quantity": 0,
"tax": 0.0,
"amount_before_tax": 0.0
},
"is_webhook": true
}

Your endpoint receives this over HTTPS POST:

{
"payload": "<base64>",
"signature": "<hmac-sha256-hex>",
"sub_merchant_id": "<sub_merchant_id>",
"version": "v4"
}
Decoded payload
{
"event_type": "payment_link_opened",
"status": "opened",
"message": "Payment link opened",
"payment_link": {
"status": "opened",
"currency": "INR",
"amount_paid": 0.0,
"hash": "Vw4V1DZArA5YGpBB",
"id": "pl_Vw4V1DZArA5YGpBB",
"invoice_id": "inv_aPW7kPJx5WOa2vNY",
"url": "https://pages.nimbbl.tech/Omkar34/Vw4V1DZArA5YGpBB",
"quantity": 0,
"tax": 0.0,
"amount_before_tax": 999.0
},
"is_webhook": true
}

Your endpoint receives this over HTTPS POST:

{
"payload": "<base64>",
"signature": "<hmac-sha256-hex>",
"sub_merchant_id": "<sub_merchant_id>",
"version": "v4"
}
Decoded payload
{
"event_type": "payment_link_paid",
"status": "paid",
"message": "Payment link paid successfully",
"payment_link": {
"status": "paid",
"currency": "INR",
"amount_paid": 1000.0,
"hash": "8KpOZpXA3yXvzPzl",
"id": "pl_8KpOZpXA3yXvzPzl",
"invoice_id": "ae5ee6d6b0f9415a972a7bf7a4d088f6_f2aa77a602224bcea9cf3227d41f121a",
"url": "https://pages.nimbbl.tech/Omkar34/8KpOZpXA3yXvzPzl",
"quantity": 1,
"tax": 0.0,
"amount_before_tax": 1000.0
},
"is_webhook": true
}

payment_link_authorized fires when a pre-authorization hold is placed against a payment link — the payment link equivalent of the payment_authorized event. Nimbbl treats it as a "rich" event: unlike the other payment link events above, it carries the full transaction, order, and user objects — the same shape as payment_link_paid — rather than just the payment_link summary. Fulfil this the same way you'd handle any other pre-authorization: do not treat the link as settled until you capture the hold.

Your endpoint receives this over HTTPS POST:

{
"payload": "<base64>",
"signature": "<hmac-sha256-hex>",
"sub_merchant_id": "<sub_merchant_id>",
"version": "v4"
}

Base64-decode payload to get the JSON below.

Decoded payload
{
"event_type": "payment_link_authorized",
"status": "authorized",
"message": "Payment link authorized",
"payment_link": {
"status": "authorized",
"currency": "INR",
"amount_paid": 0.0,
"hash": "8KpOZpXA3yXvzPzl",
"id": "pl_8KpOZpXA3yXvzPzl",
"invoice_id": "ae5ee6d6b0f9415a972a7bf7a4d088f6_f2aa77a602224bcea9cf3227d41f121a",
"url": "https://pages.nimbbl.tech/Omkar34/8KpOZpXA3yXvzPzl",
"quantity": 1,
"tax": 0.0,
"amount_before_tax": 1000.0
},
"transaction": {
"transaction_id": "<Transaction_ID>",
"payment_partner": "<Payment Partner>",
"status": "authorized",
"payment_mode": "<Payment Mode>",
"transaction_currency": "INR",
"transaction_amount": 1000.0,
"transaction_type": "payment",
"authorization_details": {
"mechanism": "pre_auth",
"capture_mode": "manual",
"authorized_time": "2026-06-22T10:46:14Z",
"expiry_time": "2026-06-29T10:46:14Z",
"captured_amount": 0.0,
"voided_amount": 0.0,
"available_authorized_amount": 1000.0
}
},
"order": {
"order_id": "<Order_ID>",
"status": "lapsed",
"lapsed_reason": "payment_authorized",
"currency": "INR",
"total_amount": 1000.0
},
"user": {
"email": "[email protected]",
"mobile": "9121212121",
"name": "Shakthiman",
"user_id": "<user_ID>"
},
"is_webhook": true
}

Your endpoint receives this over HTTPS POST:

{
"payload": "<base64>",
"signature": "<hmac-sha256-hex>",
"sub_merchant_id": "<sub_merchant_id>",
"version": "v4"
}
Decoded payload
{
"event_type": "payment_link_cancelled",
"status": "cancelled",
"message": "Payment link cancelled",
"payment_link": {
"status": "cancelled",
"currency": "INR",
"amount_paid": 0.0,
"hash": "8KpOZpXA3yXvzPzl",
"id": "pl_8KpOZpXA3yXvzPzl",
"invoice_id": "ae5ee6d6b0f9415a972a7bf7a4d088f6_f2aa77a602224bcea9cf3227d41f121a",
"url": "https://pages.nimbbl.tech/Omkar34/8KpOZpXA3yXvzPzl",
"quantity": 0,
"tax": 0.0,
"amount_before_tax": 0.0
},
"is_webhook": true
}

Your endpoint receives this over HTTPS POST:

{
"payload": "<base64>",
"signature": "<hmac-sha256-hex>",
"sub_merchant_id": "<sub_merchant_id>",
"version": "v4"
}
Decoded payload
{
"event_type": "payment_link_expired",
"status": "expired",
"message": "Payment link expired",
"payment_link": {
"status": "expired",
"currency": "INR",
"amount_paid": 0.0,
"hash": "8KpOZpXA3yXvzPzl",
"id": "pl_8KpOZpXA3yXvzPzl",
"invoice_id": "ae5ee6d6b0f9415a972a7bf7a4d088f6_f2aa77a602224bcea9cf3227d41f121a",
"url": "https://pages.nimbbl.tech/Omkar34/8KpOZpXA3yXvzPzl",
"quantity": 0,
"tax": 0.0,
"amount_before_tax": 0.0
},
"is_webhook": true
}