Finpass Agendar una demo

DesarrolladoresAPI de integración

Conecte el sistema de su inmobiliaria a Finpass.

Su ERP o CRM sigue siendo la fuente de la verdad del contrato; Finpass es dueño del pago. Dos sentidos, un solo conjunto de reglas:

  • Entrada: cree o actualice contratos y compradores por su propia referencia, en lotes de hasta 200. Reenviar nunca duplica.
  • Vuelta: avisos firmados (webhooks) de pagos confirmados y parciales, excepciones, cuotas vencidas, compradores que apagan los recordatorios y rescisiones.
  • Consulta: liste los pagos de cualquier período, con el enlace del comprobante, para conciliar cada día.

La dirección base y su clave de API vienen con la puesta en marcha de la inmobiliaria — la clave la genera el responsable en el panel, en Integração (Integración).

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.

  1. 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.

  2. 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.

  3. Una cuota omitida queda como está. Nada se borra porque faltó en el envío. Para cancelar una cuota, envíela con "status": "cancelled".

  4. El dinero en curso está protegido. Estos cambios no se aplican; vuelven como conflict para 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.

  5. 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.

  6. La moneda del contrato nunca cambia después de creado el contrato.

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

  • 201 cuando se crea;
  • 200 cuando se actualiza o no cambia;
  • 422 cuando 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: contrato o referencia;
  • comprador: comprador o nome, telefone o whatsapp, documento, cpf o ci, email;
  • propiedad: imovel o lote;
  • 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):

  1. Registre la dirección HTTPS.
  2. Genere el secreto de la firma. Se muestra una sola vez.
  3. 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 2xx cuenta 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.

FinpassEmpiece ahora

Lleve a sus compradores del exterior a una sola conversación.

Finpass está en producción. Cuéntenos sobre sus contratos y le mostramos cómo funciona con su banco.

  • Con sus propios contratos. La conversación del comprador, el panel y cómo se conecta su banco.
  • En su idioma. Inglés, portugués o español.
  • El comprador nunca paga. La inmobiliaria se suscribe por contratos activos.