Skip to content

Payments lifecycle and statuses

Most integrations do not create payments directly: they create a checkout session and let the hosted checkout take the card. POST /v1/payments is for merchants who already hold a card token (stored_token) or use the switch's hosted fields (hosted_fields with a clientToken). Either way, the lifecycle is the same.

Status Meaning Final?
created The payment exists; no processor has it yet. no
requires_action The customer must act (3-D Secure). nextAction says how: { "type": "redirect", "url" } or { "type": "client_secret", "clientSecret" }. no
processing Sent; waiting for the processor. no
unknown The processor did not answer in time (timeout, network error, 5xx). The payment may or may not have been charged. no
authorized Approved and held (manual capture); capture with POST /v1/payments/{id}/capture, release with /void. no
succeeded Captured. yes
failed Declined or refused (including "no processor could take it"). yes
cancelled Voided, or closed before reaching any processor. yes

How a status changes:

  • Only server-side evidence moves a payment: a signed webhook from the processor or switch, a server-to-server status fetch, or the processor's direct answer to GIEP's own call. A shopper's browser coming back to a return URL is never evidence of an outcome (at most it moves created to processing).
  • A final status never changes into a different final status. Late or out-of-order events are ignored. If two sources disagree about a final status, the payment is flagged needsReview: true and an event payment.needs_review is recorded; a person decides.
  • POST /v1/payments/{id}/sync asks the processor for the current status (safe to repeat). While the processor still cannot confirm, it answers 503 reconcile_pending or 503 provider_unavailable: try again shortly.

unknown: a timeout is never a decline

GIEP never treats unknown as a decline and never retries an unknown attempt on another processor, because the first one may have charged the card. Instead it reconciles: it looks the attempt up at the processor by its idempotency key (GIEP derives one per attempt, <paymentId>:attempt:<n>, and stores it before the call). A scheduled sweep does this every 5 minutes for stuck payments, and also catches up payments whose webhook was lost.

not_received

If, after a grace period, the processor confirms it never received the in-doubt attempt, that attempt is recorded as failed with decline code not_received, and only then may the payment move on to the next eligible processor as a new attempt with its own key. The routing log shows "confirmed it never received attempt N". A not_received is not a decline by the issuer.

needsReview

needsReview: true means a person must look at the payment. It is set when:

  • reconciliation still has no answer 24 hours after the payment was created (its status is left as it is; GIEP never invents an outcome, and a health alert lists the payment);
  • two sources reported conflicting final outcomes;
  • a result arrived for an attempt after another process had taken it over;
  • a card on the blocklist reached a processor (hosted fields keep the card number from GIEP, so it can only be known after the fact; nothing is voided or refunded automatically).

A payment flagged for review cannot be reprocessed until the flag is resolved.

Cascading and reprocessing

On a definitive soft decline the payment may be retried on the next eligible processor (the store's cascade settings and the decline-code tables decide). Hard, fraud, insufficient-funds and authentication declines are not cascaded. POST /v1/payments/{id}/reprocess starts a new attempt on a failed payment whose card can be charged again (see the reference for the exact conditions); processorAccountId forces one account (routing:override).

Card data

GIEP never receives card numbers: cards are entered in the payment switch's hosted fields and GIEP gets a token. Card facts you already hold (cardBin, cardLast4, expiry, a processor fingerprint) can be passed for the blocklist and BIN routing rules.