Reçu Cash-Out
Obtenez le reçu d'une transaction PIX au format structuré, avec des données formatées pour affichage à l'utilisateur final.
Endpoint
GET /api/external/transactions/:id/receiptHeaders
| Header | Type | Obligatoire | Description |
|---|---|---|---|
Authorization | String | Oui | ApiKey {client_id}:{client_secret} |
Path Parameters
| Paramètre | Type | Obligatoire | Description |
|---|---|---|---|
id | String | Oui | ID de la transaction (transaction_id) |
Disponibilité
Le reçu consulte la table transactions — disponible pour les transactions avec status final (settled ou failed). Les transactions encore en traitement (état processing dans outbound_requests, stage 1–2) retournent 404 ici ; consultez d'abord via GET /transactions/:id et attendez la promotion vers transactions avant de demander le reçu.
Les QRs payés apparaissent dans le reçu de la transaction réelle liée (pas du QR lui-même) — utilisez le transaction_id retourné dans le webhook pix.charge.paid ou via consultation.
Exemple
curl -X GET https://api.owem.com.br/api/external/transactions/PIXOUT20260309a1b2c3d4e5f6/receipt \
-H "Authorization: ApiKey $CLIENT_ID:$CLIENT_SECRET"Réponse de succès -- 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": "Paiement fournisseur",
"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"
}
}
}Champs du reçu
L'objet receipt contient exactement 17 champs (y compris le sous-objet institution). C'est l'inventaire complet — il n'y a pas d'autres champs retournés par cet endpoint :
| # | Champ | Type | Description |
|---|---|---|---|
| 1 | receipt.transaction_id | String | Identifiant unique de la transaction |
| 2 | receipt.end_to_end_id | String | Identifiant End-to-End dans le SPI/BACEN |
| 3 | receipt.external_id | String | ID externe fourni par le client au cash-out. null quand non renseigné, ou quand l'ID externe n'a pas passé le sanitize (max 128 caractères, uniquement a-zA-Z0-9._:-) |
| 4 | receipt.type | String | Type de la transaction. Valeurs observées : pix (défaut), pix_return (remboursement). Les rows legacy peuvent retourner d'autres valeurs (ted, tef, etc.) — le controller fait passthrough de t.type sans filtrer |
| 5 | receipt.direction | String | outbound ou inbound quand le champ est persisté dans transactions.direction. Quand nil, le controller fait fallback vers Helpers.infer_direction/2, qui retourne uniquement credit (compte cible est celui du bénéficiaire) ou debit (compte cible est celui du payeur) — jamais inbound/outbound dans le chemin d'inférence |
| 6 | receipt.status | String | Status de la transaction résolu via Helpers.format_status/1. Valeurs possibles : settled (normal), pending (transactions.status=2), failed (status=3), completed (fallback legacy pour les rows où status=1 et payment_status=nil). Voir valeurs possibles |
| 7 | receipt.amount | Integer | Valeur en unités de base (÷ 10 000 pour reais). 300000 = R$ 30,00 |
| 8 | receipt.amount_formatted | String | Valeur formatée en reais (R$ 30,00) |
| 9 | receipt.fee_amount | Integer | Frais en unités de base |
| 10 | receipt.fee_formatted | String | Frais formatés en reais (inclut sub-centavos quand applicable, ex. : R$ 0,035) |
| 11 | receipt.net_amount | Integer | Valeur nette en unités de base (fallback `t.net_amount |
| 12 | receipt.description | String | Description du virement |
| 13 | receipt.counterparty_name | String | Nom de la contrepartie (payeur ou bénéficiaire, selon direction) |
| 14 | receipt.recipient_key | String | Clé PIX du destinataire (uniquement sorties) |
| 15 | receipt.created_at | String | Date de création (ISO 8601, venant de t.started_at) |
| 16 | receipt.completed_at | String | Date de conclusion (ISO 8601, venant de t.finished_at) |
| 17 | receipt.institution | Object | Données de l'institution émettrice — sous-objet avec name, cnpj (formaté XX.XXX.XXX/XXXX-XX) et ispb |
Champs formatés
Le reçu inclut des champs _formatted avec des valeurs déjà converties en reais (ex. : R$ 30,00, R$ 0,035 pour les frais sub-centavo). Utilisez ces champs pour l'affichage à l'utilisateur. Utilisez les champs numériques (amount, fee_amount, net_amount) pour les calculs. Il n'y a pas de net_amount_formatted — dérivez l'affichage de amount_formatted + fee_formatted.
Le reçu NE retourne PAS les champs de contrepartie
Cet endpoint omet explicitement les champs suivants qui apparaissent dans d'autres consultations (ex. : GET /transactions/:id, GET /transactions/e2e/:e2e_id, Consulter PIX IN par ID) :
payer_documentrecipient_documentpayer_ispbpayer_bank_name
Si votre intégration a supposé ces champs dans /receipt basée sur des exemples de cash-in, elle lit undefined à l'exécution. Pour accéder aux données complètes de la contrepartie (documents, ISPB, nom de la banque), utilisez GET /transactions/:id ou GET /transactions/e2e/:e2e_id — les deux utilisent la table transactions (même source) mais exposent le shape complet via Helpers.format_external_transaction/1.
Reçu vs consultation par ID
L'endpoint /receipt et l'endpoint GET /transactions/:id utilisent la même source (transactions) mais retournent des shapes distincts :
/receipt(17 champs) : focus sur l'affichage — ajoute_formatted,institution, et omet les 4 champs de contrepartie listés ci-dessus.GET /transactions/:id(18 champs dans le shape « settled ») : focus sur l'intégration — inclut le contexte complet de la contrepartie (payer_document,recipient_document,payer_ispb,payer_bank_name,counterparty_name) utile pour la conciliation, et omet les champs_formatted.
Utilisez /receipt pour générer des PDFs/emails/écrans de confirmation à l'utilisateur final. Utilisez GET /transactions/:id pour l'intégration programmatique et la réconciliation interne.
Réponse d'erreur -- 404
{
"worked": false,
"detail": "Transação não encontrada"
}