Saltar al contenido principal
Como tu Merchant of Record, Dodo Payments gestiona el proceso de disputas y contracargos con las redes de tarjetas en tu nombre. Estos webhooks mantienen tus sistemas sincronizados a medida que una disputa avanza en su ciclo de vida, para que puedas revocar el acceso, recopilar evidencia y conciliar tus registros.

Eventos de Webhook de Disputa

Una disputa emite un evento en cada etapa de su ciclo de vida:
EventoDispara cuandoLo que usualmente significa
dispute.openedUn titular de tarjeta abre una disputa sobre un pagoLos fondos están retenidos; prepárate para responder
dispute.challengedSe ha presentado evidencia para impugnar la disputaLa disputa está siendo revisada por la red
dispute.acceptedLa disputa fue aceptada (no impugnada)Los fondos son devueltos al titular de la tarjeta
dispute.cancelledLa disputa fue retirada o canceladaNo se necesita más acción
dispute.expiredEl período de respuesta pasó sin resoluciónTípicamente se resuelve en tu contra
dispute.wonLa disputa se resolvió a tu favorLos fondos son retenidos
dispute.lostLa disputa se resolvió a favor del titular de la tarjetaLos fondos son devueltos al titular de la tarjeta
Las disputas resueltas automáticamente a través de Visa Rapid Dispute Resolution (RDR) aparecen como dispute.lost con is_resolved_by_rdr: true. Esto es esperado: el reembolso se emitió automáticamente para prevenir un contracargo formal.

Manejo de Eventos de Disputa

Cuando dispute.opened se dispara, el monto disputado se retiene inmediatamente. Usa el evento para actualizar tus registros y, si planeas impugnarlo, recopila evidencia en el panel de control.
Handling dispute events
app.post('/webhooks/dodo', async (req, res) => {
  const event = req.body;

  switch (event.type) {
    case 'dispute.opened': {
      const dispute = event.data;
      // Record the dispute and consider revoking access while it is open
      await recordDispute(dispute.dispute_id, dispute.payment_id, dispute.amount);
      // Gather and submit evidence from the Dodo Payments dashboard (within 4 days)
      break;
    }
    case 'dispute.won': {
      // Funds retained — restore normal state in your records
      await markDisputeResolved(event.data.dispute_id, 'won');
      break;
    }
    case 'dispute.lost': {
      // Funds returned to the cardholder — reconcile and keep access revoked
      await markDisputeResolved(event.data.dispute_id, 'lost');
      break;
    }
  }

  res.json({ received: true });
});
Siempre verifica la firma del webhook antes de procesar, consulta la guía de Webhooks para la configuración. El manejador arriba omite la verificación por brevedad.
Tienes 4 días para responder a una disputa después de que se crea. Consulta las Mejores Prácticas para la Respuesta a Disputas para la evidencia a recopilar y cómo formatearla.

Estado y Etapa de la Disputa

El objeto de disputa informa su progreso a través de dos campos:
CampoValores
dispute_statusdispute_opened, dispute_expired, dispute_accepted, dispute_cancelled, dispute_challenged, dispute_won, dispute_lost
dispute_stagepre_dispute, dispute, pre_arbitration

Relacionado

Managing Disputes

Cómo responder a disputas, presentar evidencia, y cómo RDR protege tu tasa de disputas.

Handle Payment Failures

Detecta y recupera pagos fallidos antes de que se conviertan en disputas.

Esquema de Carga Útil del Webhook

amount
string
requerido

The amount involved in the dispute, represented as a string to accommodate precision.

business_id
string
requerido

The unique identifier of the business involved in the dispute.

created_at
string<date-time>
requerido

The timestamp of when the dispute was created, in UTC.

currency
string
requerido

The currency of the disputed amount, represented as an ISO 4217 currency code.

dispute_id
string
requerido

The unique identifier of the dispute.

dispute_stage
enum<string>
requerido

The current stage of the dispute process.

Opciones disponibles:
pre_dispute,
dispute,
pre_arbitration
dispute_status
enum<string>
requerido

The current status of the dispute.

Opciones disponibles:
dispute_opened,
dispute_expired,
dispute_accepted,
dispute_cancelled,
dispute_challenged,
dispute_won,
dispute_lost
payment_id
string
requerido

The unique identifier of the payment associated with the dispute.

is_resolved_by_rdr
boolean | null

Whether the dispute was resolved by Rapid Dispute Resolution

remarks
string | null

Remarks

Última modificación el 18 de junio de 2026