Skip to main content
Cash-in and cash-out operations return different identifiers at different moments, and they reach their final status in different ways. This page explains those differences and the practices that keep your integration free of duplicate payouts and unreconciled payments. You use these identifiers for reconciliation, transaction tracking, idempotency, duplicate prevention, lookups and operational investigations, so persist every one of them.
Coming from V1? Every V2 path starts with /v2, the receiving or paying account is bank_account_id (there are no virtual accounts), responses use inserted_at / updated_at instead of timestamp, and origin_type became the nested origin.{id,type}. The cash-out response already returned out_document_id in V1 and still does.

Identifier overview

Cash out

The identifier is final from the start

A cash-out request creates the financial transaction immediately, so POST /v2/out/pix/async and POST /v2/out/pix return the final transaction identifier in the response:
out_document_id already identifies the out document. When the payment needs approval, approval_request_id carries the ID of the approval request. Persist out_document_id and use it for status queries, reconciliation, receipt validation, support investigations and audit trails. You read the document back with GET /v2/documents/out/{id}.

Lifecycle

An out document is created and ends as either settled or failed:
Both settled and failed are final states. Once either is reached, no further events occur and the transaction lifecycle is permanently closed.

Understanding failed

A cash out that reaches failed was not completed, is finalized immediately and receives no further updates. Possible causes include:
  • Invalid Pix key;
  • Banking rejection;
  • Insufficient balance;
  • Banking processing failures.

Understanding settled

A cash out that reaches settled was completed, the funds were delivered and the transaction becomes immutable.

Response times

Timeouts

If a cash-out request times out, do not create another payment request right away. The transaction may have been processed successfully, and a second request without validation generates a duplicate payout.
Before retrying:
  1. Search the out document with the same external_id using GET /v2/documents/out/search;
  2. Check the webhook notifications you received;
  3. Check your reconciliation status;
  4. Contact Trio support if you still cannot tell what happened.

Cash in

The first identifier is the QR code, not the payment

A cash-in request only creates the QR code. At that stage the payment has not happened, there is no financial settlement and no final transaction document exists. POST /v2/in/pix/qrcodes returns the QR code identifier in data.id:
Treat data.id as the QR code identifier (the ref_id), not as the final financial transaction identifier. The in document id is generated only after a successful settlement.

Settlement

Once the payment completes, Trio sends a settled webhook containing the external_id, the ref_id (the QR code id) and the final in document id. These three fields let you associate the QR code request, the payment confirmation and the final financial transaction.
The in document itself also points back to the QR code: GET /v2/documents/in/{id} returns reference.id with the QR code id and reference.type as pix_qrcode, and GET /v2/documents/in/search finds the document by external_id.

Lifecycle

Possible sequences of events for a cash in:
For cash in, failed is not necessarily a final status. A failed event only means that a payment attempt was rejected. It does not mean that the QR code expired, that it was canceled or that the operation is permanently closed: the QR code remains active and may still receive future payment attempts. Common failed scenarios include third-party payment attempts, rejected payer validations and business rule validation failures. See Closed-loop reconciliation for the compliance rules that refuse a deposit. Once a cash in reaches settled, the payment is finalized, the in document id is generated, the QR code is automatically closed and no further events occur. After settlement, additional failed events are not possible.

Response times and retries

If you receive no response within 500ms while generating a QR code, you may create a new request, but it must use a new external_id.

external_id and idempotency

external_id is the primary reconciliation identifier between your platform and Trio, and it must be unique for every operation. Cash-in and cash-out operations enforce an idempotency window of 24 hours (1 day). During this period the same external_id cannot be reused and duplicate requests may return the previous transaction, which prevents accidental duplicate operations. Recommended:
  • Use UUIDs;
  • Persist all identifiers in your database;
  • Associate identifiers with your internal orders or payments;
  • Query the transaction before retrying a request.
Avoid:
  • Reusing identifiers;
  • Sequential IDs;
  • Blind automatic retries;
  • Creating new operations without validating the previous one.

Webhook processing

Treat webhooks as the source of truth for final transaction status updates.
For production environments:
  • Process webhooks asynchronously;
  • Return HTTP 200 OK immediately;
  • Persist webhook payloads;
  • Maintain an audit history;
  • Avoid long-running synchronous processing.
See Webhooks for the delivery model and retry schedule.

Summary

Cash-in and cash-out operations behave differently and need different handling. For cash out:
  • The final transaction identifier (out_document_id) is returned immediately;
  • failed and settled are terminal states;
  • Handle timeout retries carefully to avoid duplicate payouts.
For cash in:
  • The initial request creates only the QR code reference (ref_id);
  • The final financial transaction exists only after settlement;
  • failed does not necessarily represent a permanent failure;
  • Multiple payment attempts may occur before settlement;
  • The in document id is received only through the webhook notification.
For both:
  • external_id is always unique;
  • All identifiers are persisted for reconciliation;
  • Webhooks are the authoritative source of transaction state;
  • Proper timeout and retry handling prevents duplicate operations and reconciliation inconsistencies.

Next steps