Saltar al contenido principal

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.

El acuerdo de liquidación, a fondoGuion: .docx · .yaml

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)
DefineCómo recibes: métodos, cuenta de liquidación, si repartesEl pago concreto: monto, referencia, quién paga
CuándoUna vez, y lo reutilizasUna por cada pago
Ejemplos de campospayment_methods, default_bank_account_id, splitamount_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 su agreement_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.
El alta de un partner ya te devuelve uno

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.

SPIDI dice que sí existe, y lleva desde el 12-ago sin ruta

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.

Modificar un acuerdo sigue sin estar disponible

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
}
CampoTipoObligatorioQué hace
titlestringTítulo visible del acuerdo.
descriptionstringNoDescripción del acuerdo (máx. 500 caracteres).
payment_methodsobjectQué métodos aceptas. Sus tres claves son obligatorias.
default_bank_account_iduuidCuenta bancaria por defecto donde se liquida.
splitbooleanHabilita (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:

CampoQué esCuándo lo usas
default_bank_account_idTu cuenta principal: donde cae el dinero por defecto en todas tus operacionesSiempre. Es parte del acuerdo
destination_bank_account_idUna instrucción opcional y puntual: manda el dinero de esta operación a otra cuentaSolo 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.
La distribución NO va en el acuerdo

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 acuerdo

El 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:

  1. Acuerdo de recepción (createSplitReceivingAgreement) — registra al receptor y su cuenta; SPIDI le asigna un split_recipient_agreement_id con prefijo rcv_.
  2. Acuerdo de liquidación con split: truehabilita el reparto (booleano, sin detalles).
  3. Sesión de pago — en su objeto split.distribution indicas 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 (el rcv_… del paso 1), amount_reference (cuánto recibe) y observations.
  • 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_id global con prefijo rcv_, 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_at y created_by.
Un receptor es una cuenta, no una URL

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: false y el 100 % se te acredita a ti; split: true y la distribución la detallas en cada sesión, contra uno o varios rcv_….
  • Qué métodos aceptas. Un destino que solo acepte mobile_payment, otro que además acepte immediate_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 de payment_methods.
  • split en el acuerdo es booleano. Si necesitas repartir, ponlo en true y detalla la distribución en la sesión.
  • crypto liquida en bolívares. Aceptar cripto no cambia la moneda de liquidación.
Campo 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.

Modelo de pago · Split · Ciclo de vida de la sesión