Errors
The Fluveo /v1 API uses conventional HTTP status codes and a Stripe-compatible
error envelope. A 2xx is success; a 4xx means something about your request
needs fixing; a 5xx is a problem on Fluveo’s side.
The error envelope
Every error returns JSON with a top-level error object:
Public responses use Stripe field names and never leak internal connector/provider/acquirer identifiers.
Error types
Common error codes
These code values appear most often on the payment path (see the full schemas
in the API Reference):
Decline codes (decline_code)
On a card_declined response, decline_code carries the machine-readable
reason. The common values:
When the card issuer declines while a PaymentIntent is being confirmed (create
with confirm=true, an update with confirm=true, or /confirm), the error
object also carries payment_intent: the PaymentIntent as a retrieve returns
it. Usually its status is requires_payment_method and last_payment_error is
set. If a held card failed its security-code check and the hold is not yet
released, the status is processing and last_payment_error is null.
These 402 declines do not carry payment_intent: an antifraud refusal, a
card brand the merchant’s acquirer does not accept, a decline reported as an
error by the payment processor instead of by the issuer, and the rare case
where the PaymentIntent could not be read back at the time of the decline.
Retrieve the PaymentIntent to see its state.
Antifraud screening
Card payments are screened for fraud before they reach the card network.
If screening refuses a payment, the confirm call returns 402 with
code: "card_declined" and decline_code: "fraudulent" — the same shape as
any other decline, and the payment never reaches the issuer (no authorization,
no charge). A refusal is indistinguishable from a network decline by
design; do not surface “fraud” wording to the shopper.
Notes:
- Retrying the same card on the same PaymentIntent replays the refusal. A shopper may try a different card, which is screened fresh.
- The intent stays in
requires_confirmationafter a screening refusal (it is not moved torequires_payment_method); read the PaymentIntent if you need its current state. This is a documented deviation from Stripe’s post-decline state. - In the sandbox, screening runs against the provider sandbox; refusals are
deterministic for the provider’s designated test cards so you can exercise
the
402path end to end.
Handling errors
A practical pattern:
- Branch on
error.type, not onmessagetext (messages may change). - For
card_error, show the customer a clear, non-technical decline message; thedecline_codetells you why but is for your logs, not the cardholder. - For
invalid_request_error, fix the field named inparam— these are programming errors, not runtime conditions. - For
rate_limit_error(429), back off exponentially before retrying. - For
api_error(5xx), retry the same request with the sameIdempotency-Keyso you never double-charge. Idempotent retries are the safe way to recover from transient failures — see the quickstart.
For the canonical envelope reference, see the overview.