Cash-Out Receipt
Retrieves the receipt for a PIX transaction in a structured format, with data formatted for display to the end user.
Endpoint
GET /api/external/transactions/:id/receiptHeaders
| Header | Type | Required | Description |
|---|---|---|---|
Authorization | String | Yes | ApiKey {client_id}:{client_secret} |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
id | String | Yes | Transaction ID (transaction_id) |
Availability
The receipt queries the transactions table — available for transactions with final status (settled or failed). Transactions still in processing (state processing in outbound_requests, stage 1–2) return 404 here; query first via GET /transactions/:id and wait for promotion to transactions before requesting the receipt.
Paid QRs appear in the receipt of the linked real transaction (not the QR itself) — use the transaction_id returned in the pix.charge.paid webhook or via query.
Example
curl -X GET https://api.owem.com.br/api/external/transactions/PIXOUT20260309a1b2c3d4e5f6/receipt \
-H "Authorization: ApiKey $CLIENT_ID:$CLIENT_SECRET"Success Response -- 200
{
"worked": true,
"receipt": {
"transaction_id": "PIXOUT20260309a1b2c3d4e5f6",
"end_to_end_id": "E37839059202603091530abcdef01",
"external_id": "order-9876",
"type": "pix",
"direction": "outbound",
"status": "settled",
"amount": 300000,
"amount_formatted": "R$ 30,00",
"fee_amount": 350,
"fee_formatted": "R$ 0,035",
"net_amount": 300350,
"description": "Pagamento fornecedor",
"counterparty_name": "Joao Silva",
"recipient_key": "12345678901",
"created_at": "2026-03-09T15:30:00Z",
"completed_at": "2026-03-09T15:30:02Z",
"institution": {
"name": "Owem Pay",
"cnpj": "37.839.059/0001-88",
"ispb": "37839059"
}
}
}Receipt Fields
The receipt object contains exactly 17 fields (including the institution sub-object). This is the full inventory — there are no other fields returned by this endpoint:
| # | Field | Type | Description |
|---|---|---|---|
| 1 | receipt.transaction_id | String | Unique transaction identifier |
| 2 | receipt.end_to_end_id | String | End-to-End identifier in SPI/BACEN |
| 3 | receipt.external_id | String | External ID provided by the client on cash-out. null when not provided, or when the external ID did not pass the sanitize step (max 128 chars, only a-zA-Z0-9._:-) |
| 4 | receipt.type | String | Transaction type. Observed values: pix (default), pix_return (refund). Legacy rows may return other values (ted, tef, etc.) — the controller passes t.type through without filtering |
| 5 | receipt.direction | String | outbound or inbound when the field is persisted in transactions.direction. When nil, the controller falls back to Helpers.infer_direction/2, which returns only credit (target account is the recipient's) or debit (target account is the payer's) — never inbound/outbound in the inference path |
| 6 | receipt.status | String | Transaction status resolved via Helpers.format_status/1. Possible values: settled (normal), pending (transactions.status=2), failed (status=3), completed (legacy fallback for rows where status=1 and payment_status=nil). See possible values |
| 7 | receipt.amount | Integer | Value in base units (÷ 10,000 for BRL). 300000 = R$ 30.00 |
| 8 | receipt.amount_formatted | String | Amount formatted in BRL (R$ 30,00) |
| 9 | receipt.fee_amount | Integer | Fee in base units |
| 10 | receipt.fee_formatted | String | Fee formatted in BRL (includes sub-centavos when applicable, e.g., R$ 0,035) |
| 11 | receipt.net_amount | Integer | Net value in base units (fallback `t.net_amount |
| 12 | receipt.description | String | Transfer description |
| 13 | receipt.counterparty_name | String | Counterparty name (payer or recipient, as per direction) |
| 14 | receipt.recipient_key | String | Recipient PIX key (outbound only) |
| 15 | receipt.created_at | String | Creation date (ISO 8601, from t.started_at) |
| 16 | receipt.completed_at | String | Completion date (ISO 8601, from t.finished_at) |
| 17 | receipt.institution | Object | Issuing institution data — sub-object with name, cnpj (formatted XX.XXX.XXX/XXXX-XX), and ispb |
Formatted fields
The receipt includes _formatted fields with values already converted to BRL (e.g., R$ 30,00, R$ 0,035 for sub-centavo fees). Use these fields for display to the user. Use the numeric fields (amount, fee_amount, net_amount) for calculations. There is no net_amount_formatted — derive the display from amount_formatted + fee_formatted.
The receipt does NOT return counterparty fields
This endpoint explicitly omits the following fields that appear in other queries (e.g., GET /transactions/:id, GET /transactions/e2e/:e2e_id, Query PIX IN by ID):
payer_documentrecipient_documentpayer_ispbpayer_bank_name
If your integration assumed these fields in /receipt based on cash-in examples, it is reading undefined at runtime. For full counterparty data access (documents, ISPB, bank name), use GET /transactions/:id or GET /transactions/e2e/:e2e_id — both use the transactions table (same source) but expose the full shape via Helpers.format_external_transaction/1.
Receipt vs query by ID
The /receipt endpoint and the GET /transactions/:id endpoint use the same source (transactions) but return distinct shapes:
/receipt(17 fields): focused on display — adds_formatted,institution, and omits the 4 counterparty fields listed above.GET /transactions/:id(18 fields in the "settled" shape): focused on integration — includes full counterparty context (payer_document,recipient_document,payer_ispb,payer_bank_name,counterparty_name) useful for reconciliation, and omits_formattedfields.
Use /receipt to generate PDFs/emails/confirmation screens for the end user. Use GET /transactions/:id for programmatic integration and internal reconciliation.
Error Response -- 404
{
"worked": false,
"detail": "Transação não encontrada"
}