Skip to main content
A Payment represents one attempt to collect funds. It always moves forward through a defined set of states and ends in exactly one terminal state.

State diagram

A payment rejected before it reaches the card networks (for example, by validation at the provider) moves directly from PENDING to FAILED.
A status is a snapshot of the current state, not a step on a progress bar. Non-terminal statuses can alternate: a direct payment that is PROCESSING may move to REQUIRES_ACTION when the issuer requests 3D Secure, then back to PROCESSING once the customer completes it. Only the four terminal states (SUCCEEDED, FAILED, EXPIRED, CANCELED) are final. Transition history is preserved in status_transitions.

Statuses

StatusTerminalMeaning
PENDINGNoAccepted by Flowlix, waiting to be processed.
REQUIRES_ACTIONNoThe customer must act — complete 3D Secure or the hosted payment page. The action URL is in next_action.redirect_url. Can occur before or after PROCESSING.
PROCESSINGNoSubmitted to downstream payment systems; the outcome is not yet known. Flowlix synchronizes the provider result automatically — no merchant action is needed.
SUCCEEDEDYesFunds were collected. The payment becomes refundable (amount_refundable).
FAILEDYesDeclined or failed permanently. decline_code and decline_message say why.
CANCELEDYesCanceled before completion (for example, the customer canceled on the hosted page).
EXPIREDYesThe customer did not complete a required action before its expiry time.
Timestamps for each transition are exposed in status_transitions (processing_at, succeeded_at, failed_at, …), all as Unix timestamps in seconds.

Tracking the outcome

Two complementary mechanisms:

Webhooks (recommended)

Flowlix calls your endpoint the moment a payment reaches a new state. Best latency, no polling load.

Polling

Call GET /v1/payments/{id} until the status is terminal. Simple and dependable; use it as a fallback even when you use webhooks.

Polling guidance

  • Poll every 2–5 seconds while a payment is PROCESSING or REQUIRES_ACTION and the customer is waiting on your page.
  • Switch to a slower background schedule (for example every minute, then every 10 minutes) after the customer leaves.
  • Treat only terminal statuses as final. A payment in PROCESSING resolves automatically — you never need to re-submit it.
  • If a payment is still non-terminal after 24 hours, contact support with the payment ID and Request-Id; do not create a duplicate charge.

Reacting to each status

  • SUCCEEDED — fulfil the order. Record amount_refundable if you may need refunds.
  • FAILED — read decline_code to decide: ask for another payment method (insufficient_funds, expired_card), allow a plain retry (processor_unavailable, try_later), or do not retry (stolen_card, fraud_filter).
  • EXPIRED / CANCELED — the attempt is over; create a new payment if the customer wants to try again. Reuse your merchant_reference so all attempts for the order stay linked.

Multiple attempts per order

One order in your system may legitimately produce several Payment objects: a decline followed by a retry, or an abandoned hosted page followed by a new one. Use merchant_reference to group attempts, and make sure at most one of them is fulfilled — the Idempotency-Key header protects you against accidental duplicates of the same attempt, while merchant_reference only labels attempts and never blocks them.