Por qué dos pasos
Dividir un cash-out en iniciar y procesar te da un punto de control entre “¿quién es el receptor?” y “envía el dinero”:
- Verifica primero el destino. Iniciar valida y resuelve la cuenta del receptor sin tocar saldos. Una clave Pix equivocada o una cuenta inválida falla aquí, antes de que se mueva dinero.
- Muestra al pagador quién recibe el dinero. La respuesta de iniciación devuelve el titular de la cuenta resuelta. Tu app puede mostrar el nombre real y dejar que el pagador confirme primero.
- Mueve los fondos solo con la confirmación. El plugin no debita nada hasta que procesas la transferencia. Si el pagador abandona el flujo, no hay movimiento que deshacer.
Ambos pasos aceptan una clave
X-Idempotency. Reintenta con la misma clave para evitar transferencias duplicadas. Consulta Reintentos e idempotencia.Paso 1: Iniciar (confirmar el destino)
Iniciar una transferencia crea un registro de vida corta que valida y resuelve al receptor sin mover fondos. Cómo encuentra el plugin el destino depende de con qué empiezas:
Para
KEY y QR_CODE, nunca proporcionas el destino tú mismo. El plugin lo resuelve y lo devuelve en la respuesta, listo para mostrárselo al pagador y que lo confirme.
Solicitud: elige la pestaña de tu tipo de iniciación
type de cuenta son CACC (corriente), SVGS (ahorro), TRAN (transaccional) y OTHR (otra). endToEndId es opcional para todos los tipos. El plugin genera uno cuando lo omites.
Respuesta
La respuesta devuelve elid de la iniciación (usado como initiationId en el paso 2) y el destination resuelto:
Las iniciaciones expiran. La respuesta incluye un timestamp
expiresAt. Procesa la transferencia antes de que venza, o inicia otra. Esto evita que un destino confirmado quede obsoleto entre la consulta y el pago.Paso 2: Procesar (mover el dinero)
Procesar ejecuta el cash-out a partir de la iniciación que confirmaste. Debita la cuenta de origen y luego enruta el pago a BTG para su liquidación con BACEN. La liquidación con la red Pix es asíncrona. La transferencia vuelve como
PROCESSING mientras BTG liquida. El resultado final (por ejemplo COMPLETED o REJECTED) llega después mediante un webhook TRANSFER / CASHOUT. Diseña tu flujo para reaccionar a ese evento, no para esperar la respuesta del procesamiento. Consulta Webhooks.
Solicitud
Pasa elid de la respuesta de iniciación como initiationId, junto con el amount a transferir:
amount es obligatorio. También puedes pasar un description opcional (máx. 140 caracteres) y metadata (atributos clave-valor personalizados).
El header X-Purpose
Usa el header X-Purpose opcional para declarar el motivo del cash-out. Cuando se omite, toma TRANSFER como valor predeterminado:
Códigos QR de monto fijo: la iniciación puede ser un
QR_CODE cuyo payload EMV lleva un monto fijo. En ese caso, el amount que envías a procesar debe ser igual a ese monto codificado. Una discrepancia se rechaza antes de que se mueva ningún fondo.Respuesta
Cuando el destino pertenece a tu propia institución, el dinero nunca sale hacia BTG. Se liquida internamente como una transferencia P2P. Consulta Transferencias intra-PSP.
Seguimiento de una transferencia
Una transferencia empieza en
CREATED y pasa por PENDING/PROCESSING mientras está en tránsito. Luego llega a un COMPLETED, FAILED, CANCELLED o REJECTED terminal. Para ver en qué punto está una transferencia, consulta una sola por su id. También puedes listar transferencias filtradas por estado, tipo (cash-out o cash-in) o rango de fechas.
status, type (CASHOUT/CASHIN), end_to_end y modified_after/modified_before, además de la paginación con page/limit/sort_order.
Pagos programados
Un pago programado ejecuta un cash-out Pix en una fecha y hora futuras. Primero, inicia la transferencia como en el paso 1. Luego, pasa el
id de la iniciación como initiationId a POST /v1/schedules, con el amount y la fecha y hora scheduledFor:
scheduledFor debe estar al menos SCHEDULE_MIN_FUTURE_SECONDS en el futuro y como máximo SCHEDULE_MAX_FUTURE_DAYS días adelante. También puedes pasar una description opcional (hasta 140 caracteres) y maxAttempts (1 o 2). Si omites maxAttempts, el plugin usa SCHEDULE_MAX_ATTEMPTS.
Una programación empieza en SCHEDULED. A la hora programada, el worker de programaciones la pasa a PROCESSING y ejecuta el cash-out. Luego, la programación termina en EXECUTED, FAILED o CANCELLED. Para cancelar una programación, envía DELETE /v1/schedules/{schedule_id} mientras está en SCHEDULED. El plugin envía un webhook SCHEDULE / CASHOUT con el tipo de evento schedule.executed, schedule.failed o schedule.cancelled.
Pix Automático (pagador)
Pix Automático permite que un receptor debite la cuenta del pagador según un calendario, después de que el pagador lo autoriza. El plugin maneja el lado del pagador. Las llamadas reciben la cuenta del pagador en el header
X-Account-Id. En el listado de autorizaciones, el header es opcional. Sin él, el listado cubre todas las cuentas.
Cuando aceptas una solicitud, la solicitud pasa a
APPROVING. La autorización empieza cuando BTG la aprueba. Cuando el plugin acepta un cobro del receptor, crea un pago programado para ese cobro. El plugin envía webhooks RECURRING para las entidades AUTHORIZATION_REQUEST, AUTHORIZATION y CHARGE. Consulta Webhooks.
Cómo llegan las transferencias a Midaz
El plugin registra cada movimiento liquidado en Midaz como una transacción del ledger, con el tramo externo contra la cuenta
@external/BRL. Midaz guarda el asiento y los metadatos de correlación, no los datos bancarios completos de la transferencia. La agencia, el número de cuenta, el tipo de cuenta y la clave Pix de la contraparte nunca llegan a Midaz. La única excepción es la identidad del pagador en el cash-in (sourceBank, sourceDocument, sourceName), estampada cuando se conoce. El detalle completo de la contraparte vive en el registro de transferencia del plugin.
Los metadatos estampados en la transacción de Midaz dependen del flujo:
El
code de la transacción de Midaz también lleva el endToEndId (o el returnIdentification en las devoluciones), por lo que el identificador E2E se ve directamente en el asiento del ledger.
La correlación funciona en ambos sentidos:
- El plugin guarda los identificadores de transacción y de operación de Midaz en sus propios registros de transferencia y de devolución, y los usa para confirmar, cancelar o revertir asientos del ledger.
- La transacción de Midaz lleva claves de correlación en sus metadatos: filtra por
metadata.endToEndIdpara los cash-outs y los cash-ins, o pormetadata.originalEndToEndId/metadata.returnIdentificationpara las devoluciones. Elcodede la transacción es el respaldo común. Lleva el ID E2E en las transferencias y la identificación de devolución en las devoluciones.
Los
metadata personalizados que pasas al procesar un cash-out se guardan con el registro de transferencia del plugin y los devuelve la propia API del plugin. No se copian a la transacción de Midaz. El plugin fija las claves de metadatos de Midaz indicadas arriba.Verificación de fraude en Pix entrante
El plugin puede consultar un endpoint de decisión que tú operas antes de aceptar un Pix entrante o una devolución entrante. La verificación está desactivada de forma predeterminada. Para activarla, define
ANTIFRAUD_HOOK_ENABLED=true y las demás variables de la verificación de fraude.
El plugin envía una solicitud POST con un cuerpo JSON a ANTIFRAUD_HOOK_URL:
contractVersion:1.0.eventType:PIX_CASHINpara un Pix entrante, oPIX_REFUND_CASHINpara una devolución entrante.approvalId: un UUID que identifica la verificación.requestedAtyrespondBy: marcas de tiempo en UTC.respondByesrequestedAtmásANTIFRAUD_HOOK_TIMEOUT_MS.cashin, enPIX_CASHIN:amount,endToEndId,transactionIdentification,transactionType,paymentType,initiationType,urgency,remittanceInformation,movementIds,debitParty,creditPartyyaccount. Cada parte tienename,taxId,personType,bank,branch,account,accountTypeykey.cashin.accounttieneaccountId,aliasId,holderIdydocument.refundCashin, enPIX_REFUND_CASHIN:returnIdentification,originalEndToEndId,amount,reason,additionalInformationyoriginalTransaction.originalTransactiontieneendToEndId,amount,createdAtycreditPartyconname,taxId,bank,branchyaccount.metadata: un objeto vacío.
transactionIdentification, remittanceInformation, key, aliasId, holderId y additionalInformation cuando están vacíos.
Cada solicitud trae estos headers:
X-Webhook-Timestamp: la hora Unix, en segundos, en que el plugin firmó la solicitud.X-Webhook-Signature:v1,sha256=<hex>.<hex>es el HMAC-SHA256 dev1:<timestamp>.<raw body>conANTIFRAUD_HOOK_HMAC_SECRETcomo clave.<timestamp>es el valor deX-Webhook-Timestamp.Idempotency-Key: elapprovalId.
X-Webhook-Signature.
Responde con un estado 2xx y un objeto JSON con decision y un reason opcional. El plugin registra reason como antifraudReason. Lee decision sin distinguir mayúsculas de minúsculas:
APPROVEoALLOWacepta el Pix.REJECT,DENYoREVIEWrechaza el Pix ante BTG con el código de motivoFRAD.
2xx, una respuesta que no puede leer o un circuit breaker abierto. También ocurre cuando un Pix entrante no trae datos del pagador.
El plugin no hace la verificación en créditos y devoluciones intra-PSP, ni en créditos de devolución MED (INSTANT_PAYMENT_REFUND y REFUND_AUTOMATIC_PIX).
Un Pix rechazado no crea un cash-in ni una devolución. El plugin registra cada decisión en el webhook entrante almacenado. Consultar un webhook entrante la devuelve en payload.metadata: antifraudDecision, antifraudSource, antifraudReason y antifraudLatencyMs. También devuelve antifraudRawDecision cuando tu endpoint respondió, o antifraudPolicy cuando decidió el fallback.
Cuando una transferencia se atasca
Si la llamada de liquidación a BTG agota el timeout antes de que BTG confirme, una transferencia puede quedarse en
PROCESSING con sus fondos retenidos. El plugin provee una operación de desbloqueo. El desbloqueo vuelve a verificar la transferencia con BTG y la lleva al estado final correcto. Liquida la transferencia si BTG confirma, o libera la retención si BTG nunca la recibió.
El desbloqueo no aplica a las transferencias intra-PSP. No hay transacción en BTG que volver a verificar. Para el comportamiento completo del desbloqueo y sus opciones, consulta Operaciones de devolución.
Próximos pasos
- Transferencias intra-PSP: Liquidación P2P interna
- Códigos QR: Generar y decodificar códigos QR
- Operaciones de devolución: Devoluciones y desbloqueo
- Webhooks: Manejo de eventos de cash-out y cash-in
- Referencia de API: Detalles completos de solicitud/respuesta, headers y esquemas de campos

