VexorpayDocs
VexorpayDocs
APIDocumentación de VexorpayPrimeros pasosVenta de producto digital

Core API

Referencia de APICrear link de pago únicoCrear link de pago recurrenteListar y obtener linksSuscripcionesCheckout por compraCobrosDisputasSaldoRetirosAcreditacionesEventos de reconciliaciónWebhooks salientesAutenticaciónEspecificación OpenAPI

Recursos

Migrar desde el SDK `vexor`PostmanComunidadModo sandbox

Disputas

Consulta las disputas (chargebacks) de tu cuenta, el detalle con la evidencia cargada y responde una disputa con evidencia.

Las disputas (dispute, o chargeback) son reclamos que abre el titular de una tarjeta. Podés listarlas, ver el detalle con el estado en vivo de Stripe y responder con evidencia antes del plazo.

La aceptación de disputas no está disponible por API. Aceptar (perder) una disputa es irreversible y sólo puede hacerse desde el dashboard. Esta API sólo permite listar, ver y responder.

Listar disputas

GET /api/v1/disputes

Parámetros

ParámetroDescripción
statuswarning_needs_response, warning_under_review, warning_closed, needs_response, under_review, won, lost, expired o closed.
charge_idFiltrar por el cobro original asociado a la disputa.
sandboxtrue (solo disputas de prueba) o false (solo producción). Sin el parámetro devuelve ambos entornos.
limit / starting_after / ending_beforePaginación por cursor (default 10, máximo 100).

Ejemplo

curl "https://api.vexorpay.com/api/v1/disputes?status=needs_response" \
  -H "Authorization: Bearer vxp_u_tu_clave"

Respuesta exitosa

200 OK

{
  "data": [
    {
      "id": "68f1c1e2c8a4b0d1f2e3a4b5",
      "chargeId": "67f1c1e2c8a4b0d1f2e3a4b5",
      "paymentLinkId": "66f1c1e2c8a4b0d1f2e3a4b5",
      "reference": "ORD-1001",
      "customerEmail": "cliente@mail.com",
      "stripeDisputeId": "dp_1UC0lPPRu4jOz4R",
      "status": "needs_response",
      "statusLabel": "Requiere respuesta",
      "reason": "fraudulent",
      "reasonLabel": "Pago fraudulento",
      "amountCents": 1900,
      "currency": "usd",
      "feeCents": 1500,
      "evidenceDeadline": "2026-10-15T12:00:00.000Z",
      "daysLeft": 7,
      "isOpen": true,
      "canRespond": true,
      "canAccept": true,
      "outcome": null,
      "recoveredCents": null,
      "compensatedCents": null,
      "sandbox": false,
      "paymentLinkUrl": "https://www.vexorpay.com/p/a1b2c3d4e5",
      "createdAt": "2026-10-08T12:03:00.000Z",
      "resolvedAt": null
    }
  ],
  "has_more": false,
  "total_count": 1,
  "url": "/v1/disputes?limit=10"
}

Campos clave:

  • status: estado de la disputa. Abiertas: needs_response, under_review (y las consultas tempranas warning_needs_response, warning_under_review). Cerradas: won, lost, expired, warning_closed.
  • isOpen / canRespond: canRespond es false cuando ya venció el plazo o la disputa está cerrada.
  • canAccept: si se puede aceptar (perder) la disputa. Es false para las consultas tempranas (warning_*), que se cierran solas.
  • feeCents: la fee de Stripe por la disputa (USD 15), que se cobra al creador en todos los desenlaces.
  • evidenceDeadline / daysLeft: plazo para enviar evidencia (null cuando no aplica o ya venció).

Obtener una disputa

GET /api/v1/disputes/{id}

El id es el id local de la disputa (el campo id de la lista, no el stripeDisputeId). En sandbox, mandá ?sandbox=true.

Además del resumen, la respuesta incluye el estado en vivo de Stripe (por si el webhook todavía no llegó), la evidencia ya cargada, el costo estimado y el enlace al panel de Stripe.

{
  "id": "68f1c1e2c8a4b0d1f2e3a4b5",
  "stripeDisputeId": "dp_1UC0lPPRu4jOz4R",
  "status": "needs_response",
  "stripe": {
    "status": "needs_response",
    "evidenceDueBy": "2026-10-15T12:00:00.000Z",
    "hasEvidence": false,
    "submissionCount": 0,
    "pastDue": false,
    "cardBrand": "visa",
    "cardCaseType": "fraudulent",
    "networkReasonCode": "10.4",
    "reason": "fraudulent"
  },
  "evidence": {
    "productDescription": null,
    "customerCommunication": null,
    "receipt": null,
    "uncategorizedText": null
  },
  "cost": {
    "amountInDisputeCents": 1900,
    "feeCents": 1500,
    "feeChargedToCreator": true,
    "recoveredCents": null,
    "compensatedCents": null
  },
  "paymentLinkUrl": "https://www.vexorpay.com/p/a1b2c3d4e5",
  "stripeDashboardUrl": "https://dashboard.stripe.com/disputes/dp_1UC0lPPRu4jOz4R"
}

Devuelve la disputa o 404 dispute_not_found.

Responder una disputa

POST /api/v1/disputes/{id}/response

Carga evidencia en una disputa abierta y la envía a Stripe (submit: true). La evidencia va en snake_case; al menos un campo debe tener contenido. Una vez enviada, la disputa pasa a under_review y el plazo deja de aplicar.

Soporta Idempotency-Key: un replay con la misma clave y el mismo body devuelve el detalle actual de la disputa sin re-enviar evidencia (200); con la misma clave y un body distinto responde 409 idempotency_conflict.

Body

CampoDescripción
product_descriptionQué se entregó/servició y por qué el cobro es legítimo (campo principal).
customer_communicationConversación con el cliente (se concatena con notes en uncategorized_text).
notesNotas libres.
service_dateFecha de entrega/servicio (YYYY-MM-DD).
shipping_carrier / shipping_tracking_numberEnvío (para product_not_received).
refund_policy_urlURL pública de la política de reembolso.
cancellation_policy_urlURL pública de la política de cancelación.
cancellation_rebuttalRefutación de la cancelación (suscripciones).
duplicate_charge_id / duplicate_charge_explanationCobro duplicado (reason duplicate).
attach_receiptAdjunta el comprobante PDF del pago como evidencia (default false).
sandboxtrue para operar sobre disputas de prueba.

Ejemplo

curl https://api.vexorpay.com/api/v1/disputes/68f1c1e2c8a4b0d1f2e3a4b5/response \
  -X POST \
  -H "Authorization: Bearer vxp_u_tu_clave" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: dispute-68f1c1e2-response-1" \
  -d '{
    "product_description": "Ebook de UX en PDF enviado por email el 2026-01-02.",
    "customer_communication": "El cliente confirmó la recepción por email.",
    "notes": "Entrega verificada en el log de envíos.",
    "attach_receipt": true
  }'

Respuesta exitosa

200 OK con el detalle de la disputa actualizado (mismo shape que GET /api/v1/disputes/{id}). El campo stripe.status pasa a under_review.

Sobre los textos de evidencia: la conversación con el cliente (customer_communication) y tus notes se concatenan en uncategorized_text de Stripe. Cada campo de texto admite hasta 20.000 caracteres: los valores más largos se recortan para que la evidencia nunca falle por largo.

Errores

ErrorHTTPCausa
validation_error400status no es un estado válido en el listado.
dispute_not_found404No existe esa disputa en tu cuenta (o es de otro modo).
dispute_not_respondable400La disputa ya está cerrada: no admite respuesta.
dispute_deadline_passed400Venció el plazo para enviar evidencia.
evidence_required400Ningún campo de evidencia tiene contenido.
dispute_evidence_rejected400Stripe rechazó la evidencia (el mensaje trae el detalle).
idempotency_conflict409La Idempotency-Key ya se usó con un body distinto.

Cobros

Consulta los cobros de tu cuenta, un cobro puntual y el comprobante en PDF.

Saldo

Consulta el saldo disponible y pendiente de tu cuenta conectada.

On this page

Listar disputasParámetrosEjemploRespuesta exitosaObtener una disputaResponder una disputaBodyEjemploRespuesta exitosaErrores