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

# Payment lifecycle

> Every state a payment and its attempts move through, what triggers each transition, and the time windows that seal a quiet payment.

A payment intent has no deadline of its own. Its status always derives from two things: **what its attempts did**, and **how long it has been waiting**. This page maps every state, every transition, and every clock so you can build your integration on the exact behaviour.

## The two resources

* The **payment intent** is what you create and what your customer owes. It is the source of truth for the outcome.
* An **attempt** is one try at collecting the intent through one payment method. An intent can hold several attempts (up to 4), but only one can be in flight at a time.

## Intent states

```mermaid theme={null}
stateDiagram-v2
    direction LR
    [*] --> pending : intent created
    pending --> completed : an attempt succeeded
    pending --> failed : attempt budget exhausted,\nor retry window ran out
    pending --> expired : never attempted,\nwindow ran out
    failed --> pending : requery
    completed --> partially_refunded : partial refund cleared
    completed --> refunded : fully refunded
    partially_refunded --> refunded
    completed --> [*]
    failed --> [*]
    expired --> [*]
```

| State                             | Meaning                                                                                              |
| --------------------------------- | ---------------------------------------------------------------------------------------------------- |
| `pending`                         | Payable. The inactivity window is running.                                                           |
| `completed`                       | One attempt collected the funds. Terminal, refundable.                                               |
| `failed`                          | The payer engaged but the payment did not succeed. Recoverable through [requery](/payments/requery). |
| `expired`                         | **Nobody ever tried.** The intent ran out of time with zero attempts.                                |
| `partially_refunded` / `refunded` | Post-completion refund states.                                                                       |

<Note>
  `expired` means exactly one thing: the payment was never attempted. A payment your customer engaged with never expires — it fails, so your reconciliation can always tell abandonment before checkout from failure during it.
</Note>

## Attempt states

```mermaid theme={null}
stateDiagram-v2
    direction LR
    [*] --> processing : attempt created
    processing --> action_required : payer action needed\n(OTP, redirect)
    action_required --> processing : payer confirmed
    processing --> completed : provider confirmed
    processing --> failed : provider declined
    processing --> expired : no resolution\nwithin the window
    action_required --> completed
    action_required --> failed
    action_required --> expired : payer never acted\nwithin the window
    failed --> processing : requery
    expired --> processing : requery
```

Each waiting state carries its own entry timestamp (`processing_at`, `action_required_at`) so you can see exactly how long an attempt has been waiting, and each terminal state carries its own (`completed_at`, `failed_at`, `expired_at`).

## How attempts drive the intent

The intent reacts **the moment an attempt finalises** — there is no polling delay on these transitions:

| An attempt...                       | The intent...                                                       |
| ----------------------------------- | ------------------------------------------------------------------- |
| completes                           | completes immediately                                               |
| fails or expires, with budget left  | stays `pending` and its window restarts, so the payer can try again |
| fails or expires as the 4th attempt | fails immediately                                                   |

## Time windows

| Window                       | Default     | Clock starts                                                                                                                            |
| ---------------------------- | ----------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| Intent inactivity            | 30 minutes  | at creation, restarted whenever an attempt hands the intent back or a requery reopens it                                                |
| Attempt in `processing`      | 120 minutes | on entering the state; the attempt is re-verified with the provider one last time before it expires, so a late confirmation always wins |
| Attempt in `action_required` | 120 minutes | on entering the state, reset when the payer confirms                                                                                    |

Two things protect a pending intent from its inactivity window:

1. **An attempt in flight.** An intent is never sealed under an active attempt.
2. **An open hosted checkout session.** The session carries the expiry you chose at creation (`expires_in_minutes`); as long as it is open, the intent stays payable even past its own window.

When the window runs out with no protection, the intent is sealed: `expired` if it holds no attempts, `failed` otherwise. The corresponding [webhook](/webhooks) — `payment.expired` or `payment.failed` — fires at that moment.

## Recovering a sealed payment

`failed` and `expired` are terminal for the payer but not for you: a [requery](/payments/requery) re-verifies the active attempt with its provider and reopens the payment when the provider actually settled it after the window closed.
