🚀 Lanzamiento v2.3: Activa y desactiva métodos de pago para tu Conekta Checkout desde el Panel, sin tocar tu código. Ver documentación →

Seguimiento de dispersiones

Consulta el estado de tus dispersiones, próximas y pasadas

Una vez que tienes beneficiarios e instrucciones de dispersión configuradas, puedes consultar en cualquier momento qué se va a pagar, qué ya se pagó y en qué estado está cada dispersión.

Conceptos

  • Grupo de dispersión (batch) — todos los pagos que ocurren (o se proyecta que ocurran) en una misma fecha para tu negocio.
  • Dispersión — el pago individual a un beneficiario dentro de un grupo.

Grupos de dispersión (batches)

# Próximos 30 días (proyección)
curl --request GET \
  --url 'https://api.conekta.io/payouts/batches?tab=proximas' \
  --header 'Accept: application/vnd.conekta-v2.3.0+json' \
  --header 'Authorization: Bearer key_ZLy4TfHN2wM9pXqRkD8jV3sB'

# Historial real
curl --request GET \
  --url 'https://api.conekta.io/payouts/batches?tab=historial' \
  --header 'Accept: application/vnd.conekta-v2.3.0+json' \
  --header 'Authorization: Bearer key_ZLy4TfHN2wM9pXqRkD8jV3sB'

Parámetros de consulta:

ParámetroDescripción
tabproximas (default) — proyecta los próximos 30 días según tus instrucciones activas. historial — grupos ya ejecutados. Sin status explícito, historial muestra los grupos de fechas pasadas en cualquier estado (para que uno atascado en processing siga siendo visible) y los de hoy en adelante solo si ya son completed o failed. Si pasas status explícitamente, ese filtro se aplica tal cual, sin este recorte por fecha.
statusupcoming, scheduled, processing, completed, failed, incomplete. 422 si el valor no es uno de estos seis. Para historial, upcoming no aplica y devuelve lista vacía.
scheduled_from / scheduled_toRango de fechas YYYY-MM-DD. 422 si la fecha no es parseable.
page / limitPaginación. Default 1 / 20, máximo 100.

Respuesta 200 OK:

{
  "data": [
    {
      "date": "2026-06-02",
      "status": "upcoming",
      "funding_batch_id": null,
      "beneficiary_count": 3,
      "disbursement_count": 4,
      "skipped_count": 0,
      "failed_count": 0,
      "total_amount": 2925000,
      "total_fees": 0,
      "is_projection": true
    }
  ],
  "pagination": { "pageIndex": 1, "totalPages": 1, "totalItems": 8, "itemsPerPage": 20, "hasPreviousPage": false, "hasNextPage": false }
}

Valores de status:

ValorSignificado
upcomingEl grupo proyectado más próximo — el siguiente en ejecutarse.
scheduledGrupos proyectados posteriores, o ya creados pero aún no procesados.
processingEl fondeo o la dispersión están en curso — incluye el caso en que ninguna instrucción tuvo saldo suficiente ese día: el grupo queda aquí (no en failed) esperando un fondeo adicional que lo reactive.
completedTodas las dispersiones del grupo se completaron.
failedTodas las dispersiones del grupo terminaron en falla, sin ninguna recuperable pendiente.
incompleteResultado mixto: al menos una dispersión se completó y al menos una falló sin quedar nada recuperable pendiente. No se recupera solo — necesitas reintentar las que fallaron.

total_amount y total_fees están en centavos MXN, igual que el amount de una instrucción de dispersión — ambos son enteros, sin decimales. total_fees refleja la comisión efectivamente cobrada hasta el momento de la consulta — se actualiza a medida que se despachan y cobran las dispersiones del grupo, no es un estimado fijo desde su creación. funding_batch_id es null mientras el grupo sigue siendo una proyección (is_projection: true); se llena una vez que existe un fondeo real para esa fecha. skipped_count cuenta las dispersiones skipped por límite del beneficiariono están incluidas en disbursement_count, total_amount ni total_fees. Un grupo con solo dispersiones skipped se marca completed, no failed. failed_count cuenta las dispersiones en failed dentro del grupo — útil para decidir si vale la pena llamar al endpoint de reintento por grupo (0 en proyecciones).

Detalle de un grupo

curl --request GET \
  --url https://api.conekta.io/payouts/batches/2026-06-02 \
  --header 'Accept: application/vnd.conekta-v2.3.0+json' \
  --header 'Authorization: Bearer key_ZLy4TfHN2wM9pXqRkD8jV3sB'

Incluye el arreglo disbursements con cada pago individual del grupo (real o proyectado) y el beneficiario y la instrucción asociados:

{
  "date": "2026-06-02",
  "status": "upcoming",
  "funding_batch_id": null,
  "total_amount": 2925000,
  "total_fees": 0,
  "failed_count": 0,
  "is_projection": true,
  "disbursements": [
    {
      "id": null,
      "status": "pending",
      "amount": 1250000,
      "fee_charged": 0,
      "cep_url": null,
      "is_projection": true,
      "payee": { "id": "payee_abc123", "name": "Mkt Solutions SA", "alias": "mkt-solutions" },
      "rule": { "id": "payout_rule_xyz789", "rule_type": "recurrent", "frequency": "monthly", "name": "Nómina mensual" }
    }
  ]
}

Si la fecha es futura y ninguna instrucción activa proyecta ejecución ese día, la respuesta es 404.

Dispersiones

Todas las dispersiones del negocio

curl --request GET \
  --url 'https://api.conekta.io/payouts/disbursements?status=completed' \
  --header 'Accept: application/vnd.conekta-v2.3.0+json' \
  --header 'Authorization: Bearer key_ZLy4TfHN2wM9pXqRkD8jV3sB'

Parámetros de consulta:

ParámetroDescripción
statuspending, processing, completed, failed, skipped. Uno o varios separados por coma. 422 si algún valor no es válido.
rule_typeone_time, scheduled, recurrent. Uno o varios separados por coma. 422 si algún valor no es válido.
created_from / created_toRango de fechas YYYY-MM-DD.
page / limitPaginación. Default 1 / 20, máximo 100.

Cada elemento incluye el beneficiario embebido:

{
  "id": "external_payout_transaction_31A4VsoUJ7ddQ6s9y",
  "status": "completed",
  "amount": 150000,
  "fee_charged": 450,
  "created_at": 1780502641,
  "executed_at": 1780243439,
  "settled_at": 1780243479,
  "tracking_key": "1234567890123456789",
  "cep_url": "https://www.banxico.org.mx/cep/go?i=90734&s=20260710&d=abc",
  "failure_reason": null,
  "skip_reason": null,
  "rule": { "id": "6a188130ff51790001e27a00", "rule_type": "recurrent", "frequency": "monthly", "name": "Nómina mensual" },
  "payee": { "id": "payee_317roDjGQMta9DYVs", "name": "Juan Pérez García", "alias": "proveedor-norte" }
}

Historial de dispersiones de un beneficiario

curl --request GET \
  --url 'https://api.conekta.io/payouts/payees/PAYEE_ID/disbursements' \
  --header 'Accept: application/vnd.conekta-v2.3.0+json' \
  --header 'Authorization: Bearer key_ZLy4TfHN2wM9pXqRkD8jV3sB'

Acepta los mismos filtros (status, rule_type, created_from, created_to, page, limit). A diferencia del endpoint anterior, no incluye el objeto payee (ya lo tienes si estás consultando por PAYEE_ID).

Detalle de una dispersión

curl --request GET \
  --url 'https://api.conekta.io/payouts/payees/PAYEE_ID/disbursements/external_payout_transaction_xxxxxxxx' \
  --header 'Accept: application/vnd.conekta-v2.3.0+json' \
  --header 'Authorization: Bearer key_ZLy4TfHN2wM9pXqRkD8jV3sB'

Campos de una dispersión:

CampoDescripción
statuspending, processing, completed, failed, skipped.
amountMonto en centavos MXN.
fee_chargedComisión cobrada, en centavos MXN.
executed_atMomento en que se envió la instrucción. null si aún no se ha ejecutado, o si nunca se ejecutó por quedar skipped.
settled_atMomento en que SPEI confirmó la liquidación final. null hasta entonces.
tracking_keyClave de rastreo SPEI. Se llena al recibir la confirmación de liquidación — null hasta entonces.
cep_urlURL del Comprobante Electrónico de Pago de Banxico. null hasta que se genera tras la liquidación — solo para Money Out; nunca se genera para Money In o reembolsos.
failure_reasonMotivo de un intento de envío que falló, cuando aplica. null si no falló.
skip_reasonpayee_limit_exceeded. Solo presente cuando status == "skipped".
ruleLa instrucción de dispersión que la generó. null si la instrucción fue eliminada.
📘

skip_reason no es lo mismo que failure_reason

failure_reason describe un envío que se intentó y falló (rechazo del banco, saldo insuficiente). skip_reason describe una instrucción que nunca se intentó enviar porque el límite del beneficiario la bloqueó antes del dispatch. Una dispersión skipped es terminal — a diferencia de un failed por saldo insuficiente, nunca se reintenta automática ni manualmente; corrige el límite o el monto y genera una instrucción nueva.

Errores:

CódigoMotivo
404 Not FoundEl external_payout_transaction_xxxxxxxx no existe, no pertenece al PAYEE_ID indicado, o no pertenece a tu negocio.

Reintentar una dispersión fallida por saldo insuficiente

Una dispersión failed es reintentable solo si su failure_reason es recuperable — hoy, saldo insuficiente (insufficient_balance) o precio no disponible (pricing_unavailable). Un reintento, automático o manual, hace que la misma transacción vuelva a pending — no crea una dispersión nueva:

  • Automático: en cuanto llega un fondeo adicional (MONEY_IN) a tu cuenta de dispersiones, Conekta reintenta sin que hagas nada las transacciones fallidas recuperables que puede cubrir.
  • Manual, vía API: dos endpoints sobre el mismo motor de clasificación.

Reintentar una dispersión individual:

curl --request POST \
  --url https://api.conekta.io/payouts/disbursements/external_payout_transaction_31A4VsoUJ7ddQ6s9y/retry \
  --header 'Accept: application/vnd.conekta-v2.3.0+json' \
  --header 'Authorization: Bearer key_ZLy4TfHN2wM9pXqRkD8jV3sB'

Respuesta 202 Accepted:

{ "id": "external_payout_transaction_31A4VsoUJ7ddQ6s9y", "status": "pending", "failure_reason": null }
🚧

202, no 200 — la respuesta no es el resultado del reintento

El status: "pending" confirma que la transacción se reseteó y quedó encolada para dispersarse — el dispatch real ocurre después, de forma asíncrona. Sigue el resultado final por los webhooks payout.* o consultando Detalle de una dispersión.

Reintentar todas las elegibles de un grupo de dispersión:

curl --request POST \
  --url https://api.conekta.io/payouts/batches/2026-06-02/retry \
  --header 'Accept: application/vnd.conekta-v2.3.0+json' \
  --header 'Authorization: Bearer key_ZLy4TfHN2wM9pXqRkD8jV3sB'

La fecha es la misma que usas en Detalle de un grupo. Solo evalúa las dispersiones en failed de ese grupo — usa failed_count (ver la sección "Grupos de dispersión" arriba) para saber si vale la pena llamarlo.

Respuesta 202 Accepted:

{
  "summary": { "queued": 2, "not_eligible": 2 },
  "not_eligible_by_reason": { "not_retriable_failure": 1, "external_payee_not_validated": 1 }
}

Errores:

CódigoMotivo
422 Unprocessable EntityLa dispersión no es elegible (instruction_not_eligible): ya se completó (already_completed), ya está en curso (already_in_progress), nunca se despachó (not_yet_attempted), falló por un motivo no reintentable (not_retriable_failure), su beneficiario ya no está validated_active (external_payee_not_validated), o la regla que la generó fue eliminada (cancelled).
404 Not FoundLa dispersión, o la fecha del grupo, no existe o no pertenece a tu negocio. Una fecha proyectada nunca es reintentable.
422 Unprocessable Entity (reintento por grupo)La fecha no tiene un formato YYYY-MM-DD válido.
📘

Este endpoint no dispara la primera ejecución

Una dispersión que todavía no se ha intentado (not_yet_attempted) no es elegible para reintento — eso sigue siendo trabajo exclusivo del proceso nocturno o del dispatch on-demand.

Notificaciones

Agrega un Webhook a tu cuenta para recibir actualizaciones de estado de tus dispersiones y beneficiarios sin tener que hacer polling.

Eventos de una dispersión:

EventoCuándo se dispara
payout.createdAl crear la ExternalPayoutTransaction — tanto si se va a fondear hoy como si queda pendiente esperando saldo.
payout.in_transitJusto antes de enviar la instrucción a la red SPEI.
payout.paid_outCuando el banco confirma la liquidación final.
payout.failedCuando el banco rechaza o revierte la dispersión, o cuando falla por saldo insuficiente u otro error de ejecución.
payout.retryingCuando una dispersión failed recuperable (insufficient_balance/pricing_unavailable) vuelve a pending — por un fondeo adicional (MONEY_IN) o por un reintento manual vía API. Se dispara en ambos casos por igual.
payout.skipped_limitCuando una dispersión queda skipped por el límite del beneficiario — nunca se dispara junto con payout.created para esa misma dispersión.

Eventos de un beneficiario:

EventoCuándo se dispara
payee.payout_method.createdAl crear un beneficiario.
payee.payout_method.updatedAl editar metadata, cambiar validation_status, o cuando termina la validación automática de cuenta (resultado real, no la respuesta inmediata del POST).
payee.payout_method.deletedAl eliminar un beneficiario.
payee.max_amount_limit.updatedAl editar (PATCH) el max_amount_limit de un beneficiario.

Eventos de una regla de dispersión:

Estos eventos son sobre la instrucción (payout_rule) en sí, no sobre una dispersión individual:

EventoCuándo se dispara
payout_rule.renewal.upcomingA 30, 15 y 3 días de que una instrucción recurrent llegue a su end_date — mismo evento sin importar el valor de auto_renew.
payout_rule.paused_by_expirationCuando una instrucción recurrent con auto_renew: true llega a end_date sin confirmarse y pasa a paused_by_expiration.
payout_rule.monthly_digestUna vez al mes (primer día hábil), por negocio con al menos una instrucción recurrent activa ese mes — resumen, no una proyección día por día.

Ver Vigencia y renovación de instrucciones recurrentes para el ciclo completo de estos eventos.

Consulta Eventos de Conekta para el catálogo completo y el formato general del payload de cada tipo.

Importante

Verifica siempre la firma de cada notificación antes de actuar sobre ella — ver Verificar firmas de Webhooks. Un webhook de dispersiones sin verificar puede ser falsificado por un tercero para simular que un pago falló o se completó.

Related


Did this page help you?