Quem é dono de quê. O sistema da imobiliária é a fonte da verdade do contrato: comprador, imóvel, valores e vencimentos. O Finpass é a fonte da verdade do pagamento: códigos de pagamento, confirmação do banco, conciliação, recibos e a trilha de evidências. O Finpass nunca vira o sistema de gestão da imobiliária.
Autenticação
Cada imobiliária tem uma chave de API. O responsável gera a chave no painel, em Integração → Gerar nova chave. A chave aparece uma única vez, e gerar uma nova desliga a anterior.
Authorization: Bearer fp_…
Content-Type: application/json
As regras da sincronização
As mesmas regras valem para a API e para a importação por planilha.
A chave de ligação é a referência do contrato no sistema da imobiliária (única por imobiliária), mais o número da parcela (
seq) dentro do contrato. Enviar o mesmo contrato de novo nunca duplica nada.Criar ou atualizar. Referência desconhecida cria o contrato. Referência conhecida atualiza o comprador, a descrição do imóvel e as parcelas que mudaram.
Parcela omitida fica como está. Nada é apagado porque faltou no envio. Para cancelar uma parcela, envie-a com
"status": "cancelled".Dinheiro em andamento fica protegido. Estas mudanças não são aplicadas; voltam como
conflictpara uma pessoa resolver no painel:- valor novo em parcela paga, paga em parte ou com código de pagamento emitido;
- cancelamento de parcela que já recebeu dinheiro;
- reabertura de parcela cancelada.
Mudar só o vencimento é aplicado, desde que o valor continue o mesmo.
Distrato não é sincronizado. Enviar
"status": "terminated"devolve um conflito. O distrato é feito no painel, porque calcula a devolução.A moeda do contrato nunca muda depois que o contrato é criado.
Telefone novo do comprador vale para os próximos lembretes. Se o número novo já pertencer a outro comprador da mesma imobiliária, o número antigo é mantido e um conflito é devolvido.
Formato do contrato
{
"reference": "LOTE-12-QD-7",
"status": "active",
"propertyLabel": "Quadra 7, lote 12",
"currency": "BRL",
"buyer": {
"name": "Maria Souza",
"phone": "64211234567",
"document": "123.456.789-00",
"email": "maria@exemplo.com"
},
"installments": [
{ "seq": 1, "amount": "2450.00", "dueDate": "2026-11-10" },
{ "seq": 2, "amount": "2450.00", "dueDate": "2026-12-10" },
{ "seq": 3, "amount": "2450.00", "dueDate": "2027-01-10", "status": "cancelled" }
]
}
| Campo | Regra |
|---|---|
reference |
Obrigatório, até 120 caracteres. |
currency |
ISO 4217, por exemplo BRL, PYG, USD, EUR, NZD. |
buyer.phone |
Dígitos com o código do país (DDI). +, espaços e traços são ignorados. |
installments[].amount |
Texto decimal com ponto ("2450.00"). PYG não tem casas decimais ("920000"). |
installments[].dueDate |
AAAA-MM-DD. |
installments[].status |
open (padrão) ou cancelled. |
Um contrato que falha na validação é recusado inteiro, e nada é gravado.
Os nomes dos campos, os valores de status e os códigos de erro são sempre os mesmos, em qualquer
idioma.
Endereços
POST /api/sync/contracts: lote
Até 200 contratos por chamada. Cada contrato é tratado sozinho, e o lote inteiro fica registrado como uma sincronização, visível no painel em Integração.
{ "contracts": [ { …contrato… }, { …contrato… } ] }
Resposta 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/{referência}: um contrato
O corpo é o contrato, e reference pode ser omitida. A resposta é um único resultado:
201quando criado;200quando atualizado ou sem mudança;422quando recusado.
Contrato recusado, ou com conflito, também aparece no histórico do painel.
GET /api/contracts/{referência}: estado atual
Devolve o comprador, cada parcela com seu status (open, settled ou cancelled), o paidMinor,
se há código de pagamento emitido (chargeIssued) e o saldo do contrato. Use para conferir o que o
Finpass tem antes ou depois de uma sincronização.
GET /api/sync/runs/{runId}: uma sincronização passada
Devolve os totais da sincronização e o resultado de cada contrato.
Códigos de erro e de conflito
| Código | Significado |
|---|---|
referencia_obrigatoria |
O contrato veio sem referência. |
moeda_nao_suportada |
Moeda não suportada. |
telefone_invalido |
Telefone do comprador ausente ou inválido. |
email_invalido |
E-mail do comprador mal formado. |
parcelas_obrigatorias |
O contrato veio sem parcelas. |
parcelas_demais |
Mais de 600 parcelas. |
numero_de_parcela_invalido |
seq precisa ser um inteiro positivo. |
parcela_repetida:N |
O seq N aparece duas vezes. |
vencimento_invalido:N |
Vencimento inválido na parcela N. |
valor_invalido:N |
Valor inválido na parcela N. |
contrato_nao_esta_ativo |
O contrato foi distratado no Finpass. |
moeda_do_contrato_nao_muda |
A moeda é diferente da do contrato existente. |
contrato_distratado_nao_e_importado |
Um contrato novo chegou já distratado. |
distrato_deve_ser_feito_no_painel (conflito) |
Faça o distrato no painel. |
parcela_paga_nao_muda (conflito) |
A parcela está paga. |
parcela_com_pagamento_parcial (conflito) |
A parcela recebeu um pagamento parcial. |
parcela_com_cobranca_em_aberto (conflito) |
Há um código de pagamento emitido. Tente de novo quando ele for pago ou expirar. |
parcela_com_pagamento_nao_pode_ser_cancelada (conflito) |
A parcela já recebeu dinheiro. |
parcela_cancelada_nao_volta (conflito) |
Parcela cancelada não é reaberta. |
telefone_ja_pertence_a_outro_comprador (conflito) |
O telefone novo pertence a outro comprador. |
Sem integração técnica
A tela Importar carteira do painel aceita uma planilha com uma linha por contrato. Ela segue as mesmas regras: reimportar atualiza o que mudou e nunca duplica. Colunas aceitas:
- contrato:
contratooureferencia; - comprador:
compradorounome,telefoneouwhatsapp,documento,cpfouci,email; - imóvel:
imoveloulote; - valores e datas:
moeda,valor,parcelas,primeiro_vencimento.
Avisos (webhooks): o Finpass avisa o seu sistema
Configure no painel, em Integração → Avisos para o sistema de vocês:
- Cadastre o endereço HTTPS.
- Gere o segredo da assinatura. Ele aparece uma única vez.
- Envie um aviso de teste.
Eventos
| Evento | Quando |
|---|---|
payment.confirmed |
A parcela foi paga por inteiro. O banco confirmou, ou uma pessoa vinculou o pagamento na fila de exceções. |
payment.partial |
Entrou dinheiro, mas a parcela continua em aberto. |
exception.created |
Chegou dinheiro que o Finpass não concilia sozinho: pagador ou referência desconhecidos, valor errado ou outra moeda. |
installment.overdue |
A parcela passou do vencimento e continua em aberto. Um aviso por parcela. |
buyer.reminders_opted_out / buyer.reminders_opted_in |
O comprador respondeu PARAR ou LEMBRETES. |
contract.terminated |
O contrato foi distratado no painel, com os valores pago, retido e a devolver. |
ping |
O botão de teste. |
Formato do aviso
{
"id": "6f1c…",
"type": "payment.confirmed",
"createdAt": "2026-10-10T14:32:05.120Z",
"data": {
"contract": { "id": "…", "reference": "LOTE-12-QD-7" },
"installment": { "seq": 37, "amountMinor": 245000, "currency": "BRL", "dueDate": "2026-10-10",
"status": "settled", "paidMinor": 245000 },
"payment": { "amountMinor": 245000, "currency": "BRL", "confirmedBy": "bank",
"payerName": "MARIA SOUZA", "bankTransactionId": "E1234…",
"receiptUrl": "https://…/v/…" },
"buyer": { "name": "Maria Souza", "phone": "64211234567", "document": "123.456.789-00" }
}
}
Quando o pagamento foi feito em outra moeda, payment também traz
"original": { "amountMinor": 70000, "currency": "BRL", "rate": "1314" }. No exemplo, R$ 700,00
foram pagos a uma taxa declarada de 1 BRL = 1.314 PYG, contra uma parcela em guaranis.
Valores vêm sempre em inteiros na menor unidade da moeda (amountMinor): 245000 em BRL são
R$ 2.450,00; em PYG, a menor unidade é o próprio guarani.
Cabeçalhos
Finpass-Event: o tipo do evento.Finpass-Delivery: o id do evento. É o mesmo em toda nova tentativa; use-o para ignorar duplicados.Finpass-Signature:t=<segundos unix>,v1=<hex>.
Como conferir a assinatura
Calcule HMAC-SHA256(segredo, "<t>." + corpo_bruto) em hexadecimal e compare com v1 usando uma
comparação de tempo constante. Recuse o aviso se t tiver mais 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
- Qualquer resposta
2xxconta como entregue. Responda rápido e faça o trabalho depois. - Pagamentos confirmados pelo banco saem em segundos. O resto sai em até 5 minutos.
- Falhas são tentadas de novo depois de 2, 4, 8, 16, 32, 64 e 128 minutos. Depois da 8ª tentativa, o aviso fica como "Desistiu".
- Cada aviso, sua situação e o último código de resposta aparecem no painel. Qualquer aviso não entregue pode ser reenviado com um clique.
- Avisos só são registrados enquanto houver um endereço configurado.
Exportação de recebimentos (consulta)
GET /api/payments?from=AAAA-MM-DD&to=AAAA-MM-DD
Lista cada pagamento creditado no período, com as duas datas incluídas. Cada item traz:
- a referência do contrato e a parcela;
- o valor e, quando for diferente, a moeda original;
- o nome do pagador e o id da transação no banco;
- o link do comprovante;
- o comprador.
Use se preferir buscar a receber avisos, ou para conciliar uma vez por dia.
O painel tem os mesmos dados em planilha: Integração → Exportar recebimentos. O arquivo usa ;
como separador, vírgula decimal para imobiliárias em português e espanhol, e um BOM para o Excel ler
os acentos certos.