Skip to content

Payloads des Webhooks

Exemples de payloads envoyes pour chaque type d'evenement. Tous les webhooks sont envoyes en HTTP POST avec Content-Type: application/json.

En-tetes de securite

Chaque notification inclut les en-tetes X-Owem-Signature (HMAC-SHA256), X-Owem-Timestamp, X-Owem-Event-Id et X-Owem-Event-Type. Consultez Webhooks — Vue d'ensemble pour les details de validation.


Reference des Statuts

Tous les evenements ne signifient pas que la transaction est terminee. Utilisez le tableau ci-dessous pour savoir quand les fonds ont ete effectivement regles.

EvenementStatutSignificationFonds regles ?
pix.charge.createdcreatedQR code généré ou cash-in initié. En attente de paiement.Non — juste créé
pix.charge.paidpaidPIX reçu et réglé sur le compte. Solde mis à jour, frais débités.Oui
pix.charge.expiredexpiredQR code expiré sans paiement.N/A
pix.charge.cancelledcancelledQR code annulé explicitement par le merchant avant le paiement.N/A
pix.payout.queuedqueuedPIX envoyé mis en file par rate limit (ClientLimiter ou bucket DICT). Pas encore de débit.Non — en attente de quota
pix.payout.processingprocessingPIX envoyé, en attente de confirmation du destinataire. Solde réservé (hold).Non — peut être annulé
pix.payout.confirmedsettledPIX envoyé confirmé par le destinataire. Débit définitif.Oui
pix.payout.failedrejectedPIX envoyé rejeté par le destinataire. Hold libéré, solde restauré.Non
pix.payout.returnedreturnedPIX envoyé remboursé après règlement.Oui (inverse)
pix.refund.requestedrequestedRemboursement PIX demandé (MED). Blocage conservatoire créé.Partiel
pix.refund.completedsettled / completedRemboursement PIX complété et réglé. Débit définitif.Oui
pix.return.receivedsettledRetour PIX reçu et réglé sur le compte.Oui
pix.infraction.createdACKNOWLEDGEDInfraction PIX signalée contre vous. Exige une action.Partiel — blocage conservatoire si >R$1k
pix.infraction.resolvedCLOSED / CANCELLEDInfraction résolue (remboursement exécuté ou refusé).N/A — effet dans un autre événement
pix.infraction.defense_submitteddefense_submittedDéfense soumise par le merchant. En attente BACEN.N/A
webhook.testtestÉvénement de test déclenché manuellement via portail Admin/Merchant.N/A

Règles de réconciliation :

  • Considérez les entrées de solde uniquement dans les status : paid (crédit PIX IN) et returned (inversion d'un PIX OUT envoyé précédemment).
  • Considérez les sorties de solde uniquement dans les status : settled (débit PIX OUT confirmé) et completed (débit MED refund définitif), et settled dans pix.return.received (inversion d'un PIX IN reçu précédemment).
  • Tous les autres status (created, queued, processing, rejected, expired, requested, ACKNOWLEDGED, defense_submitted, etc.) sont intermédiaires — ils ne déclenchent pas de mouvement comptable de votre côté.
  • Ne traitez pas pix.payout.processing comme une confirmation ; attendez l'événement terminal (pix.payout.confirmed ou pix.payout.failed).

Champs communs

Tous les payloads de webhook incluent ces champs :

ChampTypeDescription
event_typestringType d'evenement ayant declenche le webhook (ex : pix.charge.paid)
statusstringStatut de l'operation — voir la Reference des Statuts
account_idintegerNumero de votre compte chez Owem
entity_idstring (UUID)Identifiant d'entite Owem

Valeurs monetaires : Tous les montants sont en subcentavos (1 BRL = 10 000 subcentavos). Pour convertir en reais : montant / 10000. Exemple : 300000 / 10000 = R$ 30,00.


pix.charge.paid

Envoye quand un PIX est recu et regle sur le compte. C'est l'evenement qui confirme que l'argent est arrive.

Exemple — lie a un QR code

json
{
  "event_type": "pix.charge.paid",
  "status": "paid",
  "account_id": 10014,
  "amount": 300000,
  "fee_amount": 400,
  "end_to_end_id": "E9040088820260402095758709999671",
  "entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
  "tx_id": "u5f26sfyrq4plkw7tjwa",
  "qr_code_id": "f401d5e3-a2b1-4c8e-9f3d-1234567890ab",
  "counterparty_name": "MARIA SANTOS",
  "payer_document": "12345678901",
  "payer_ispb": "60701190",
  "payer_bank_name": "Itau Unibanco S.A.",
  "external_id": "order-9876",
  "paid_at": "2026-04-02T09:58:05Z"
}

Exemple — transfert direct (sans QR)

json
{
  "event_type": "pix.charge.paid",
  "status": "paid",
  "account_id": 10014,
  "amount": 300000,
  "fee_amount": 400,
  "end_to_end_id": "E9040088820260402095758709999671",
  "entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
  "tx_id": null,
  "qr_code_id": null,
  "counterparty_name": "JOAO SILVA",
  "payer_document": "98765432100",
  "payer_ispb": "00000000",
  "payer_bank_name": "Banco do Brasil S.A.",
  "external_id": null,
  "paid_at": "2026-04-02T10:15:22Z"
}
ChampTypeDescription
event_typestringToujours pix.charge.paid
statusstringToujours paid
account_idintegerNumero de compte ayant recu le PIX
amountintegerMontant recu en subcentavos. 300000 = R$ 30,00
fee_amountintegerFrais debites en subcentavos. 400 = R$ 0,04
end_to_end_idstringIdentifiant E2E du BACEN (unique par transaction PIX)
entity_idstring (UUID)Identifiant d'entite Owem
tx_idstring ou nullID de transaction. Present quand lie a un QR code. null pour les transferts directs
qr_code_idstring ou nullUUID du QR code associe. null pour les transferts directs
counterparty_namestring ou nullNom du payeur (expediteur)
payer_documentstring ou nullCPF/CNPJ du payeur (chiffres uniquement)
payer_ispbstring ou nullISPB (8 chiffres) de l'institution du payeur
payer_bank_namestring ou nullNom de l'institution du payeur, resolu via le cache BCB (896 banques)
external_idstring ou nullVotre identifiant externe. Present lorsque le QR code a ete cree via l'API avec external_id. null pour les transferts directs ou QR sans external_id
paid_atstring (ISO 8601)Horodatage du reglement (UTC)

pix.charge.created

Envoye quand un QR code est genere ou un cash-in est initie. Aucun mouvement financier n'a eu lieu.

json
{
  "event_type": "pix.charge.created",
  "status": "created",
  "account_id": 10014,
  "amount": 500000,
  "entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
  "tx_id": "abc123def456ghi789"
}

pix.payout.confirmed

Envoye quand un PIX envoye est confirme par l'institution destinataire. Debit definitif.

json
{
  "event_type": "pix.payout.confirmed",
  "status": "settled",
  "account_id": 10014,
  "amount": 500000,
  "fee_amount": 200,
  "end_to_end_id": "E3783905920260402101500000001",
  "entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
  "transaction_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "external_id": "payment-456",
  "pix_key": "destinataire@email.com",
  "pix_key_type": "EMAIL",
  "description": "Paiement fournisseur",
  "initiated_at": "2026-04-02T10:14:59Z",
  "recipient": {
    "name": "EMPRESA DESTINO LTDA",
    "document": "12345678000199",
    "ispb": "60701190",
    "account": "12345678",
    "agency": "0001",
    "institution_name": "Itau Unibanco S.A."
  },
  "sender": {
    "name": "MINHA EMPRESA LTDA",
    "document": "98765432000100",
    "ispb": "37839059",
    "account": "00001234",
    "agency": "0001"
  }
}
ChampTypeDescription
event_typestringToujours pix.payout.confirmed
statusstringToujours settled -- debit definitif
amountintegerMontant envoye en subcentavos
fee_amountintegerFrais debites en subcentavos
end_to_end_idstringIdentifiant E2E du BACEN
transaction_idstring (UUID)Identifiant unique de la transaction
external_idstring ou nullVotre identifiant externe
pix_keystringCle PIX du destinataire
pix_key_typestringType de cle : CPF, CNPJ, EMAIL, PHONE, EVP
descriptionstring ou nullDescription fournie par l'expediteur
initiated_atstring (ISO 8601)Horodatage du cash-out original (pas l'heure du settlement -- pour cela utilisez X-Owem-Timestamp du header)
recipientobjectDonnees bancaires du destinataire (resolues via DICT)
recipient.namestring ou nullNom du titulaire du compte destination
recipient.documentstring ou nullCPF/CNPJ du destinataire (chiffres uniquement)
recipient.ispbstring ou nullISPB de l'institution destination
recipient.accountstring ou nullNumero du compte destination
recipient.agencystring ou nullAgence du compte destination
recipient.institution_namestring ou nullNom de l'institution destination (resolu via le cache BCB)
senderobjectDonnees bancaires du compte expediteur (votre compte Owem)
sender.namestring ou nullNom du titulaire du compte expediteur
sender.documentstring ou nullCPF/CNPJ de l'expediteur (chiffres uniquement)
sender.ispbstring ou nullISPB d'Owem Pay (37839059)
sender.accountstring ou nullNumero du compte expediteur
sender.agencystring ou nullAgence du compte expediteur

pix.payout.processing

Envoye quand un PIX envoye est en cours de traitement. Le solde est reserve (hold) mais pas definitif. Cet evenement est optionnel -- si vous ne souhaitez etre notifie que de l'etat terminal, ignorez-le et attendez pix.payout.confirmed ou pix.payout.failed.

json
{
  "event_type": "pix.payout.processing",
  "status": "processing",
  "account_id": 10014,
  "amount": 500000,
  "fee_amount": 200,
  "end_to_end_id": "E3783905920260402101500000001",
  "entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
  "transaction_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "external_id": "payment-456",
  "pix_key": "destinataire@email.com",
  "pix_key_type": "EMAIL",
  "description": "Paiement fournisseur",
  "initiated_at": "2026-04-02T10:14:59Z",
  "recipient": {
    "name": "EMPRESA DESTINO LTDA",
    "document": "12345678000199",
    "ispb": "60701190",
    "account": "12345678",
    "agency": "0001",
    "institution_name": "Itau Unibanco S.A."
  },
  "sender": {
    "name": "MINHA EMPRESA LTDA",
    "document": "98765432000100",
    "ispb": "37839059",
    "account": "00001234",
    "agency": "0001"
  }
}
ChampTypeDescription
event_typestringToujours pix.payout.processing
statusstringToujours processing -- solde reserve, peut etre annule
amountintegerMontant en subcentavos
fee_amountintegerFrais en subcentavos (meme frais qui apparaitra dans confirmed/failed plus tard -- il est calcule a la creation du cash-out, pas apres)
end_to_end_idstringIdentifiant E2E du BACEN
transaction_idstring (UUID)Identifiant unique de la transaction
external_idstring ou nullVotre identifiant externe
pix_keystringCle PIX du destinataire
pix_key_typestringType de cle : CPF, CNPJ, EMAIL, PHONE, EVP
descriptionstring ou nullDescription fournie par l'expediteur
initiated_atstring (ISO 8601)Horodatage du cash-out original
recipientobjectDonnees bancaires du destinataire (resolues via DICT)
recipient.namestring ou nullNom du titulaire du compte destination
recipient.documentstring ou nullCPF/CNPJ du destinataire (chiffres uniquement)
recipient.ispbstring ou nullISPB de l'institution destination
recipient.accountstring ou nullNumero du compte destination
recipient.agencystring ou nullAgence du compte destination
recipient.institution_namestring ou nullNom de l'institution destination
senderobjectDonnees bancaires du compte expediteur (votre compte Owem)
sender.namestring ou nullNom du titulaire du compte expediteur
sender.documentstring ou nullCPF/CNPJ de l'expediteur (chiffres uniquement)
sender.ispbstring ou nullISPB d'Owem Pay (37839059)
sender.accountstring ou nullNumero du compte expediteur
sender.agencystring ou nullAgence du compte expediteur

Ordre des evenements

Un pix.payout.processing est toujours suivi (quelques secondes a quelques minutes plus tard) par un pix.payout.confirmed ou pix.payout.failed. Sur des transactions rapides (settlement immediat), le processing peut etre omis et vous recevez directement le terminal.


pix.payout.failed

Envoye quand un PIX envoye est rejete. Hold libere, solde restaure.

Mis a jour le 10/04/2026

Le payload inclut desormais les champs structures reason_code (code BACEN SPI) et reason_description (description en anglais). Les nouvelles integrations doivent utiliser ces champs pour le routage programmatique des echecs. Le champ legacy reason (texte libre) continue d'etre envoye pour assurer la compatibilite avec les integrations anciennes.

json
{
  "event_type": "pix.payout.failed",
  "status": "rejected",
  "account_id": 10014,
  "amount": 500000,
  "fee_amount": 200,
  "end_to_end_id": "E3783905920260402101500000001",
  "entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
  "transaction_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "external_id": "payment-456",
  "pix_key": "destinataire@email.com",
  "pix_key_type": "EMAIL",
  "description": "Paiement fournisseur",
  "initiated_at": "2026-04-02T10:14:59Z",
  "reason_code": "AC03",
  "reason_description": "Invalid creditor account number",
  "reason": "Compte destinataire introuvable",
  "recipient": {
    "name": "EMPRESA DESTINO LTDA",
    "document": "12345678000199",
    "ispb": "60701190",
    "account": "12345678",
    "agency": "0001",
    "institution_name": "Itau Unibanco S.A."
  },
  "sender": {
    "name": "MINHA EMPRESA LTDA",
    "document": "98765432000100",
    "ispb": "37839059",
    "account": "00001234",
    "agency": "0001"
  }
}
ChampTypeDescription
event_typestringToujours pix.payout.failed
statusstringToujours rejected -- hold libere, solde restaure
amountintegerMontant en subcentavos
fee_amountintegerFrais en subcentavos. Les frais affiches correspondent au montant qui aurait ete debite -- dans le ledger TB le pending transfer est automatiquement annule, donc en pratique aucun frais n'est debite pour les transactions rejetees
end_to_end_idstringIdentifiant E2E du BACEN
transaction_idstring (UUID)Identifiant unique de la transaction
external_idstring ou nullVotre identifiant externe
pix_keystringCle PIX du destinataire
pix_key_typestringType de cle : CPF, CNPJ, EMAIL, PHONE, EVP
descriptionstring ou nullDescription fournie par l'expediteur
initiated_atstring (ISO 8601)Horodatage du cash-out original
reason_codestringCode BACEN SPI structure (2-6 caracteres). Exemples : AC03, ED05, AM02, BE01, MD06, FOCR. Utilisez ce champ pour le routage programmatique
reason_descriptionstringDescription en anglais du reason_code. Exemple : "Invalid creditor account number"
reasonstring[Legacy] Description libre du motif. Conserve pour assurer la compatibilite ; les nouvelles integrations doivent utiliser reason_code + reason_description
recipientobjectDonnees bancaires du destinataire (resolues via DICT)
recipient.namestring ou nullNom du titulaire du compte destination
recipient.documentstring ou nullCPF/CNPJ du destinataire (chiffres uniquement)
recipient.ispbstring ou nullISPB de l'institution destination
recipient.accountstring ou nullNumero du compte destination
recipient.agencystring ou nullAgence du compte destination
recipient.institution_namestring ou nullNom de l'institution destination
senderobjectDonnees bancaires du compte expediteur (votre compte Owem)
sender.namestring ou nullNom du titulaire du compte expediteur
sender.documentstring ou nullCPF/CNPJ de l'expediteur (chiffres uniquement)
sender.ispbstring ou nullISPB d'Owem Pay (37839059)
sender.accountstring ou nullNumero du compte expediteur
sender.agencystring ou nullAgence du compte expediteur

Codes reason_code les plus courants (BACEN SPI)

CodeSignification en anglaisAction recommandee
AC03Invalid creditor account numberVerifier les donnees bancaires du destinataire avec le client final
AC06Creditor account blockedCompte destination bloque -- ne pas retenter
AM02Not allowed amount (limit exceeded)Le montant depasse la limite PIX du destinataire ou de l'expediteur
AM04Insufficient fundsSolde insuffisant a l'origine
BE01End customer not in whitelistIdentifiant du destinataire non reconnu
ED05Settlement failedEchec du settlement -- retentative possible apres investigation
MD06Refund requested by end customerRemboursement demande par le client final
FOCRForbidden credit returnRetour de credit interdit

Liste complete : consultez le Catalogo de Mensagens do SPI du BACEN.


pix.payout.returned

Envoye quand un PIX que vous avez envoye est retourne par la banque destinataire apres settlement. Rare, mais peut survenir plusieurs jours plus tard. Le solde du merchant augmente (credit entrant).

Distinction de nomenclature

Trois flux differents peuvent etre confondus :

  • pix.return.received : un PIX que vous avez recu est retourne au payeur original. Solde DIMINUE.
  • pix.payout.returned (celui-ci) : un PIX que vous avez envoye vous revient. Solde AUGMENTE.
  • pix.refund.requested : blocage preventif MED sur un PIX que vous avez recu. Fonds geles.
json
{
  "event_type": "pix.payout.returned",
  "status": "settled",
  "account_id": 10014,
  "amount": 500000,
  "entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
  "return_e2e_id": "D3783905920260410111500000001",
  "end_to_end_id": "E3783905920260402101500000001",
  "original_transaction_id": "PIXOUTa1b2c3d4e5f67890abcdef1234567890",
  "external_id": "payment-456",
  "return_reason": "MD06",
  "return_reason_description": "Refund requested by end customer",
  "counterparty_ispb": "60701190",
  "counterparty_name": "EMPRESA DESTINO LTDA",
  "paid_at": "2026-04-10T11:15:00Z"
}
ChampTypeDescription
event_typestringToujours pix.payout.returned
statusstringToujours settled -- retour regle et credite sur votre compte
amountintegerMontant retourne en subcentavos (peut etre inferieur a l'original pour les retours partiels)
return_e2e_idstringE2E du retour (prefixe D)
end_to_end_idstringE2E de la transaction PIX OUT originale (prefixe E)
original_transaction_idstringtransaction_id du PIX OUT original. Utilisez-le pour la correlation avec votre systeme
external_idstring ou nullVotre identifiant externe de la transaction originale (si applicable)
return_reasonstringCode BACEN du retour : MD06, BE08, FR01, SL02
return_reason_descriptionstringDescription en anglais du return_reason
counterparty_ispbstringISPB de l'institution ayant initie le retour
counterparty_namestringNom de la contrepartie (institution destinataire du PIX original)
paid_atstring (ISO 8601)Horodatage du settlement du retour (UTC)

Les frais ne sont pas rembourses

Les frais du cash-out original ne sont pas rembourses sur pix.payout.returned. Les frais ont ete debites pour l'envoi reussi, qui a bien eu lieu. Si la regle metier exige un remboursement des frais au client final, le merchant doit le gerer separement.


pix.refund.completed

Envoye quand un remboursement PIX est traite et complete.

json
{
  "event_type": "pix.refund.completed",
  "status": "settled",
  "account_id": 10014,
  "amount": 300000,
  "entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
  "original_end_to_end_id": "E9040088820260402095758709999671",
  "return_code": "MD06"
}

pix.return.received

Envoye quand un retour PIX est recu. Cet evenement est genere quand un PIX que vous avez precedemment recu (cash-in) est retourne au payeur original. Le solde du merchant diminue.

Distinction de nomenclature

  • pix.return.received (celui-ci) : un PIX que vous avez recu est retourne au payeur original. Solde DIMINUE.
  • pix.payout.returned : un PIX que vous avez envoye vous revient. Solde AUGMENTE.

Les noms sont inverses par rapport au sens commun -- faites attention.

json
{
  "event_type": "pix.return.received",
  "status": "settled",
  "account_id": 10014,
  "amount": 300000,
  "entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
  "return_e2e_id": "D9040088820260402111500000001",
  "end_to_end_id": "E9040088820260402095758709999671",
  "original_transaction_id": "PIXINE9040088820260402095758709999671",
  "external_id": null,
  "return_reason": "MD06",
  "return_reason_description": "Refund requested by end customer",
  "counterparty_ispb": "60701190",
  "counterparty_name": "EMPRESA X LTDA",
  "paid_at": "2026-04-02T11:15:00Z"
}
ChampTypeDescription
event_typestringToujours pix.return.received
statusstringToujours settled -- retour regle
amountintegerMontant retourne en subcentavos
return_e2e_idstringE2E du retour (prefixe D)
end_to_end_idstringE2E de la transaction PIX IN originale (prefixe E)
original_transaction_idstringtransaction_id du PIX IN original. Utilisez-le pour la correlation avec votre systeme
external_idstring ou nullVotre identifiant externe de la transaction originale (si applicable)
return_reasonstringCode BACEN du retour : MD06, BE08, FR01, SL02
return_reason_descriptionstringDescription en anglais du return_reason
counterparty_ispbstringISPB de l'institution qui recoit le retour
counterparty_namestringNom de la contrepartie (payeur original du PIX IN)
paid_atstring (ISO 8601)Horodatage du settlement du retour (UTC)

Deduplication

Pour dedupliquer les retries de webhook, utilisez le header X-Owem-Event-Id OU la combinaison (return_e2e_id, end_to_end_id). Le return_e2e_id commence par D (retour) et le end_to_end_id commence par E (original).


webhook.test

Evenement de test declenche manuellement pour valider la configuration du webhook.

json
{
  "event_type": "webhook.test",
  "status": "test",
  "account_id": 10014,
  "entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7",
  "message": "Webhook test event"
}

pix.payout.queued

Déclenché quand un PIX OUT est automatiquement placé en file de retry (feature du retry queue pix_out_retry_queue_enabled, disponible depuis la session 155). Motifs : rate limit du ClientLimiter par merchant ou épuisement du bucket DICT BACEN partagé.

Déclenché par pix.ex:315 (module Fluxiq.UseCases.Payments.OutboundPayment.Pix).

json
{
  "event_type": "pix.payout.queued",
  "status": "queued",
  "account_id": 10011,
  "merchant_id": "1b2db911-972f-4466-9be9-60a7c5450064",
  "transaction_id": "PIXOUT0200806193e0984f830569",
  "end_to_end_id": "E3783905920260421133012abcdef1234",
  "amount": 200,
  "external_id": "payment-456",
  "reason": "dict_client_rate_limited",
  "reason_code": "DICT_CLIENT_RATE_LIMITED",
  "reason_description": "Merchant exceeded per-minute DICT lookup quota",
  "queued_at": "2026-04-21T13:30:12Z",
  "estimated_retry_seconds": 3,
  "queue_ttl_seconds": 7200
}
ChampTypeDescription
event_typestringToujours pix.payout.queued
statusstringToujours queued
account_idintegerCompte ayant initié le PIX OUT
merchant_idstring (UUID)Votre merchant_id
transaction_idstringIdentifiant de la transaction Owem
end_to_end_idstringE2E BACEN généré pour le PIX OUT
amountintegerValeur en subcentavos
external_idstring ou nullVotre identifiant externe (si envoyé dans le request original)
reasonstringMotif de la mise en file (snake_case). Valeurs connues : dict_client_rate_limited (limite par merchant), dict_bucket_exhausted (bucket DICT BACEN partagé épuisé), dict_rate_limited (fallback générique)
reason_codestringCode interne en UPPERCASE correspondant au reason. Valeurs : DICT_CLIENT_RATE_LIMITED, DICT_BUCKET_EXHAUSTED, DICT_RATE_LIMITED. Ce n'est pas un code BACEN SPI (comme AC03, AM02) — la mise en file se produit avant l'envoi au BACEN, donc les codes sont internes à Owem
reason_descriptionstringDescription en anglais du motif
queued_atstring (ISO 8601)Moment où la requête est entrée dans la file (UTC)
estimated_retry_secondsintegerIntervalle de retry du worker (3 s par défaut) ; la file ne garantit pas 3 s — peut prendre plus de temps si le bucket tarde à se libérer
queue_ttl_secondsintegerTTL maximum dans la file en secondes (7200 = 2 h). Après expiration, la requête passe en failed avec motif queue_ttl_expired

reason_code ici n'est pas BACEN SPI

Notez que dans pix.payout.queued le reason_code est un code interne Owem en UPPERCASE (DICT_CLIENT_RATE_LIMITED, etc.). Dans pix.payout.failed le reason_code est un code BACEN SPI (ex. : AC03, AM02, ED05). Les deux champs ont le même nom mais des vocabulaires différents — traitez chaque événement séparément dans votre consommateur.

Drainage automatique

Les requêtes en file sont relancées automatiquement par le worker toutes les ~3s tant que le TTL reste valide. Dans des conditions normales, le traitement reprend dès que la limite par merchant ou le bucket DICT BACEN libère de la capacité, mais ce n'est pas un SLA de 3–10 min. Prochain événement : pix.payout.processing (quand elle sort de la file et est envoyée au BACEN). Si le TTL de 2 h expire sans succès, vous recevez pix.payout.failed avec reason="queue_ttl_expired".


pix.infraction.created

Déclenché quand une infraction PIX est signalée par la contrepartie (via BACEN DICT). Exige une défense avant defense_deadline OU blocage conservatoire automatique (MED).

Déclenché par pix_compliance.ex:463 (fonction upsert_infraction quand is_new=true).

json
{
  "event_type": "pix.infraction.created",
  "infraction_id": "e7f4d23a-6f2a-4d1e-a3e6-fe8b32bba95d",
  "e2e_id": "E0416201020260404113012abcdef1234",
  "status": "ACKNOWLEDGED",
  "infraction_type": "REFUND_REQUEST",
  "amount": 1500000,
  "analysis_result": null,
  "analysis_details": null,
  "defense_deadline": "2026-04-21T23:59:59Z",
  "counterpart_ispb": "60701190",
  "account_id": 10011,
  "merchant_id": "1b2db911-972f-4466-9be9-60a7c5450064",
  "entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7"
}
ChampTypeDescription
event_typestringToujours pix.infraction.created
infraction_idstring (UUID)ID interne de l'infraction
e2e_idstringE2E de la transaction contestée
statusstringStatus BACEN : ACKNOWLEDGED, CLOSED, CANCELLED
infraction_typestringType BACEN : REFUND_REQUEST, REFUND_CANCELLED, FRAUD
amountintegerValeur en subcentavos
defense_deadlinestring (ISO 8601)Délai pour soumission de défense
counterpart_ispbstring (8 chiffres)ISPB de l'institution contrepartie
account_idintegerVotre compte affecté
merchant_idstring (UUID)Votre merchant_id

Action obligatoire

Les infractions avec status ACKNOWLEDGED et valeur > R$ 1 000 génèrent un blocage conservatoire automatique (MED). Vous devez répondre via POST /api/merchant/infractions/{id}/defense avant le defense_deadline sinon le remboursement sera exécuté.


pix.infraction.resolved

Déclenché quand une infraction est résolue (admin close ou auto-deny). Libère le blocage conservatoire s'il y en a un.

Déclenché par pix_compliance.ex:664 et admin/infractions/resolve_controller.ex:84.

json
{
  "event_type": "pix.infraction.resolved",
  "infraction_id": "e7f4d23a-6f2a-4d1e-a3e6-fe8b32bba95d",
  "e2e_id": "E0416201020260404113012abcdef1234",
  "status": "CLOSED",
  "infraction_type": "REFUND_REQUEST",
  "amount": 1500000,
  "analysis_result": "DISAGREED",
  "analysis_details": "Verificado pelo time de compliance e sem evidencias concretas nao temos como fazer devolucao",
  "defense_deadline": "2026-04-21T23:59:59Z",
  "counterpart_ispb": "60701190",
  "account_id": 10011,
  "merchant_id": "1b2db911-972f-4466-9be9-60a7c5450064",
  "entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7"
}
ChampTypeDescription
analysis_resultstringAGREED (rembourse), DISAGREED (refuse)
analysis_detailsstringJustification de la décision
Autres champsIdentiques à pix.infraction.created

pix.infraction.defense_submitted

Déclenché quand le merchant soumet une défense contre une infraction (via portail ou API).

Déclenché par admin/infractions/defense_controller.ex:67 et merchant/infractions/defense_controller.ex:178.

json
{
  "event_type": "pix.infraction.defense_submitted",
  "infraction_id": "e7f4d23a-6f2a-4d1e-a3e6-fe8b32bba95d",
  "e2e_id": "E0416201020260404113012abcdef1234",
  "status": "defense_submitted",
  "account_id": 10011,
  "merchant_id": "1b2db911-972f-4466-9be9-60a7c5450064",
  "entity_id": "26a48541-edce-4581-8c6e-564e7f2e6cd7"
}
ChampTypeDescription
event_typestringToujours pix.infraction.defense_submitted
statusstringToujours defense_submitted
infraction_idstring (UUID)ID de l'infraction en cours de défense

Attend l'analyse BACEN

Après soumission, BACEN analyse la défense + preuves de la contrepartie. Résultat via pix.infraction.resolved.


Comment interpréter les webhooks

Pour confirmer que l'argent est arrivé : Attendez pix.charge.paid avec status: "paid". C'est le seul événement qui garantit que le montant a été crédité et les frais débités.

Pour confirmer que l'argent a été envoyé : Attendez pix.payout.confirmed avec status: "settled". Le statut processing est intermédiaire — le solde est réservé mais peut être annulé si rejeté.

Pour les retours : pix.return.received avec status: "settled" confirme le crédit réglé sur le compte.

Déduplication : Utilisez l'en-tête X-Owem-Event-Id ou le champ end_to_end_id comme clé d'idempotence.

Owem Pay Instituição de Pagamento — ISPB 37839059