Skip to content
LIQFYdocs
PTENENEN
Go to dashboard

Disputas y MED (contracargo de Pix)

Un pago Pix puede ser disputado después de liquidarse. En Pix, el canal para ello es el MED (Mecanismo Especial de Devolução del BACEN, el Mecanismo Especial de Devolución): el pagador solicita a su propio banco revertir una transacción que alega fue fraude, una estafa o un error. Cuando se abre un MED contra uno de tus cobros, Liqfy abre un caso MED para él, retiene el monto de tu cuenta mientras el caso está en curso y te notifica — por webhook, por correo electrónico y en el dashboard — para que no descubras la pérdida recién a fin de mes.

Esto es distinto de un reembolso, que es una reversión que tú decides emitir. Un MED lo inicia el pagador, del lado de su banco.

Todo lo que aparece en esta página está disponible a través de la API (/v1/med/cases), los SDK oficiales (recurso medCases) y el panel Disputes & MED Cases de tu dashboard. Los tres leen y modifican el mismo caso.

#El ciclo de vida de un vistazo

text
                 charge paid
                      │
        MED opened by the payer's bank
                      │
                      ▼
   med_case "open"  ── amount held from your account,
                      │  charge becomes "disputed", refund blocked
          ┌───────────┴──────────────┐
          ▼                          ▼
   you accept                 you appeal (+ evidence)
          │                          │
          ▼                          ▼
     "accepted"                 "appealed"
   (loss taken)                      │
                         ┌───────────┴───────────┐
                         ▼                       ▼
                    "rejected"               "closed"
                  (MED upheld,          (in your favor, or
                   loss taken)       closed without refund)

Un caso también puede pasar directamente de open a closed — por ejemplo, cuando el pagador retira el reclamo o el fallo resulta a tu favor antes de que respondas. Otras transiciones que no provienen de tu propia acción se describen en Estados del caso.

#Qué ocurre cuando se abre un MED

  1. Se crea un caso MED (med_case, id med_…) vinculado al cobro disputado (charge_id, ch_…). Comienza en open.
  2. Liqfy retiene el monto de tu cuenta. El monto disputado se debita de tu saldo operativo (puede quedar negativo) y se retiene mientras el caso está en curso. Si el caso se cierra a tu favor, se devuelve; si pierdes, ya estaba reservado. Un caso que la plataforma registra manualmente sin impacto financiero no debita nada.
  3. El cobro pasa a disputed. El estado público del cobro (vocabulario de estados) pasa de paid a disputed. Un cobro disputed no puede reembolsarse — un reembolso duplicaría la reversión (tu reembolso + el MED ejecutado por el banco). Si el caso se cierra a tu favor, el cobro vuelve a paid.
  4. Se te notifica, por todos los canales que se indican a continuación.

Reportes repetidos o inconsistentes. Si llega un nuevo reporte para un cobro que ya tiene un caso con el mismo monto (o la misma referencia contable del proveedor), o si, junto con los demás MED del cobro, superaría el monto del cobro, Liqfy lo registra para revisión interna sin mover dinero, y no aparece para ti — ni caso, ni webhook, ni correo. Si la plataforma concluye que se trata de un MED independiente, el caso aparece en ese momento (con med_case.created) y el monto se retiene entonces.

#Cómo se te notifica

CanalQué recibes
Webhook med_case.createdEl objeto med_case completo cuando se abre el caso, incluido response_deadline cuando se conoce el plazo. Normalmente en open; un caso que la plataforma registra ya con pérdida llega en accepted.
Webhook med_case.updatedEl objeto med_case completo en los cambios de estado (appealed, accepted, rejected, closed) y cuando la plataforma te solicita evidencia (evidence_requested_at). No en absolutamente cada escritura: se suprime para los casos que la plataforma registra para gestión manual individual en modo silencioso, y las actualizaciones de resultado (accepted / rejected / closed) no se envían cuando la configuración de avisos de resultado de la plataforma está desactivada o cuando quien decidió el caso optó por no notificarte.
Webhook med.resolvedEl destino final del dinero: refunded_to_merchant, closed_without_refund o lost. El mismo resultado no se envía dos veces para un caso; si el resultado se corrige después (por ejemplo, de refunded_to_merchant a lost), se envía el nuevo resultado.
Correo electrónicoCorreos de "MED abierto" y "MED resuelto" al contacto de tu cuenta. Para un caso registrado sin impacto financiero, "MED abierto" indica que no se debitó ningún monto. No se envía el correo de "MED resuelto" cuando el caso se cierra sin que el monto te sea devuelto (closed_without_refund) — ese resultado te llega a través de med.resolved y de la API.
DashboardPanel Disputes & MED Cases, con el monto, el motivo alegado, cuánto está retenido, a dónde fue el dinero, el E2E de Pix y las acciones descritas abajo. La búsqueda acepta un prefijo del id del caso, del id de la transacción o de la referencia del caso, o un E2E de Pix completo.
APIGET /v1/med/cases y GET /v1/med/cases/{id} — siempre actualizados.

Los payloads y las firmas de los tres eventos están en Webhooks.

No se dispara ningún webhook charge.* por un MED. El cobro fue pagado; un MED no es una falla del cobro ni es un reembolso — charge.failed y charge.refunded no se envían cuando un MED se abre, se gana o se pierde. Suscríbete a med_case.created, med_case.updated y med.resolved. Al volver a leer el cobro (GET /v1/charges/{id}) se ve status: "disputed" mientras el caso está abierto.

Los webhooks son una señal; la API es la fuente de verdad. Las notificaciones de resultado (med.resolved, y med_case.updated para accepted / rejected / closed) pueden no llegar: un evento de caso MED que no se logra publicar no se reintenta. Concilia con GET /v1/med/cases (por ejemplo, una vez al día, filtrando por created_after) y considera definitivos status + money_outcome de la API.

#Estados del caso

statusSignificadoEfecto en el dinero
openEl MED acaba de abrirse. Esperando a que lo aceptes o apeles.Monto retenido.
appealedApelaste (enviaste tu defensa); esperando el resultado.El monto sigue retenido hasta el resultado.
acceptedLa pérdida se aceptó sin apelación — por ti, o registrada por la plataforma.El monto sigue debitado (pérdida asumida).
rejectedLa apelación no prosperó — el MED fue confirmado.El monto sigue debitado (pérdida definitiva).
closedEl caso está cerrado. Lee money_outcome para saber a dónde fue el dinero.Se te devolvió, o no — ver abajo.

Transiciones que no provienen de tu propia acción:

  • open → appealed cuando el proveedor informa que el caso está en revisión. En ese caso, appealed_at se completa, appeal_reason permanece en null, y el caso ya no puede apelarse ni aceptarse a través de la API.
  • open / appealed → accepted cuando el proveedor informa que el reclamo fue aceptado, o cuando la plataforma registra la pérdida; appealed → rejected cuando se pierde la apelación o la plataforma registra la pérdida.
  • closed → accepted cuando la plataforma corrige un caso que se cerró por error: el monto se debita nuevamente, money_outcome pasa a lost y se envía med_case.updated.

money_outcome es null mientras el caso está en open o appealed, y luego te indica el destino final del dinero:

money_outcomeSignificado
refunded_to_merchantEl monto retenido se devolvió a tu saldo (fallo a tu favor o reclamo retirado).
closed_without_refundEl caso se cerró, pero el monto no se devolvió a tu saldo.
lostEl caso terminó en pérdida (accepted o rejected); el monto sigue debitado.

closed por sí solo no significa que ganaste. Lee siempre money_outcome.

Algunos resultados se aplican en cuanto el banco del pagador o el BACEN dicta un fallo sobre el caso; otros tardan más en confirmarse, y el caso mantiene su estado actual (open o appealed) hasta que se confirman. Un resultado favorable informado por el proveedor puede pasar primero por una revisión del equipo de Liqfy — un reclamo retirado siempre pasa por ella — y un fallo desfavorable informado por el proveedor también lo gestiona el equipo antes de que el caso cambie.

#Plazos

response_deadline (ISO 8601, UTC) es el plazo para responder al caso. Se completa cuando el plazo fue informado a Liqfy, y es null en caso contrario. Se envía en med_case.created y lo devuelve toda lectura. Planifica apelar (con tu evidencia) con bastante antelación — el fallo no te espera.

#Tu defensa: apelar, aceptar y evidencia

Mientras un caso está en open, eliges uno de dos caminos:

  • Apelar (POST /v1/med/cases/{id}/appeal) — impugnas el MED con una justificación escrita (reason: al menos 5 caracteres después de quitar los espacios, como máximo 2.000 caracteres sin procesar — el límite de 2.000 se aplica a las llamadas con API key). El caso pasa a appealed.
  • Aceptar (POST /v1/med/cases/{id}/accept) — renuncias a impugnar. El caso pasa a accepted y el monto sigue debitado.

La evidencia (factura, comprobante de entrega, conversaciones con el comprador — todo lo que demuestre que el cobro fue legítimo) se adjunta mediante la carga en tres pasos que se describe abajo. Puedes adjuntar evidencia antes o después de apelar; adjúntala antes del plazo.

Importante — a dónde va tu defensa. Tu apelación, tu aceptación y cada archivo de evidencia cuya carga confirmaste quedan registrados en la plataforma Liqfy de inmediato, y el caso cambia en el acto. También se reenvían al proveedor de pagos del cobro disputado, de forma asíncrona, cuando esa cuenta del proveedor admite recibir una defensa de MED; cuando no, quedan registrados solo en la plataforma Liqfy. Solo se reenvía evidencia en PDF, PNG, JPEG, WEBP o GIF de hasta 10 MB. El reenvío no decide el caso: el fallo oficial llega a Liqfy por el canal MED y se refleja en el caso (status, money_outcome) y en los webhooks anteriores.

#API

Todas las rutas usan tu API key y solo ven tus casos. La ruta canónica es /v1/med/cases; /v1/infractions es un alias que sirve las mismas rutas.

text
Authorization: Bearer lq_live_...

El header de autenticación canónico es Authorization: Bearer <key>. La forma heredada apikey: <key> sigue funcionando por compatibilidad, pero las integraciones nuevas deben usar Authorization: Bearer.

MétodoRutaQué hace
GET/v1/med/casesLista tus casos MED (paginación por cursor).
GET/v1/med/cases/{id}Obtiene un caso.
POST/v1/med/cases/{id}/appealApela un caso open.
POST/v1/med/cases/{id}/acceptAcepta un caso open.
GET/v1/med/cases/{id}/evidenceLista los archivos de evidencia del caso.
POST/v1/med/cases/{id}/evidenceSolicita una URL de carga para un nuevo archivo de evidencia.
POST/v1/med/cases/{id}/evidence/{evidence_id}/completeConfirma la carga de un archivo de evidencia.

El {id} del caso acepta el id med_… (el mismo id sin el prefijo med_ también funciona).

#El objeto med_case

json
{
  "id": "med_3f1c2b9e-0d7a-4a55-9a51-6f0e3c1d2b10",
  "object": "med_case",
  "type": "med",
  "status": "open",
  "amount": 15000,
  "currency": "BRL",
  "charge_id": "ch_6b0f4c1e-2a8d-4c1b-9d0e-1f2a3b4c5d6e",
  "charge_metadata": { "order_id": "PED-10442" },
  "customer_name": "Maria Silva",
  "reason": "Payer reports a scam",
  "response_deadline": "2026-09-30T23:59:59.000Z",
  "evidence_requested_at": null,
  "appeal_reason": null,
  "appealed_at": null,
  "evidence_count": 0,
  "money_outcome": null,
  "opened_at": "2026-09-23T14:02:11.000Z",
  "closed_at": null,
  "created_at": "2026-09-23T14:02:12.000Z",
  "updated_at": "2026-09-23T14:02:12.000Z"
}
CampoDescripción
idId del caso, med_….
objectSiempre med_case.
typemed para un MED de Pix. Otros tipos de disputa (chargeback, dispute, fraud) usan el mismo objeto.
statusopen, appealed, accepted, rejected o closed (estados).
amountMonto disputado, en la unidad menor de la moneda (centavos para BRL).
currencyCódigo ISO 4217, p. ej. BRL.
charge_idEl cobro disputado, ch_….
charge_metadataEl metadata que enviaste al crear el cobro disputado — lee tu propio id de pedido directamente desde el caso (charge_metadata.order_id en el ejemplo anterior), sin un GET /v1/charges/{id} por caso. {} cuando el cobro no tiene metadata; null cuando no se pudo leer en ese momento (en ese caso, usa GET /v1/charges/{charge_id}).
customer_nameEl nombre del cliente que enviaste al crear el cobro, o null.
reasonEl motivo alegado, tal como se muestra en tu dashboard. Puede ser null.
response_deadlinePlazo para responder, o null cuando se desconoce (plazos).
evidence_requested_atCuándo la plataforma te solicitó evidencia, o null.
appeal_reasonLa justificación que enviaste al apelar, o null (también null cuando el caso pasó a appealed por una actualización del proveedor).
appealed_atCuándo el caso pasó a appealed, o null.
evidence_countCantidad de archivos de evidencia cuya carga fue confirmada.
money_outcomerefunded_to_merchant, closed_without_refund, lost, o null mientras no esté decidido.
opened_atCuándo se abrió el MED.
closed_atCuándo el caso llegó a un estado final, o null.
created_at / updated_atMarcas de tiempo del registro (ISO 8601, UTC).

#Listar casos

bash
curl "https://api.liqfy.com.br/v1/med/cases?status=open&limit=25" \
  -H "Authorization: Bearer $LIQFY_API_KEY"
Parámetro de consultaDescripción
limitEntero de 1 a 100. Por defecto, 25.
starting_afterUn id med_…: devuelve los casos posteriores a él (el next_cursor de la página anterior). Debe ser uno de tus casos. Máximo 140 caracteres.
statusopen, appealed, accepted, rejected o closed (no distingue mayúsculas de minúsculas).
typemed, chargeback, dispute o fraud (no distingue mayúsculas de minúsculas). Sin él, se devuelven todos los tipos.
charge_idSolo los casos de este cobro (ch_…). Máximo 140 caracteres.
created_after / created_beforeFechas y horas ISO 8601 (límites exclusivos).
json
{
  "object": "list",
  "data": [
    { "id": "med_3f1c2b9e-0d7a-4a55-9a51-6f0e3c1d2b10", "object": "med_case", "status": "open", "...": "..." }
  ],
  "has_more": true,
  "next_cursor": "med_3f1c2b9e-0d7a-4a55-9a51-6f0e3c1d2b10"
}

Los casos se ordenan del más reciente al más antiguo (created_at descendente). Mientras has_more sea true, pasa next_cursor como starting_after para leer la página siguiente; next_cursor es null en la última página. Un valor desconocido para status, type o limit, una fecha mal formada, un starting_after que no sea uno de tus casos, o un starting_after/charge_id de más de 140 caracteres devuelve 400 — los siete filtros documentados nunca se ignoran en silencio. Los parámetros adicionales q, types y page pertenecen al dashboard y se ignoran en silencio con una API key.

#Obtener un caso

bash
curl "https://api.liqfy.com.br/v1/med/cases/med_3f1c2b9e-0d7a-4a55-9a51-6f0e3c1d2b10" \
  -H "Authorization: Bearer $LIQFY_API_KEY"

Devuelve el objeto med_case, o 404 si el caso no existe en tu cuenta.

#Apelar un caso

bash
curl -X POST "https://api.liqfy.com.br/v1/med/cases/med_3f1c2b9e-0d7a-4a55-9a51-6f0e3c1d2b10/appeal" \
  -H "Authorization: Bearer $LIQFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"reason": "Order #8812 was delivered on 2026-09-20; signed delivery receipt attached."}'

reason es obligatorio: al menos 5 caracteres después de quitar los espacios, como máximo 2.000 caracteres sin procesar (el límite de 2.000 se aplica con un 400 solo en las llamadas con API key; en el dashboard, un texto más largo se recorta a los primeros 2.000 caracteres). Devuelve 200 con el caso actualizado (status: "appealed", appeal_reason y appealed_at completados). Solo un caso open puede apelarse: cualquier otro estado devuelve 400. Un caso abierto para gestión manual individual también devuelve 400 aunque siga en open — esos casos los decide directamente la plataforma y no admiten defensa. Un caso que no existe en tu cuenta devuelve 404.

#Aceptar un caso

bash
curl -X POST "https://api.liqfy.com.br/v1/med/cases/med_3f1c2b9e-0d7a-4a55-9a51-6f0e3c1d2b10/accept" \
  -H "Authorization: Bearer $LIQFY_API_KEY"

Sin body. Devuelve 200 con el caso actualizado (status: "accepted", money_outcome: "lost"). Solo un caso open puede aceptarse: cualquier otro estado devuelve 400 — y, al igual que con la apelación, un caso en gestión manual individual devuelve 400 incluso estando en open. Un caso que no existe en tu cuenta devuelve 404. Aceptar es definitivo.

#Cargar evidencia

Los archivos van directamente al almacenamiento mediante una URL firmada de corta duración; nunca pasan por el body de la API. Límites: 10 MB por archivo; tipos image/png, image/jpeg, image/jpg, image/webp, image/gif y application/pdf.

Paso 1 — solicita una URL de carga. Declara el nombre del archivo, su tamaño exacto en bytes (un número JSON) y su tipo. También se aceptan las formas camelCase fileName, fileSize y mimeType:

bash
curl -X POST "https://api.liqfy.com.br/v1/med/cases/med_3f1c2b9e-0d7a-4a55-9a51-6f0e3c1d2b10/evidence" \
  -H "Authorization: Bearer $LIQFY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"file_name": "delivery-receipt.pdf", "file_size": 52341, "mime_type": "application/pdf"}'

201 Created:

json
{
  "id": "0b8e6f52-7c3d-4e1a-9f40-2d6c8a1b5e77",
  "object": "med_case_evidence_upload",
  "upload_url": "https://storage.example.com/…?X-Amz-Signature=…",
  "upload_method": "PUT",
  "upload_headers": { "Content-Type": "application/pdf", "Content-Length": "52341" },
  "expires_in": 900
}

Paso 2 — haz PUT del archivo a upload_url dentro de expires_in segundos (15 minutos), con exactamente los headers de upload_headers. La firma vincula el tipo y el tamaño, por lo que el almacenamiento rechaza un Content-Type distinto o un archivo de otro tamaño. No envíes tu API key (ni ningún header Authorization) a esta URL — la propia URL es la credencial.

bash
curl -X PUT "$UPLOAD_URL" \
  -H "Content-Type: application/pdf" \
  --data-binary @delivery-receipt.pdf

(curl --data-binary envía el Content-Length del archivo por ti; debe coincidir con file_size del paso 1.)

Paso 3 — confirma la carga. Liqfy verifica que el archivo realmente llegó y marca la evidencia como cargada:

bash
curl -X POST "https://api.liqfy.com.br/v1/med/cases/med_3f1c2b9e-0d7a-4a55-9a51-6f0e3c1d2b10/evidence/0b8e6f52-7c3d-4e1a-9f40-2d6c8a1b5e77/complete" \
  -H "Authorization: Bearer $LIQFY_API_KEY"

200 OK con el objeto de evidencia:

json
{
  "id": "0b8e6f52-7c3d-4e1a-9f40-2d6c8a1b5e77",
  "object": "med_case_evidence",
  "file_name": "delivery-receipt.pdf",
  "file_size": 52341,
  "mime_type": "application/pdf",
  "uploaded_by": "merchant",
  "created_at": "2026-09-23T15:10:02.000Z",
  "uploaded_at": "2026-09-23T15:10:09.000Z",
  "view_url": "https://storage.example.com/…?X-Amz-Signature=…"
}

complete es idempotente: llamarlo de nuevo para un archivo confirmado devuelve la misma evidencia. Es la única ruta idempotente de esta superficie — las demás no aceptan Idempotency-Key y no se deduplican. Si el PUT aún no se realizó (o la URL expiró), devuelve 409 con error.code EVIDENCE_NOT_UPLOADED — solicita una nueva URL (paso 1) y vuelve a cargar el archivo. La evidencia que nunca se confirmó no existe para la API: no se lista, no cuenta en evidence_count y no se reenvía al proveedor.

Los SDK oficiales realizan los tres pasos en una sola llamada — consulta SDKs.

#Listar evidencia

bash
curl "https://api.liqfy.com.br/v1/med/cases/med_3f1c2b9e-0d7a-4a55-9a51-6f0e3c1d2b10/evidence" \
  -H "Authorization: Bearer $LIQFY_API_KEY"
json
{
  "object": "list",
  "data": [
    { "id": "0b8e6f52-7c3d-4e1a-9f40-2d6c8a1b5e77", "object": "med_case_evidence", "file_name": "delivery-receipt.pdf", "...": "..." }
  ]
}

Solo se devuelve la evidencia confirmada, de la más reciente a la más antigua. uploaded_by es merchant (tú), partner o platform (el equipo de Liqfy). view_url es un enlace de descarga firmado válido por 5 minutos — vuelve a obtener la lista para conseguir uno nuevo. Es nullable: null cuando el almacenamiento de documentos está desactivado para la cuenta.

#Errores

Los errores usan el formato de error estándar: un objeto error (type, code, message, y param / details cuando corresponda) más request_id, que también se envía en el header X-Request-Id. Los específicos de los casos MED:

HTTPerror.codeCuándo
400invalid_requestFiltro inválido (status, type, limit, fecha), starting_after que no es uno de tus casos, starting_after/charge_id de más de 140 caracteres, reason de menos de 5 o más de 2.000 caracteres, file_name / file_size / mime_type ausente o inválido, archivo de más de 10 MB o de un tipo no aceptado, o apelación/aceptación de un caso que no está en open (o que está en gestión manual individual).
404not_foundEl caso (o la evidencia) no existe en tu cuenta.
409EVIDENCE_NOT_UPLOADEDcomplete llamado antes de que el archivo llegara al almacenamiento (o después de que la URL expirara).
409EVIDENCE_SIZE_MISMATCHEl tamaño del archivo almacenado difiere del file_size declarado.
503service_unavailableEl almacenamiento de documentos no está disponible temporalmente; la carga de evidencia está suspendida. Reintenta más tarde.

#SDKs

Los SDK oficiales exponen las mismas rutas como un recurso medCases (med_cases en Python, MedCases en .NET), además de un helper uploadEvidence que ejecuta los tres pasos de carga:

ts
import { LiqfyClient } from '@liqfy/node';
import { readFile } from 'node:fs/promises';

const client = new LiqfyClient({ apiKey: process.env.LIQFY_API_KEY!, baseUrl: 'https://api.liqfy.com.br' });

const { data, has_more, next_cursor } = await client.medCases.list({ status: 'open' });

for (const medCase of data) {
  await client.medCases.uploadEvidence(medCase.id, await readFile('delivery-receipt.pdf'), {
    fileName: 'delivery-receipt.pdf',
    mimeType: 'application/pdf',
  });
  await client.medCases.appeal(medCase.id, 'Order delivered; signed receipt attached.');
}

Consulta SDK oficiales para la instalación y los demás lenguajes.

#Campos metadata de la transacción

Un cobro disputado también puede incluir bloques informativos en su metadata. Son informativos y no autoritativos: reflejan lo que se informó sobre el caso, son de solo lectura, pueden cambiar con cada evento del caso y su estructura puede cambiar. No construyas lógica sobre ellos — usa el objeto med_case descrito arriba.

#metadata.med — presente en un cobro disputado

CampoSignificado
caseIdId del caso MED (med_…) — el mismo id que GET /v1/med/cases/{id} y los webhooks med_case. Estable durante toda la vida del caso; úsalo para correlacionar el cobro con su caso. Puede estar ausente brevemente justo después de que se abre el caso, y está ausente en los casos abiertos antes de que existiera este campo.
referenceIdEl end_to_end_id (E2E) del Pix original que se disputa.
statusEstado del caso según lo informado: created | delivered | closed | canceled (reclamo retirado).
resultResultado del fallo según lo informado, cuando está cerrado: agreed (en tu contra) | disagreed (informado a tu favor). disagreed por sí solo no prueba que el dinero haya vuelto — lee money_outcome en el caso.
methodMotivo alegado: scam | unauthorized | coercion | invasion | other.
reasonDescripción textual del caso.
payerName / payerDocumentIdentidad de quien abrió el MED, cuando se informa.
openedAt / updatedAt / closedAtMarcas de tiempo del caso según lo informado (apertura / actualización / cierre).
lastEventAtCuándo Liqfy procesó el evento más reciente de este caso.
amountMismatchtrue cuando el monto informado difirió del monto del cobro. En ese caso, por seguridad, no se aplica ningún cambio de estado y el caso pasa a gestión manual.

Pueden aparecer otras claves en este bloque; ignora las que no reconozcas.

#metadata.failure — presente en un cobro expired / cancelled / failed

CampoSignificado
reasonMotivo textual de la falla informado por el proveedor.
providerErrorCodeCódigo/estado del proveedor (p. ej. expired, canceled) — lo que determinó el estado final.
ttlSecondsVida útil del QR de Pix en segundos (pix.expires_at − creación), cuando el cobro tenía vencimiento. Ausente cuando no lo tenía.
atCuándo se registró la falla (ISO 8601).

#Relacionado

  • Payloads y firmas de los webhooks de MED: Webhooks.
  • Reembolso voluntario (distinto del MED): consulta la pregunta sobre reembolsos en Pix y la referencia de la API.