El acuerdo de liquidación (a fondo)
Antes de recibir tu primer pago tienes que decidir una cosa: a dónde va a llegar el dinero.
Eso es un destino — en la API, un acuerdo de liquidación (agreement). Es un juego de reglas que dice cómo recibes: a qué cuenta bancaria tuya se acredita, qué métodos de pago aceptas, y si lo que llegue ahí se reparte con otros. Se define una vez y se reutiliza en muchas sesiones de pago.
Y puedes tener tantos como te hagan falta. Un negocio con una sola cuenta tendrá uno. Uno que separa ingresos por sucursal o por línea de producto, o que reparte con socios en unos casos y no en otros, tendrá varios — uno por caso. Cada destino tiene su agreement_id, y es lo que dice, en cada pago, por dónde lo enruta SPIDI.
Esta página profundiza en cada campo del contrato. Si buscas cómo encajan las piezas, parte de Modelo de pago.
Acuerdo vs. sesión: la separación clave
Es la distinción que más ordena tu integración:
Acuerdo (agreement) | Sesión (payment session) | |
|---|---|---|
| Define | Cómo recibes: métodos, cuenta de liquidación, si repartes | El pago concreto: monto, referencia, quién paga |
| Cuándo | Una vez, y lo reutilizas | Una por cada pago |
| Ejemplos de campos | payment_methods, default_bank_account_id, split | amount_reference, identifier, split.distribution |
En cada sesión eliges por qué destino la enrutas, con su agreement_id.
Tipos de acuerdo
El contrato expone dos operaciones para crear acuerdos:
- Acuerdo de liquidación (
createAgreement,POST /api/v1/ext/agreements) — el acuerdo con el que recibes pagos. Es el que referencias desde una sesión con suagreement_id. - Acuerdo de recepción de split (
createSplitReceivingAgreement,POST /api/v1/ext/split-receiving-agreements) — define un receptor final que puede recibir montos repartidos desde los pagos de otros. Solo enruta la liquidación; no admite splits propios. Lo usas cuando repartes → Split.
No siempre necesitas llamar a createSplitReceivingAgreement. Dar de alta un partner (createPartner, POST /api/v1/ext/partner) devuelve, junto a sus datos, su propio split_recipient_agreement_id. Ese identificador es su acuerdo de recepción.
El endpoint dedicado está para cuando necesites reglas más finas que «esta cuenta». Al usarlos son indistinguibles: la sesión solo lleva el rcv_, y ningún campo dice de qué endpoint salió.
Guarda el agreement_id. No hay forma de recuperarlo
Esto no es un consejo: es un requisito de diseño, y si lo saltas te quedas sin acuerdo.
No existe ninguna operación para listar acuerdos ni para consultar uno. El contrato oficial
declara 14 rutas y ninguna es GET /agreements. Tampoco hay listado de partners. La única
entidad que se puede enumerar es la Parada, con GET /payment-stops.
→ Guarda el agreement_id en tu sistema en el mismo momento en que creas el acuerdo, junto
al identificador de tu lado (tu cliente, tu contrato, tu sucursal). Si lo pierdes, el único
camino es crear otro.
Su canal de soporte confirmó el 12-ago-2026 que listar acuerdos funciona, y que es POST
con los filtros en el cuerpo, no un GET. No lo publicamos como disponible porque no
tenemos la ruta, no está en el contrato, y una operación sin ruta no se puede llamar.
Se la hemos pedido. Cuando llegue, esta sección cambia. Mientras tanto, diseña como si no existiera: es lo único que no te deja tirado si la respuesta tarda.
Si necesitas cambiar métodos de pago o cuenta de destino, crea un acuerdo nuevo — recuerda que puedes tener varios y elegir el que toca en cada sesión.
El acuerdo de liquidación (createAgreement)
Cuatro campos son obligatorios por contrato: title, payment_methods, default_bank_account_id y split.
{
"title": "Acuerdo sin Split",
"description": "Sin distribución de fondos",
"payment_methods": { "immediate_debit": true, "crypto": false, "mobile_payment": true },
"default_bank_account_id": "uuid_sofitasa_001",
"split": false
}
| Campo | Tipo | Obligatorio | Qué hace |
|---|---|---|---|
title | string | Sí | Título visible del acuerdo. |
description | string | No | Descripción del acuerdo (máx. 500 caracteres). |
payment_methods | object | Sí | Qué métodos aceptas. Sus tres claves son obligatorias. |
default_bank_account_id | uuid | Sí | Cuenta bancaria por defecto donde se liquida. |
split | boolean | Sí | Habilita (o no) el reparto en las sesiones de este acuerdo. |
payment_methods
Objeto con tres booleanos, los tres obligatorios:
"payment_methods": {
"immediate_debit": true,
"crypto": false,
"mobile_payment": true
}
immediate_debit— pagos con débito inmediato.crypto— pagos con criptomonedas. La liquidación siempre ocurre en bolívares.mobile_payment— pagos móviles.
default_bank_account_id
El UUID de la cuenta donde se liquida el dinero por defecto. Distintos acuerdos pueden apuntar a distintas cuentas.
No lo confundas con destination_bank_account_id. Son dos cosas y la diferencia es el alcance:
| Campo | Qué es | Cuándo lo usas |
|---|---|---|
default_bank_account_id | Tu cuenta principal: donde cae el dinero por defecto en todas tus operaciones | Siempre. Es parte del acuerdo |
destination_bank_account_id | Una instrucción opcional y puntual: manda el dinero de esta operación a otra cuenta | Solo cuando quieres desviar un pago concreto |
split es un booleano
En el acuerdo, split solo habilita el reparto — no lleva la distribución:
false— sin reparto; el owner (tú) recibe el 100 % del pago.true— permite reparto por sesión; la distribución concreta la envías en cada sesión de pago.
En el acuerdo, split es un booleano que solo habilita el reparto. La distribución concreta —quién recibe cuánto— va en el objeto split de cada sesión de pago, no aquí. Es una confusión muy común. Detalle en la sección El split: dónde va cada cosa.
Respuesta
SPIDI responde con success y data. Dentro de data vienen, entre otros, agreement_id, title, split, payment_methods, default_bank_account_id, y siempre:
status:"active"— el acuerdo queda activo y listo para usar.created_at— fecha de creación (ISO 8601).created_by— quién lo creó.
{
"success": true,
"data": {
"agreement_id": "uuid_acuerdo_001",
"title": "Acuerdo sin Split",
"split": false,
"payment_methods": { "immediate_debit": true, "crypto": false, "mobile_payment": true },
"default_bank_account_id": "uuid_sofitasa_001",
"status": "active",
"created_at": "2026-07-29T14:05:00Z",
"created_by": "usuario_owner"
}
}
status del acuerdoEl status del acuerdo es active (no se confunde con el status de una sesión, que recorre pending → paid/failed/expired). → Ciclo de vida de la sesión.
El split: dónde va cada cosa
Cuando repartes, el reparto se arma en tres lugares distintos — y confundirlos es el error más habitual:
- Acuerdo de recepción (
createSplitReceivingAgreement) — registra al receptor y su cuenta; SPIDI le asigna unsplit_recipient_agreement_idcon prefijorcv_. - Acuerdo de liquidación con
split: true— habilita el reparto (booleano, sin detalles). - Sesión de pago — en su objeto
split.distributionindicas quién recibe cuánto en esa transacción.
El objeto split de la sesión tiene:
distribution(array, ≥ 1 ítem) — cada receptor y su monto para esta transacción. Ítem obligatorio:split_recipient_agreement_id(elrcv_…del paso 1),amount_reference(cuánto recibe) yobservations.document(opcional) — evidencia (factura/recibo) que SPIDI transporta para tus partners; no calcula IVA.
La suma de los montos de distribution debe ser menor al monto total de la sesión: la diferencia se acredita al owner (tú). Todas las partes se llaman igual —la de cada partner y la tuya son cuotapartes—, porque todas responden a lo mismo: el acuerdo por el que se reparten ese pago. La guía completa, con los curl de cada paso, está en → Split.
El acuerdo de recepción de split (createSplitReceivingAgreement)
Define un receptor que puede recibir montos repartidos. Obligatorios: title y default_bank_account_id.
{
"title": "Partner 1 (recepción)",
"description": "Recibir de marketplace X",
"default_bank_account_id": "uuid_mercantil_007"
}
- SPIDI devuelve un
split_recipient_agreement_idglobal con prefijorcv_, que compartes con quien vaya a enviarte parte de sus pagos. - Este acuerdo no admite splits propios: su única función es definir el ruteo de la liquidación (a qué cuenta llega su parte).
- La respuesta incluye también
created_atycreated_by.
Un receptor (rcv_…) es un destino de fondos: la cuenta a la que se acredita su parte. No tiene webhook propio — las notificaciones del reparto llegan siempre a tu webhook_url.
Las cuatro cosas que puedes variar entre un destino y otro
Es lo que decide cuántos destinos necesitas: uno por cada combinación distinta de estas cuatro.
- Si se reparte o no.
split: falsey el 100 % se te acredita a ti;split: truey la distribución la detallas en cada sesión, contra uno o variosrcv_…. - Qué métodos aceptas. Un destino que solo acepte
mobile_payment, otro que además acepteimmediate_debit. - A qué cuenta llega. Distintas
default_bank_account_id, por si separas ingresos. - Cómo se enruta según el banco del pagador. El campo
rules, cuando esté disponible.
Reglas y buenas prácticas
- Reutiliza el acuerdo. Créalo una vez; no crees uno por pago. En cada sesión referencias su
agreement_id. - Los tres métodos son obligatorios en el objeto, aunque los pongas en
false. Envía siempre las tres claves depayment_methods. spliten el acuerdo es booleano. Si necesitas repartir, ponlo entruey detalla la distribución en la sesión.cryptoliquida en bolívares. Aceptar cripto no cambia la moneda de liquidación.
rules (En Desarrollo)El contrato incluye un campo opcional rules en el acuerdo (ruteo de la cuenta destino según el banco de origen del pagador). Está marcado En Desarrollo en el contrato; no dependas de él todavía.