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
| Evento | Cuándo |
|---|---|
loan.created | Se creó un préstamo (aún sin aprobar). |
loan.approved | La evaluación crediticia lo aprobó (status: "succeeded"). |
loan.authorized | El 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.failed | No se pudo aprobar (razón de sistema). |
loan.canceled | Se canceló — por ejemplo, expiró sin autorizarse. |
loan.refunded | Se devolvió (total o parcialmente; refunded_amount acumulado). |
loan.disputed | El cliente disputó la transacción. |
Eventos de cuotas
| Evento | Cuándo |
|---|---|
installment.created | Se creó una cuota (al aprobarse el préstamo). |
installment.paid | Una cuota se pagó (incluida la primera, al autorizar). |
installment.past_due | Una cuota venció y el cobro automático falló. |
installment.canceled | Una 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 negocio | Objetos | Tu balance en Venti |
|---|---|---|
| Venta en cuotas autorizada | loan.authorized + checkout.paid | + amount, − fee, − payout_fee (si aplica), − IVA |
| Cliente paga una cuota | installment.paid | Sin impacto |
| Cuota atrasada / incobrable | installment.past_due | Sin impacto |
| Devolución | loan.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 suloan_id), igual que conciliaspayment. - El préstamo indica su payout con
payout_id; puedes filtrarGET /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.
Updated 1 day ago

