Quién es dueño de qué. El sistema de la inmobiliaria es la fuente de la verdad del contrato: comprador, propiedad, importes y vencimientos. Finpass es la fuente de la verdad del pago: códigos de pago, confirmación del banco, conciliación, recibos y el rastro de evidencias. Finpass nunca se convierte en el sistema de gestión de la inmobiliaria.
Autenticación
Cada inmobiliaria tiene una clave de API. El responsable la genera en el panel, en Integração → Gerar nova chave (Integración → Generar nueva clave; el panel hoy está en portugués). La clave se muestra una sola vez, y generar una nueva desactiva la anterior.
Authorization: Bearer fp_…
Content-Type: application/json
Las reglas de la sincronización
Las mismas reglas valen para la API y para la importación por planilla.
La clave de enlace es la referencia del contrato en el sistema de la inmobiliaria (única por inmobiliaria), más el número de cuota (
seq) dentro del contrato. Enviar el mismo contrato otra vez nunca duplica nada.Crear o actualizar. Una referencia desconocida crea el contrato. Una referencia conocida actualiza el comprador, la descripción de la propiedad y las cuotas que cambiaron.
Una cuota omitida queda como está. Nada se borra porque faltó en el envío. Para cancelar una cuota, envíela con
"status": "cancelled".El dinero en curso está protegido. Estos cambios no se aplican; vuelven como
conflictpara que una persona los resuelva en el panel:- un importe nuevo en una cuota pagada, pagada en parte o con un código de pago emitido;
- la cancelación de una cuota que ya recibió dinero;
- la reapertura de una cuota cancelada.
Cambiar solo el vencimiento se aplica, siempre que el importe siga igual.
La rescisión no se sincroniza. Enviar
"status": "terminated"devuelve un conflicto. La rescisión se hace en el panel, porque calcula la devolución.La moneda del contrato nunca cambia después de creado el contrato.
Un teléfono nuevo del comprador vale para los próximos recordatorios. Si el número nuevo ya pertenece a otro comprador de la misma inmobiliaria, se mantiene el número anterior y se devuelve un conflicto.
Formato del contrato
{
"reference": "LOTE-12-QD-7",
"status": "active",
"propertyLabel": "Manzana 7, lote 12",
"currency": "PYG",
"buyer": {
"name": "María Benítez",
"phone": "595981234567",
"document": "4.567.890",
"email": "maria@ejemplo.com"
},
"installments": [
{ "seq": 1, "amount": "920000", "dueDate": "2026-11-24" },
{ "seq": 2, "amount": "920000", "dueDate": "2026-12-24" },
{ "seq": 3, "amount": "920000", "dueDate": "2027-01-24", "status": "cancelled" }
]
}
| Campo | Regla |
|---|---|
reference |
Obligatorio, hasta 120 caracteres. |
currency |
ISO 4217, por ejemplo PYG, BRL, USD, EUR, ARS. |
buyer.phone |
Dígitos con el código de país. Se ignoran +, espacios y guiones. |
installments[].amount |
Texto decimal con punto ("2450.00"). PYG no tiene decimales ("920000"). |
installments[].dueDate |
AAAA-MM-DD. |
installments[].status |
open (por defecto) o cancelled. |
Un contrato que no pasa la validación se rechaza entero, y no se graba nada.
Los nombres de los campos, los valores de status y los códigos de error son siempre los mismos, en
cualquier idioma.
Endpoints
POST /api/sync/contracts: lote
Hasta 200 contratos por llamada. Cada contrato se trata por separado, y el lote entero queda registrado como una sincronización, visible en el panel en Integração.
{ "contracts": [ { …contrato… }, { …contrato… } ] }
Respuesta 200:
{
"runId": "5fbda03b-…",
"total": 3, "created": 1, "updated": 0, "unchanged": 1, "rejected": 1, "conflicts": 0,
"results": [
{
"reference": "LOTE-12-QD-7",
"status": "created",
"contractId": "…",
"changes": { "buyer": true, "property": true,
"installments": { "created": 2, "updated": 0, "cancelled": 0, "unchanged": 0 } },
"conflicts": []
},
{ "reference": "X-9", "status": "rejected", "error": "telefone_invalido", "changes": { … }, "conflicts": [] }
]
}
PUT /api/contracts/{referencia}: un contrato
El cuerpo es el contrato, y reference puede omitirse. La respuesta es un único resultado:
201cuando se crea;200cuando se actualiza o no cambia;422cuando se rechaza.
Un contrato rechazado, o con conflictos, también aparece en el historial del panel.
GET /api/contracts/{referencia}: estado actual
Devuelve el comprador, cada cuota con su status (open, settled o cancelled), el paidMinor,
si hay un código de pago emitido (chargeIssued) y el saldo del contrato. Úselo para verificar qué
tiene Finpass antes o después de una sincronización.
GET /api/sync/runs/{runId}: una sincronización pasada
Devuelve los totales de la sincronización y el resultado de cada contrato.
Códigos de error y de conflicto
| Código | Significado |
|---|---|
referencia_obrigatoria |
El contrato llegó sin referencia. |
moeda_nao_suportada |
Moneda no admitida. |
telefone_invalido |
Teléfono del comprador ausente o inválido. |
email_invalido |
Correo del comprador mal formado. |
parcelas_obrigatorias |
El contrato llegó sin cuotas. |
parcelas_demais |
Más de 600 cuotas. |
numero_de_parcela_invalido |
seq debe ser un entero positivo. |
parcela_repetida:N |
El seq N aparece dos veces. |
vencimento_invalido:N |
Vencimiento inválido en la cuota N. |
valor_invalido:N |
Importe inválido en la cuota N. |
contrato_nao_esta_ativo |
El contrato fue rescindido en Finpass. |
moeda_do_contrato_nao_muda |
La moneda es distinta de la del contrato existente. |
contrato_distratado_nao_e_importado |
Un contrato nuevo llegó ya rescindido. |
distrato_deve_ser_feito_no_painel (conflicto) |
Haga la rescisión en el panel. |
parcela_paga_nao_muda (conflicto) |
La cuota está pagada. |
parcela_com_pagamento_parcial (conflicto) |
La cuota recibió un pago parcial. |
parcela_com_cobranca_em_aberto (conflicto) |
Hay un código de pago emitido. Reintente cuando se pague o venza. |
parcela_com_pagamento_nao_pode_ser_cancelada (conflicto) |
La cuota ya recibió dinero. |
parcela_cancelada_nao_volta (conflicto) |
Una cuota cancelada no se reabre. |
telefone_ja_pertence_a_outro_comprador (conflicto) |
El teléfono nuevo pertenece a otro comprador. |
Sin integración técnica
La pantalla Importar carteira (Importar cartera) del panel acepta una planilla con una fila por contrato. Sigue las mismas reglas: reimportar actualiza lo que cambió y nunca duplica. Columnas aceptadas:
- contrato:
contratooreferencia; - comprador:
compradoronome,telefoneowhatsapp,documento,cpfoci,email; - propiedad:
imovelolote; - importes y fechas:
moeda,valor,parcelas,primeiro_vencimento.
Avisos (webhooks): Finpass le avisa a su sistema
Configúrelos en el panel, en Integração → Avisos para o sistema de vocês (Avisos para su sistema):
- Registre la dirección HTTPS.
- Genere el secreto de la firma. Se muestra una sola vez.
- Envíe un aviso de prueba.
Eventos
| Evento | Cuándo |
|---|---|
payment.confirmed |
La cuota se pagó por completo. El banco lo confirmó, o una persona vinculó el pago en la cola de excepciones. |
payment.partial |
Entró dinero, pero la cuota sigue abierta. |
exception.created |
Llegó dinero que Finpass no concilia solo: pagador o referencia desconocidos, importe incorrecto u otra moneda. |
installment.overdue |
La cuota pasó su vencimiento y sigue abierta. Un aviso por cuota. |
buyer.reminders_opted_out / buyer.reminders_opted_in |
El comprador respondió BAJA o RECORDATORIOS. |
contract.terminated |
El contrato fue rescindido en el panel, con los importes pagado, retenido y a devolver. |
ping |
El botón de prueba. |
Formato del aviso
{
"id": "6f1c…",
"type": "payment.confirmed",
"createdAt": "2026-11-24T14:32:05.120Z",
"data": {
"contract": { "id": "…", "reference": "LOTE-12-QD-7" },
"installment": { "seq": 1, "amountMinor": 920000, "currency": "PYG", "dueDate": "2026-11-24",
"status": "settled", "paidMinor": 920000 },
"payment": { "amountMinor": 920000, "currency": "PYG", "confirmedBy": "manual",
"payerName": "MARIA BENITEZ", "bankTransactionId": "…",
"receiptUrl": "https://…/v/…" },
"buyer": { "name": "María Benítez", "phone": "595981234567", "document": "4.567.890" }
}
}
Cuando el pago se hizo en otra moneda, payment también trae
"original": { "amountMinor": 70000, "currency": "BRL", "rate": "1314" }. En el ejemplo se pagaron
R$ 700,00 a una tasa declarada de 1 BRL = 1.314 PYG, contra una cuota en guaraníes.
Los importes vienen siempre como enteros en la unidad mínima de la moneda (amountMinor): en PYG la
unidad mínima es el propio guaraní; en BRL, 245000 son R$ 2.450,00.
Encabezados
Finpass-Event: el tipo de evento.Finpass-Delivery: el id del evento. Es el mismo en cada reintento; úselo para ignorar duplicados.Finpass-Signature:t=<segundos unix>,v1=<hex>.
Cómo verificar la firma
Calcule HMAC-SHA256(secreto, "<t>." + cuerpo_crudo) en hexadecimal y compárelo con v1 usando una
comparación de tiempo constante. Rechace el aviso si t tiene más de 5 minutos.
const [t, v1] = header.split(',').map((p) => p.split('=')[1])
const expected = crypto.createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex')
const valid = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1))
&& Math.abs(Date.now() / 1000 - Number(t)) < 300
Entrega
- Cualquier respuesta
2xxcuenta como entregada. Responda rápido y haga el trabajo después. - Los pagos confirmados por el banco salen en segundos. El resto sale en hasta 5 minutos.
- Los fallos se reintentan después de 2, 4, 8, 16, 32, 64 y 128 minutos. Tras el 8º intento, el aviso queda como "Desistiu" (abandonado).
- Cada aviso, su estado y el último código de respuesta aparecen en el panel. Cualquier aviso no entregado puede reenviarse con un clic.
- Los avisos solo se registran mientras haya una dirección configurada.
Exportación de cobros (consulta)
GET /api/payments?from=AAAA-MM-DD&to=AAAA-MM-DD
Lista cada pago acreditado en el período, con ambas fechas incluidas. Cada ítem trae:
- la referencia del contrato y la cuota;
- el importe y, cuando es distinta, la moneda original;
- el nombre del pagador y el id de la transacción en el banco;
- el enlace del comprobante;
- el comprador.
Úselo si prefiere consultar en lugar de recibir avisos, o para conciliar una vez al día.
El panel tiene los mismos datos en planilla: Integração → Exportar recebimentos (Exportar
cobros). El archivo usa ; como separador, coma decimal para inmobiliarias en portugués y español, y
un BOM para que Excel lea bien los acentos.