Webhooks y conciliación

Los eventos de préstamos y cuotas, cómo reconocer una venta en cuotas y cómo conciliar tu balance.

Webhooks y conciliación

Los eventos llegan por tus webhooks de siempre, con el mismo formato, firma y reintentos.

Eventos de préstamos

EventoCuándo
loan.createdSe creó un préstamo (aún sin aprobar).
loan.approvedLa evaluación crediticia lo aprobó (status: "succeeded").
loan.authorizedEl crédito se concretó: la primera cuota se cobró. Este es el evento de venta — junto con él, si venía de un checkout, recibes checkout.paid.
loan.failedNo se pudo aprobar (razón de sistema).
loan.canceledSe canceló — por ejemplo, expiró sin autorizarse.
loan.refundedSe devolvió (total o parcialmente; refunded_amount acumulado).
loan.disputedEl cliente disputó la transacción.

Eventos de cuotas

EventoCuándo
installment.createdSe creó una cuota (al aprobarse el préstamo).
installment.paidUna cuota se pagó (incluida la primera, al autorizar).
installment.past_dueUna cuota venció y el cobro automático falló.
installment.canceledUna cuota se canceló (típicamente por una devolución).

Para tu operación normal basta con loan.authorized (venta) y loan.refunded (devolución); los eventos de cuotas son informativos — la cobranza es de Venti.

Reconocer una venta en cuotas

Un checkout pagado con financiamiento se distingue por successful_object:

{
  "id": "chk_oGGZr23beBw6IXvJ3SNK7d7E",
  "status": "paid",
  "successful_object": "loan",
  "loan_id": "loan_mK4vR7xT3nQ8sYbF6dAoU2Wp",
  "payment_id": null
}

Con expand[]=loan obtienes el préstamo en la misma llamada (installments_plan, fee, etc.). Un préstamo directo (creado con POST /loans) no tiene checkout_id; su evento de venta es loan.authorized.

Conciliación contable

La regla de oro: tu abono ocurre una sola vez, al autorizarse el préstamo. Las cuotas del cliente nunca tocan tu balance.

Evento de negocioObjetosTu balance en Venti
Venta en cuotas autorizadaloan.authorized + checkout.paid+ amount, − fee, − payout_fee (si aplica), − IVA
Cliente paga una cuotainstallment.paidSin impacto
Cuota atrasada / incobrableinstallment.past_dueSin impacto
Devoluciónloan.refunded− monto devuelto (y reintegro de comisión, si tu comercio lo tiene pactado)

En la práctica:

  • Concilia ventas contra transacciones de balance tipo loan (cada una referencia su loan_id), igual que concilias payment.
  • El préstamo indica su payout con payout_id; puedes filtrar GET /loans?payout_id=po_... para cuadrar un payout.
  • No intentes cuadrar los pagos de cuotas contra tu flujo de caja: son cobros de Venti al cliente.

Idempotencia y reintentos

Los webhooks pueden llegar más de una vez (reintentos durante 3 días): deduplica por el id del evento o del objeto, como con cualquier otro webhook de Venti. El estado que manda siempre es el del objeto — ante la duda, consulta GET /loans/{id}.

Modo test

Todo el flujo funciona en modo test con tu API key de test y las tarjetas de prueba: el cliente elige cuotas en el checkout de test, el préstamo se aprueba y autoriza, y se generan las cuotas. En modo test no se ejecuta la evaluación crediticia real ni las validaciones de identidad del cliente, para que puedas probar la integración completa sin datos reales.