How to handle the invoice.payment_failure webhook payload
Last updated: June 30, 2026
How to handle the invoice.payment_failure webhook payload
When a payment attempt on an invoice fails, Lago sends an invoice.payment_failure webhook. This payload does not contain the full invoice. It carries the decline reason from the payment provider and the IDs you need to identify the invoice and customer, so you can read why the payment failed straight from the webhook and fetch the full invoice from the API only if you need its amounts or line items.
How the payload is shaped
The payload is wrapped under a single root key, payment_provider_invoice_payment_error, with webhook_type set to invoice.payment_failure. Inside that object you get the provider's failure reason and the identifiers for the invoice and customer, rather than the invoice itself:
{
"webhook_type": "invoice.payment_failure",
"object_type": "payment_provider_invoice_payment_error",
"payment_provider_invoice_payment_error": {
"lago_invoice_id": "...",
"lago_customer_id": "...",
"external_customer_id": "...",
"provider_error": { "...": "..." }
}
}The failure reason lives in provider_error, which carries the message and error code returned by the payment provider. For most failure handling, deciding whether to notify the customer, retry, or flag the account, that is the field you want, and it is already in the payload.
Getting the full invoice
The webhook deliberately omits the invoice object, so it does not include amounts, fees, or line items. When you need those, take lago_invoice_id from the payload and call GET /api/v1/invoices/{lago_invoice_id}. The invoice returned reflects its state at the time of the call, so treat any status on it as current rather than as a fixed record of the failure: a later retry can change it.
This article reflects guidance drawn from customer case resolutions. It is not officially supported documentation and may not apply to all situations.