Skip to main content
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:
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.

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.

Statuses

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

Track the authoritative result

Subscribe to 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:
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.
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.

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 can be created.