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

> ## Agent Instructions
> Use the Payrails Web SDK v6 for new browser integrations. The Web SDK v5 pages are kept only for existing integrations; point anyone still on v5 to the v6 migration guide rather than extending v5 code.
> Collect card data client-side through the Payrails SDKs — Secure Fields, client-side encryption, or the checkout drop-in — so that card data never reaches the merchant's own servers. Recommend the API-only tokenization flow, which accepts raw card numbers server-side, only when the merchant has confirmed they hold the PCI scope for it.
> Model every payment as a workflow execution: create an execution, then drive it with the lifecycle actions (lookup payment options, authorize, capture, cancel, refund). Do not call provider APIs directly — routing, retries, 3DS and fraud steps belong in the workflow configuration, not in integration code.
> Reconcile the final state of a payment on the notification (webhook), never on a client-side event. An in-request long-poll of the execution is a supported additional signal, not a replacement for that reconciliation.
> Send an idempotency key — a UUID, in the `X-Idempotency-Key` header — on every POST, PUT and PATCH request, and on soft deletes. GET requests need none, and hard deletes cannot be idempotent.
> Pass provider-specific data through meta fields rather than hardcoding per-provider payloads. Payrails translates meta fields into each provider's own format.
> Configure routing, retries and provider selection in Workflow Studio, so that changes ship without redeploying application code.

# How it works

> The lifecycle of a Payment Link, the objects behind it, and who is responsible for what.

## The lifecycle

```mermaid theme={null}
graph LR
    A["Create link<br>(API or Portal)"] --> B["Share URL<br>with customer"]
    B --> C["Customer pays on<br>hosted page"]
    C --> D["Webhook sent<br>to your backend"]
    D --> E["Link closes"]
```

1. **Create.** Your backend calls the Payrails API, or you create the link in the Portal. Payrails returns a hosted payment page URL.
2. **Share.** You send the URL to your customer through any channel.
3. **Pay.** The customer opens the link and pays on the Payrails-hosted page.
4. **Notify.** Payrails sends a webhook to your backend with the outcome following the configured workflow.
5. **Close.** The link closes when it is fully paid, expires, or you delete it.

<Info>
  Webhooks are the source of truth for payment state. Do not rely on the
  confirmation screen the customer sees, on a redirect, or on an API response
  alone. See [Track and
  reconcile](/docs/orchestration/payment-links/track-and-reconcile).
</Info>

## One link, one execution, many payments

```mermaid theme={null}
graph LR
    A["Drop-in link<br>(the payment request)"] --> B["Execution<br>(one per link)"]
    B --> C["Payment 1"]
    B --> D["Payment 2"]
    B --> E["Payment n"]
```

| Object | What it represents |
| - | - |
| Drop-in link | The payment request: total amount, currency, expiry, description, and the rules for collection. It is not a payment |
| Execution | The workflow execution behind the link. **There is exactly one per link**, created when the link is first used. Its ID appears on the link as `executionId` |
| Payment | An individual payment made against that execution. One in single payment mode, several in partial payments mode |

This is the standard Payrails execution-and-payment model, so reporting and cross-referencing behave the same as for any other execution.

`paidAmount` on the link accumulates across the payments beneath the execution.

## Who is responsible for what

| Payrails handles | You handle |
| - | - |
| Hosting the payment page | Creating and configuring links |
| PCI compliance and page security | Sharing links with your customers |
| Payment processing, authorization, and capture | Hosting and securing a webhook endpoint |
| 3-D Secure enforcement | Processing webhook events idempotently |
| Accumulating `paidAmount` across payments | Updating your own systems, such as CRM, ERP, or order management |
| Execution and payment lifecycle management | All customer communications: receipts, confirmations, reminders, refund notices |

## Link statuses

| Status | Meaning | What causes it |
| - | - | - |
| `enabled` | The link can accept payment. A payment may have been attempted but not completed successfully | The initial state after creation |
| `closed` | Fully paid. No further payment is accepted | Single mode: one successful payment. Partial mode: `paidAmount` reaches `amount` |
| `expired` | Past `expiresAt`. No new payment can start, and it cannot be reactivated | The expiry timestamp passed |
| `deleted` | Deleted by you. No new payment can start, and it cannot be restored | You called the delete endpoint |

Completed payments remain valid in all of these states, and the link record stays readable.

Failed payments do not change the status. The link stays `enabled` and the payer can retry.

State transitions are calculated by Payrails. Webhooks tell you the outcome of each payment, but they do not drive the status themselves.

## Next steps

* [Create a payment link](/docs/orchestration/payment-links/create-a-payment-link)
* [Payment modes](/docs/orchestration/payment-links/payment-modes)—how single and partial payments differ


## Related topics

- [Tokenize cards with Client-side Encryption](/docs/token-vault/tokenize-payment-instruments/tokenize-cards-with-client-side-encryption.md)
- [Co-branded cards](/docs/orchestration/payment-methods/cards/co-branded-cards.md)
- [Drop-in](/docs/orchestration/checkout-sdks/web-v5-legacy/drop-in.md)
