Como a Malvo conecta
O usuário autoriza o compartilhamento no banco, por uma jornada OAuth/redirect, sem fornecer credenciais bancárias à sua aplicação.A integração é exclusivamente de dados. A Malvo não expõe PIS, iniciação de pagamentos,
Pix, boletos ou transferências, mesmo quando uma API upstream possui operações de pagamento.
supportsPaymentInitiation permanece sempre false.Cobertura internacional
A configuração aceita estas 31 jurisdições ISO-3166-1 alpha-2:GB, não UK.
O fluxo de redirecionamento e consentimento
Em conectores de Open Finance, o usuário não digita a senha do banco na sua aplicação — ele é redirecionado ao banco para autenticar e autorizar o consentimento.1
Crie o Item informando o redirect
POST /items com connectorId e oauthRedirectUri. No Brasil, envie os parameters
pedidos pelo conector, normalmente cpf ou cnpj. Em conectores internacionais,
parameters normalmente é {}; se connector.credentials anunciar o select
authMethod, envie somente uma opção declarada. Isso seleciona a jornada, não
coleta credenciais bancárias. Informe um clientUserId estável para correlacionar o usuário
e evitar duplicatas. A resposta carrega a URL de autorização em connector.oauthUrl.2
O usuário autoriza no banco
O usuário abre a URL, autentica no banco e autoriza o consentimento. Enquanto isso, o Item
usa
status=LOGIN_IN_PROGRESS e executionStatus=USER_AUTHORIZATION_PENDING.3
Retorno via oauthRedirectUri
Concluída a autorização, o provedor retorna ao callback da Malvo. A Malvo valida
state,
troca o código por consentimento/sessão e redireciona para o seu oauthRedirectUri,
acrescentando itemId e status (e message em erro). A coleta continua de forma
assíncrona até UPDATED.Semântica dos dados no Brasil
As regras abaixo são específicas do Open Finance Brasil e não devem ser aplicadas automaticamente a conectores internacionais.Histórico e atualizações incrementais
- Sincronização inicial: até 365 dias de histórico.
- Toda sincronização: avalia também
transactions-current, que cobre aproximadamente os últimos 7 dias, enquanto houver capacidade diária na rota e no recurso. - Reconciliação histórica: o histórico completo possui uma cota própria e restrita; ele é carregado inicialmente e reconciliado segundo sua cadência, sem substituir a janela recente.
- A profundidade do histórico de transações dos meios de pagamento (PIX, TED, DOC, TEF, Boleto) varia de 3 a 24 meses por instituição e por rail.
Retry e indisponibilidade temporária
Algumas instituições deixam uma API ou uma família inteira do Open Finance indisponível temporariamente. Para evitar concluir uma importação incompleta por causa de uma oscilação curta, a Malvo aplica a seguinte política:- Falhas de transporte/rede e respostas
5xxrecebem até 3 tentativas no total, com 10 segundos entre elas, na mesma execução. - A propagação de um consentimento recém-autorizado, durante a criação do token OPF ou a descoberta de recursos, também recebe até 3 tentativas no total, com 10 segundos entre elas.
- Cada tentativa física conta no consumo da rota. Se a capacidade diária ou mensal terminar antes da terceira tentativa, a Malvo respeita o lock e não o ultrapassa.
- Se uma rota esgotar as três tentativas, os recursos irmãos dessa mesma rota usam o último valor persistido durante o restante da execução, evitando repetir a indisponibilidade para cada conta.
429,423do HOLDER, cota mensal, erros permanentes4xxe cancelamento não usam esse retry curto; cada um segue sua janela de recuperação específica.
LOGIN_IN_PROGRESS / USER_AUTHORIZATION_PENDING, sem ser tratado como revogado, e fica elegível
para a recuperação assíncrona.
Se as três tentativas transitórias falharem apenas para parte dos dados, os dados válidos já
importados são preservados e a execução termina em PARTIAL_SUCCESS, com
PROVIDER_TEMPORARILY_UNAVAILABLE na família afetada. Essa execução parcial dispara
item/updated depois de persistir os dados válidos; leia statusDetail para identificar o que
ficou incompleto. Uma execução posterior que concluir as famílias restantes dispara um novo
item/updated.
Limite de recursos por conta
Transações pendentes de conta-corrente permanecemPENDING enquanto processam; valores bloqueados acumulam no blockedBalance da conta.
Em contas bancárias, balance representa o saldo disponível consolidado (incluindo aplicação automática quando informada), enquanto bankData.closingBalance representa o saldo contábil total: disponível mais bloqueado. O valor bloqueado também é exposto separadamente em bankData.blockedBalance e em GET /accounts/{id}/balance; automaticallyInvestedAmount já é consolidado pela especificação Open Finance e não é somado novamente.
Particularidades de cartão de crédito
Faturas e billId
Faturas e billId
Atualizações diárias de transações; os detalhes completos só ficam disponíveis após o fechamento da fatura. Faturas abertas só aparecem quando fechadas ou vencidas. O
billId de uma transação só é atribuído quando a fatura já existe na instituição. Algumas transações aparecem apenas na listagem de faturas, nunca no stream de transações.Parcelas futuras
Parcelas futuras
A maioria das instituições retorna apenas a primeira parcela de compras futuras nas atualizações diárias. BTG Pactual (connector 614) retorna todas as parcelas futuras como
PENDING já na primeira conexão. XP Banking (connector 602) retorna o valor total da compra em vez das parcelas individuais.Particularidades de investimentos
- A sincronização inicial retorna apenas investimentos ativos; os resgatados aparecem depois com status
TOTAL_WITHDRAWAL. - Notas de corretagem não são expostas.
- “Caixinhas” (Nubank) e “Cofrinhos” (PicPay) aparecem como investimentos CDB. Transações de investimentos via Open Finance não são suportadas de forma transversal entre instituições.
Dados de contraparte (paymentData)
Os dados da contraparte de uma transação nem sempre existem. Normalmente faltam em: tarifas da instituição, portabilidade de salário, resgates de investimento, TED/PIX/Boleto em lote, depósitos abaixo de R$ 2.000 e transações de cartão de débito/pré-pago.Semântica dos dados internacionais
- Produtos: somente
ACCOUNTSeTRANSACTIONS; os saldos são normalizados no objeto Account. - Primeira sincronização e reconsentimento: a Malvo solicita o maior histórico disponível. O período efetivamente devolvido depende do ASPSP e não possui garantia única para os 31 países.
- Sincronizações incrementais: a Malvo busca desde
lastUpdatedAtcom sobreposição de 90 dias, para reconciliar lançamentos tardios ou alterados. A cada 30 dias tenta novamente o histórico completo nos ASPSPs compatíveis; quando a janela máxima não é suportada, preservaHISTORY_LIMITEDe mantém a maior janela aceita sem repetir a estratégia incompatível. - Paginação: o cursor é opaco. A Malvo continua paginando enquanto houver uma próxima chave, inclusive quando uma página intermediária vier vazia.
- Identidade da conta: os identificadores estáveis publicados pelo provedor são usados para preservar o mesmo Account após uma nova sessão ou reconsentimento.
- Disponibilidade: consentimento, tipos de usuário pessoal/empresarial, validade máxima, filtros e profundidade de histórico variam por ASPSP.
PARTIAL_SUCCESS. Nesse caso, dados
válidos são preservados, o cursor global não avança e uma execução posterior tenta completar a
janela pendente.
Por que webhooks são a fonte da verdade
O estado de uma conexão é assíncrono: o consentimento depende do usuário no banco e o auto-sync roda em segundo plano. Por isso, a Malvo emite webhooks próprios a cada transição relevante — e eles, não oonSuccess do widget, são a fonte autoritativa do estado.
No fluxo internacional, a Malvo detecta alterações, expiração e revogação consultando a sessão
e os endpoints de dados por scheduler ou refresh manual; os
webhooks recebidos pela sua aplicação são gerados pela Malvo após a persistência local.
1
Registre um webhook na configuração da aplicação
Inscreva um endpoint HTTPS no evento
all e roteie internamente.2
Em qualquer evento item/*, re-busque o recurso canônico
Nunca confie apenas no payload: chame
GET /items/{itemId} (status, error, consentExpiresAt) e depois GET /accounts?itemId=....3
Em transactions/created e transactions/updated
Liste as contas do
itemId, pagine GET /v2/transactions?accountId=... para cada uma e faça
upsert por id da transação. Em transactions/deleted, exclua localmente pelos ids
informados.4
Em item/error e item/waiting_user_input
Marque o Item como “precisa de ação” e direcione o usuário de volta ao Connect Widget em modo de atualização.
As entregas de webhook não têm ordem garantida e podem ser reenviadas. Cada entrega carrega um
eventId (UUID) que é reutilizado em todos os reenvios e em todos os endpoints inscritos — persista o eventId e trate duplicatas como no-op. Mesmo com webhooks, mantenha um job noturno de reconciliação que re-busca itens e transações para cobrir janelas de indisponibilidade.Próximos passos
Consents
Ciclo de vida, renovação no mesmo Item e limites mensais da rede.
Items
Máquina de estados e caminhos de recuperação da conexão.