---
title: Payment webhooks | API Docs
description: Reconcile payments server-side with the payment.succeeded, payment.canceled, and payment.expired events.
---

Subscribe to payment lifecycle events so you can reconcile server-side instead of polling. A payment request emits exactly one terminal event.

## Events

| Event               | Fires when                                                                                                                                                                                                                           |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `payment.succeeded` | The recipient paid. The request’s `status` is now `succeeded`. For `mode: subscription` requests this is the **first invoice** being paid and the subscription activating — renewals emit your own Stripe webhooks, not Linq events. |
| `payment.canceled`  | You cancelled the request before it was paid.                                                                                                                                                                                        |
| `payment.expired`   | The request reached its `expires_at` without being paid.                                                                                                                                                                             |

Each payload carries the full payment request — `id`, `mode`, `amount`, `currency`, the `metadata` you set on creation, and for subscriptions the recurrence (`price_id`, `interval`, `interval_count`, `quantity`, plus `trial_end` on free trials, where `payment.succeeded` means the payment method was collected and $0 moved) — so you can match the event back to your own order or chat record without a second API call. The `stripe` object carries the ids of the objects on your connected account (`payment_intent_id`, plus `customer_id` whenever the request is attached to a Customer — always for subscriptions, and in payment mode when you created the request with a `customer_id` — and `subscription_id` for subscriptions) — your join keys for managing the ongoing lifecycle in Stripe. A `rail` field (`stripe` or `natural`) tells you which rail the request settled on; on the Natural rail the payload carries a `natural` object with its join keys (`payment_request_id`, a `prq_...`, and `transaction_id`, a `txn_...`) in place of the `stripe` object. The canonical payload shapes are in the [Webhooks API reference](/api/resources/webhooks/index.md).

:::note\[Natural rail: wallet activity beyond your requests] These `payment.*` webhooks fire only for payment requests **you create through Linq**. On the Natural rail, other wallet activity — incoming payments made outside a Linq request, transfers, deposits, and payouts — happens on your Natural account and is not bridged here. To see or get notified of it, use your **Natural dashboard** or register your **own webhooks in Natural** against your account. :::

## Subscribing

Create a webhook subscription targeting your endpoint and filtered to the payment events you care about. The full subscription lifecycle — create, list, update, delete, versioning, and **signature verification** — is covered in the [Webhooks guide](/guides/webhooks/index.md). Payment events use the same delivery, retry, and [Standard Webhooks](https://www.standardwebhooks.com/) signing scheme as every other Linq event, so if you already verify webhooks, nothing new is required.

## Reconciling

Treat the webhook as the source of truth for a request reaching a terminal state:

- On `payment.succeeded`, mark your order paid using the `metadata` you attached.
- On `payment.expired` or `payment.canceled`, release or re-issue as appropriate.

If you miss an event (endpoint downtime, etc.), you can always fetch the current state with [Retrieve a payment request](/api/resources/payment_requests/methods/retrieve/index.md) — `status` and `paid_at` reflect the same outcome the webhook reported.

## Related

- [Payments overview](/guides/payments/index.md)
- [Webhooks](/guides/webhooks/index.md) — subscriptions and signature verification.
