Skip to main content

Documentation Index

Fetch the complete documentation index at: https://developers.bloobank.com/llms.txt

Use this file to discover all available pages before exploring further.

Every payment order traverses a deterministic sequence of states from creation to a final state. The states are visible in the status field of every order and they drive webhook events.

States

StatusTypeMeaning
AWAITING_APPROVALInitial (OUT only)Outbound order created. Awaiting PUT .../approve or PUT .../cancel. No money has moved.
PENDINGTransitionalOrder accepted by the platform and submitted to the provider. The provider has not yet returned a definitive outcome.
PROCESSINGTransitionalProvider has acknowledged the order and is executing it.
SUCCESSFinalProvider confirmed settlement. Funds moved (in/out).
FAILEDFinalProvider rejected or could not complete the order. errorCode and errorMessage are populated.
CANCELEDFinalOrder canceled before reaching the provider. (Only possible for OUT orders in AWAITING_APPROVAL.)
EXPIREDFinalInbound dynamic QR/EMV expired before the payer settled.
REFUNDEDFinalA previously SUCCESS order was refunded.
A final state is terminalstatus will not change again. To reverse a SUCCESS, you create a new order in the opposite direction (or a refund flow, where supported).

Inbound (IN) state machine

Inbound orders start in PENDING immediately. There is no approval step — the platform submits to the provider as part of POST.
TransitionWhen
PENDINGPROCESSINGProvider has issued the PIX payment instrument (QR rendered, copy-paste available).
PROCESSINGSUCCESSA payer has scanned/paid; the PIX network confirms settlement.
PROCESSINGEXPIREDexpiresIn elapses without settlement.
PROCESSINGFAILEDProvider rejects the order (rare for PIX).
SUCCESSREFUNDEDOperator initiates a refund.

Outbound (OUT) state machine

Outbound orders pause in AWAITING_APPROVAL until you explicitly approve. This gate is where you implement business rules — dual control, anti-fraud, balance verification.
TransitionWhen
AWAITING_APPROVALPENDINGPUT .../approve succeeds. Funds become locked on the wallet.
AWAITING_APPROVALCANCELEDPUT .../cancel. No money moved. Order is permanently canceled.
PENDINGPROCESSINGProvider acknowledged receipt.
PROCESSINGSUCCESSFunds settled at the recipient. locked decreases, amount decreases.
PROCESSINGFAILEDProvider rejected or recipient unreachable. locked decreases, amount unchanged. errorCode populated.

What you can do per state

ActionAWAITING_APPROVALPENDINGPROCESSINGSUCCESSFAILEDCANCELEDEXPIREDREFUNDED
GET (read order)
PUT .../approve✅ (OUT only)❌ → PAYMENT_ORDER_NOT_AWAITING_APPROVAL
PUT .../cancel✅ (OUT only)❌ → PAYMENT_ORDER_INVALID_STATE
approve and cancel are valid only in AWAITING_APPROVAL. Any attempt at another state returns PAYMENT_ORDER_NOT_AWAITING_APPROVAL or PAYMENT_ORDER_INVALID_STATE (HTTP 422).

Webhook events per transition

Every state transition fires a webhook event:
TransitionEvent
Order createdpayment_order.created
PROCESSINGpayment_order.processing
SUCCESSpayment_order.success
FAILEDpayment_order.failed
CANCELEDpayment_order.canceled
EXPIREDpayment_order.expired
REFUNDEDpayment_order.refunded
Approvedpayment_order.approved
See Payment events for full event payloads.

Polling vs. webhooks

  • Webhooks are the recommended source of truth — they push immediately on transition.
  • Polling (GET .../paymentOrders/{id}) is a valid fallback when you cannot expose a webhook endpoint, but be mindful of rate limits.
A reasonable polling cadence for transient states:
StatePolling interval
PENDINGEvery 5–10 seconds
PROCESSINGEvery 5–10 seconds
Final statesStop polling

Error fields on FAILED

When status is FAILED, the order exposes:
{
  "status": "FAILED",
  "errorCode": "INSUFFICIENT_FUNDS",
  "errorMessage": "Insufficient available balance to complete this transfer."
}
FieldNotes
errorCodeProvider-reported code in UPPER_SNAKE_CASE. The catalog evolves with provider integrations.
errorMessageHuman-readable description. Suitable for direct display in some cases.
Common errorCode values include INSUFFICIENT_FUNDS, RECIPIENT_INVALID, LIMIT_EXCEEDED. Branch on errorCode, not errorMessage.

EXPIRED is final, even if the payer pays late

For inbound dynamic QR codes, EXPIRED is terminal. If the payer pays after expiration:
  • The PIX network typically rejects the payment at their end (the QR is no longer valid).
  • In rare cases where settlement is force-completed, the funds may still appear in your wallet. They will not transition the order — they remain as an unattributed balance entry visible in the wallet ledger.
To handle this safely: do not promise the payer immediate fulfillment based solely on SUCCESS. Reconcile against your local ledger.

State invariants

A few rules to internalize:
  • A payment order cannot move from a final state to a transitional state.
  • direction is set at creation and never changes.
  • idempotencyKey is set at creation and never changes.
  • amount and network are set at creation and never change.
  • errorCode and errorMessage are populated only on FAILED; null otherwise.
  • processedAt is null until the order leaves PENDING for the first time; once set, it does not change.

Next

Payments overview

The payment-order resource model.

Pix cash-in tutorial

End-to-end inbound flow.

Webhooks

Receive state transitions in real time.