> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ecomm365.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.

## Payment method and card details

`payment_method` groups the method and any available masked card details:

```json theme={null}
{
  "payment_method": {
    "type": "card",
    "card": {
      "brand": "visa",
      "last4": "2207",
      "exp_month": 12,
      "exp_year": 2027
    }
  }
}
```

`payment_method.type` is an extensible string. Known values are `card`,
`apple_pay`, and `google_pay`; handle unfamiliar values without failing or
treating them as card. Every Payment includes `payment_method`; null means unknown. Its
optional `card` contains only safe metadata, with the existing masked-field
meanings. Card details may be absent or null, and a non-card method need not
have them. Wallet credentials, format, and Google authentication data are not
response fields.

For Direct API, the method identifies the submitted attempt even before
authorization. For HPP, it remains unknown until the shopper's selected method
is established; do not infer it from a card network or the choices offered on
the page. The method is separate from `integration_type`, card brand, and
Payment status. Recognizing a wallet type does not by itself prove that the
upstream wallet route is provisioned. Direct decrypted wallet creation follows
the same Payment lifecycle; encrypted wallet creation is reserved in this
release. Apple Pay and Google Pay are Experimental: their support and this
guidance are still being refined and are not final. See
[wallet contract availability](/guides/direct-api#wallet-contract-availability).

### Update your response parser before launch

Masked card details have moved from top-level `card` to `payment_method.card`
in Payment create, retrieve, and list responses. This is a breaking response
change: update parsers, displays, and saved response fixtures that use paths
such as `card.last4` to use `payment_method.card.last4`. Do not expect both
copies. Card request fields, statuses, amounts, `integration_type`, and Refund
representations are unchanged.

Payment events use the same grouped form. Update webhook handlers to read
`data.object.payment_method.card` as described in
[Payment event snapshots](/guides/webhooks#payment-method).

## 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.

Flowlix retries eligible provider calls in bounded bursts. After an uncertain
authentication or wallet execution, it reconciles the existing provider order;
a failed technical read does not turn the Payment into `FAILED` or establish
that it expired. Background refresh is finite, so an unresolved Payment is not
guaranteed to finish within a particular period. Continue using its ID and
contact support instead of creating a replacement while its outcome is unknown.

<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>

## Optional card details

In Payment responses and Payment event snapshots, `payment_method.card`
may be omitted or null, including when a card payment has `status: SUCCEEDED`.
When present, the block contains `brand`, `last4`, `exp_month`, and `exp_year`;
additional card metadata may be optional.

Use the Payment's `status` to determine its outcome. Handle absent card details
without treating a successful payment as failed or waiting for the card block
before fulfilment.

## 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.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.