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

# Payment lifecycle

> Interpret every Payment status and decide when to poll, fulfil, or start a new attempt

A Payment represents one attempt to collect funds. Always read its current
`status` before changing an order in your system.

## Statuses

| Status            | Terminal | What it means                                                             | What you should do                                                                |
| ----------------- | -------- | ------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| `PENDING`         | No       | Flowlix accepted the request and is deciding or submitting the next step. | Store the Payment ID and poll it.                                                 |
| `REQUIRES_ACTION` | No       | The customer must complete the action in `next_action`.                   | Send the browser to the latest `next_action.redirect_url`, then poll the Payment. |
| `PROCESSING`      | No       | Downstream payment systems are processing the attempt.                    | Keep the order pending and poll the Payment. Do not submit it again.              |
| `SUCCEEDED`       | Yes      | Funds were collected.                                                     | Fulfil the order once and record `amount_refundable`.                             |
| `FAILED`          | Yes      | The attempt failed permanently.                                           | Read `failure_code`; if the customer tries again, create a new Payment.           |
| `EXPIRED`         | Yes      | The customer did not complete a required action in time.                  | Close this attempt; if the customer tries again, create a new Payment.            |

`PENDING`, `REQUIRES_ACTION`, and `PROCESSING` are non-terminal. `SUCCEEDED`,
`FAILED`, and `EXPIRED` are terminal for that Payment.

## Track the authoritative result

Subscribe to [Webhooks](/guides/webhooks) for lifecycle notifications. Each
event carries the snapshot at the time of the event; retrieve the Payment
whenever you need its latest state.

Call `GET /v1/payments/{id}` until the Payment reaches a terminal status:

```bash theme={null}
curl https://api.flowlix.eu/v1/payments/pay_q7Mk2Np8Vr4Xt6Yz9Ab3Cd5E \
  -H "Authorization: Bearer $FLOWLIX_API_KEY"
```

The retrieved Payment is authoritative. A browser return from the hosted page
or 3D Secure is only a signal to retrieve it again.

While a customer is waiting, polling every 2–5 seconds is a practical starting
recommendation, not an API guarantee. Back off to a slower schedule appropriate
for your order workflow when the customer leaves. Stop only at a terminal
status.

If a non-terminal state lasts longer than your expected checkout window,
keep the order pending and contact support with the Payment ID and
`Request-Id`. A local timeout does not authorize a duplicate charge.

<Warning>
  A non-terminal Payment is not a failed attempt. Do not create another Payment
  while the original one is still `PENDING`, `REQUIRES_ACTION`, or `PROCESSING`.
</Warning>

## Handle required actions

When the status is `REQUIRES_ACTION`:

1. Read both `next_action.reason` and `next_action.redirect_url`.
2. Treat the URL as opaque and send the customer's browser to it.
3. Retrieve the Payment again after the browser returns.
4. If the Payment still requires action and the URL changed, send the browser
   to the new URL. Do not loop back to an unchanged URL in the same session.

The action may be a hosted payment page or 3D Secure step. Your integration
does not need to infer the provider flow from the URL.

## Retry a request or create a new attempt

These are different actions:

* If the create request timed out or returned a retryable HTTP error, retry the
  same `Idempotency-Key` with an equivalent effective request identity. This
  retrieves or replays the result of the same Payment creation operation.
* If a Payment is terminal with `FAILED` or `EXPIRED` and the customer wants to
  try again, create a new Payment with a new `Idempotency-Key`.

You can reuse the same `merchant_reference` to associate several legitimate
attempts with one order. It labels attempts but does not deduplicate them.

## Status history and refunds

`status_transitions` contains the known lifecycle timestamps as Unix seconds.
After `SUCCEEDED`, use `amount_refundable` to decide whether a
[full or partial Refund](/guides/refunds) can be created.
