Errors and states
Every reason a payment request is refused, what to tell the user, and what each state of a hold means.
On this page
A refusal is an ordinary Flowion error, with the same body as every other (errors, pagination and versioning): switch on error, never on message. The set of reasons is closed, so you can write a sentence for each.
Why a request is refused
error | Status | What it means | What to do |
|---|---|---|---|
missingIdempotencyKey | 400 | The request for a hold has no Idempotency-Key header | Send one |
invalidRequest | 400 | The key is too long, or payerReference is empty, longer than 200 characters or looks like an email address | Send an opaque reference of your own |
forbidden | 403 | The caller is not an API key (a member's sign-in is refused here), or the key lacks the settlement.payment.hold permission | Call from your backend with a project key that holds it |
notFound | 404 | No such charger or hold in your project and the key's mode. A hold of another project, and one a person placed in Flowion Home, read the same | Check the id and the key's mode |
accountNotReady | 409 | The organization cannot take card payments right now: no connected account, one Stripe has restricted, or a sandbox project asking for real money | Tell the user the charger cannot take payment. The organization fixes its Stripe account |
chargerUnsafeForHold | 409 | The hold amount is too small for this charger's speed | The organization raises the hold amount |
notAPaidCharger | 409 | The charger does not take card payments | Start it as an ordinary charge |
holdNotAuthorized | 409 | The hold is not authorized, so nothing can start under it | Wait for authorized, or ask for a new hold |
windowEnded | 409 | The five minutes to start are over | Ask for a new hold |
alreadyStarted | 409 | This hold has already started its session | Read the hold. Never start twice |
noOpenSession | 409 | A stop for a hold with no running session | Read the hold: only started has a session to stop |
notCaptured | 409 | Nothing has been taken on this hold yet | Ask for the receipt once the hold says captured |
sellerUnavailable | 503 | Your organization's details cannot be read from Stripe right now | Retry shortly. The receipt can also come back with its amounts and sellerUnavailable set to true |
paymentsUnavailable | 503 | Payments cannot be reached right now | Retry shortly, with the same Idempotency-Key for a hold |
commandsUnavailable | 503 | The charger cannot be reached for a start or a stop | Retry shortly |
A card that is declined, and a bank that wants the user's approval, are not errors of these routes: they happen in the Payment Element in your page, which tells you, and Flowion then moves the hold to declined, or keeps it at requires_action until the user has approved. Read the hold for what became of it.
Which of these a given route can answer is on its page in the API reference. A 503 carries Retry-After, and a new reason can be added within /v1, so keep a fallback for an unknown code.
What a hold's state means
state | Means |
|---|---|
requested | Recorded, and Stripe has not answered yet |
requires_action | The user has not confirmed the hold yet: this is how a new hold starts. It also means the bank wants approval in the Payment Element |
authorized | The card is held. A session can start, once |
started | The session is running. This is the only state that means so |
ended | The session has ended, and its price is being taken |
captured | The price was taken and the rest released. The receipt is ready |
capture_failed | Taking the price failed. Flowion retries a bounded number of times |
declined | The bank declined. Nothing was started |
released | The hold was released with nothing taken |
expired | The five minutes passed with no session, and the hold was released |
unpaid | The session cost something that could not be taken |
The set is open: show an unknown state as "in progress" rather than failing.