Skip to content

Gateway Bancário Real (Fiducia) — Sandbox e Produção

App\Models\Banks\Fiducia (fastgivr-api) é o adapter real de BankInterface — a alternativa ao gateway Teste (mock 100% local, sem rede). Contrato de referência: API_de_Contas_-_Integracao.postman_collection.json (~150 endpoints; a Fiducia SCM é o único provedor de "conta bancária real" documentado neste repositório).

Status: implementado e não testado contra o ambiente real — a coleção Postman não tem nenhum exemplo de resposta salvo para os endpoints usados aqui, só os payloads de requisição. Ver Antes de ligar em produção antes de habilitar contra dinheiro de verdade, e o Plano de Execução para as fases e critérios de saída até chegar lá.

Os dois modos

Mesma classe, mesmo código — só muda a base URL. Controlado por FIDUCIA_MODE (config('banks.fiducia.mode')):

ModoBase URLO que significa
sandbox (padrão)FIDUCIA_SANDBOX_BASE_URLhttps://api.contashoml.fiduciascm.digital:8609Ambiente de homologação real do provedor. Chamadas de rede de verdade, contra a infraestrutura da Fiducia, mas sem movimentar dinheiro real. É o ambiente descrito na coleção Postman.
productionFIDUCIA_PRODUCTION_BASE_URL (vazia por padrão)Dinheiro real. Fiducia::baseUrl() recusa iniciar se FIDUCIA_MODE=production e essa variável estiver vazia — para nunca cair em produção por omissão de configuração.

Não confundir com BANK_SANDBOX (config('banks.sandbox')): essa outra flag já existia e decide se o cadastro (/access/register/submit) é aprovado automaticamente ou fica UNDER_REVIEW. É ortogonal ao modo do gateway — uma conta pode estar em BANK_SANDBOX=true (aprovação automática) e mesmo assim operar contra FIDUCIA_MODE=production, ou vice-versa. Também não confundir com gateways/bank_gateway: uma conta só usa o adapter Fiducia (sandbox ou produção) se accounts.bank_gateway = 'Fiducia' — o padrão do produto continua sendo Teste.

Duas credenciais, dois lugares

CredencialOnde ficaUso
SistêmicaFIDUCIA_CLIENT_ID / FIDUCIA_CLIENT_SECRET.env (config/banks.php)POST /auth/token — reservada para operações administrativas (gestão de contas/credenciais). Não usada pelo adapter hojeBankInterface não cobre onboarding de conta na Fiducia, só operação de contas já existentes. Guardada para quando esse escopo for implementado.
Por conta — login (cpfcnpj/conta/password/cod_operador)accounts.document + accounts.account (já existiam) + accounts.bank_login_password + accounts.bank_operator_code (novas, criptografadas — cast encrypted no Eloquent)POST /login — autentica como aquela conta. Todo Pix/boleto/transferência é feito com esse bearer.

O bearer obtido no login é cacheado em accounts.token / accounts.token_expires (colunas que já existiam, pensadas exatamente para isso — só não eram usadas por nenhum gateway real ainda). Fiducia::getAccessToken() só chama /login de novo quando token_expires expira — "cálculo de tempo de sessão". token foi ampliado de VARCHAR(255) para TEXT (JWT real não cabe em 255 caracteres) na migration 2026_09_09_000001_add_fiducia_credentials_to_accounts_table.

accounts.bank_login_password / bank_operator_code estão em Account::$hidden — nunca saem em toArray()/toJson()/respostas de API.

Antes de operar uma conta em modo Fiducia, alguém precisa gravar o login daquela conta especificamente:

php
$account->forceFill([
    'bank_gateway' => 'Fiducia',
    'bank_login_password' => '...',   // senha de login da Fiducia (não a senha transacional)
    'bank_operator_code' => '...',    // cod_operador
])->save();

A senha transacional (transational_password nos payloads da Fiducia — confirmação por PIN de cada operação que move dinheiro) reaproveita o campo que já existe: accounts.pin.

Mapeamento método → endpoint

Todo método de BankInterface implementado por Fiducia, mais os métodos extra que o app chama via Account::getBank()->...() sem passar pela interface (Pix in/out, gestão de chave, etc. — mesmo padrão que Teste já cobre). "Confirmado" = testado contra o ambiente real; hoje nenhum está.

Método PHPEndpoint FiduciaConfirmado?
getAccessToken()POST /loginRequisição sim, resposta não
createPixDinamico()POST /pix/qrcode/dinamico/imediato/gerarRequisição sim, resposta não
createPixComVencimento()POST /pix/qrcode/dinamico/vencimento/gerarRequisição sim, resposta não
getPixCharge($location)GET direto na URL da location (fora da API Fiducia — por especificação do Pix)Sim (spec BCB)
getPixTransactionDetails()GET /pix/dict/gestao-chave/{chave}/oculto⚠️ Melhor palpite — ver nota abaixo
makePixTransfer() / makePixTransferBank()POST /pix/spi/transferirRequisição sim, resposta não; tipo_iniciacao/tipo_chave não documentados (ver nota)
getPixRefundReasons()GET /pix/spi/devolver/motivosRequisição sim, resposta não
refundPix()POST /pix/spi/devolverRequisição sim, resposta não
createPixKey() / deletePixKey() / listPixKeys()POST /pix/dict/gestao-chave/incluir, DELETE .../excluir, GET .../listarRequisição sim, resposta não
claimPixKey() / confirmPixKeyClaim() / cancelPixKeyClaim() / listPixKeyClaims().../reivindicacao/incluir|:id/confirmar|:id/cancelar|listarRequisição sim, resposta não
makeBoleto()POST /boleto (Gerar boleto de cobrança)Requisição sim, resposta não
makeBoletoDeposito()POST /boleto/depositoRequisição sim, resposta não
fetchBoleto()GET /boleto/{nossoNumero}Requisição sim, resposta não
consultarBoleto() / getBoletoDetails()POST /pagamentos/autorizar (consulta sem debitar)Requisição sim, resposta não
pagarBoleto() / payBoleto()POST /pagamentos/autorizar (se faltar transactionIdAuthorize) + POST /pagamentos/efetivarRequisição sim, resposta não
consultarComprovante()GET /pagamentos/consultar/{id}Requisição sim, resposta não
cancelarAgendamento()DELETE /pagamentos/pendente/{id}Requisição sim, resposta não
makeBankTransfer()POST /transferenciaRequisição sim, resposta não
getBankTransferStatus() / cancelBankTransfer()GET/DELETE /transferencia/agendada/{numCtrlIF}⚠️ Só cobre transferência agendada — ver lacuna abaixo
printBoletoPdf()Sem endpoint na coleção; devolve null (fallback já esperado pelos chamadores)
consultarBoletosDDA()Sem endpoint na coleção; devolve []
endWithdraw()Sem endpoint na coleção nem uso real no app hoje; lança BankException em vez de simular sucesso

⚠️ Lacunas e suposições conhecidas

A coleção Postman documenta requisição, não resposta — nenhum dos ~150 endpoints tem exemplo de resposta salvo. Tudo abaixo precisa ser validado contra chamadas reais no sandbox de homologação antes de qualquer uso em produção (o código já marca cada ponto com // RESPOSTA NÃO CONFIRMADA):

  1. Nomes de campo na respostaFiducia lê a resposta com fallback ($response->json('token') ?? $response->json('access_token') ?? ...), mas são palpites. Se a Fiducia usar um nome de campo fora dessas variantes, o método falha com "resposta sem token reconhecível" em vez de silenciosamente aceitar dado errado — intencional, mas precisa ser corrigido assim que a resposta real for vista.
  2. Códigos de tipo_chave / tipo_iniciacao do Pix — a coleção usa tipo_chave: 3 (Transferir Pix) e tipo_chave: 4 (Incluir chave no DICT) sem tabela de referência. Fiducia::identifyPixKeyType() / pixKeyTypeCode() assumem a ordem mais comum entre provedores DICT (CPF/CNPJ=0, telefone=1, e-mail=2, aleatória=3) — pode estar errado. Confirmar com o suporte da Fiducia ou por tentativa no sandbox.
  3. Status de transferência instantânea — a coleção só expõe GET /transferencia/agendada/:numCtrlIF (transferências agendadas). Não há endpoint de status para uma transferência instantânea já efetivada; a fonte da verdade seria o extrato (GET /conta/extrato/...), fora do escopo de BankInterface hoje.
  4. DDA e segunda via de boleto em PDF — sem endpoint correspondente na coleção. Degradam para []/null (mesmo contrato que os chamadores já esperam do gateway Teste para casos não suportados), não erro 500.
  5. getPixTransactionDetails() — mapeado para "Consultar chave" (/pix/dict/gestao-chave/:chave/oculto), que fica na pasta de gestão das próprias chaves da conta. Não está confirmado que esse endpoint também resolve chaves de terceiros (necessário para mostrar o nome do destinatário antes de um Pix out) — pode ser preciso outro endpoint do DICT que não foi identificado na coleção.

Antes de ligar em produção (checklist)

  • [ ] Validar cada linha "Requisição sim, resposta não" da tabela acima contra o sandbox real da Fiducia; ajustar o parsing de resposta em App\Models\Banks\Fiducia conforme os nomes de campo reais.
  • [ ] Confirmar a tabela de tipo_chave/tipo_iniciacao do Pix com a Fiducia.
  • [ ] Resolver a lacuna de status de transferência instantânea (item 3 acima) antes de expor getBankTransferStatus() para transferências não agendadas.
  • [ ] Preencher FIDUCIA_PRODUCTION_BASE_URL só quando a conta de produção estiver liberada — o adapter recusa iniciar em production sem essa URL.
  • [ ] Nunca reusar credenciais de sandbox (bank_login_password/ bank_operator_code/client_secret) em contas de produção nem vice-versa.
  • [ ] Migrar a coluna accounts.bank_login_password com um plano de rotação de senha — se a senha de login da Fiducia mudar (ex.: exigência de troca periódica do provedor), o app precisa de um fluxo para atualizá-la sem downtime.

Ver também

FastGivr API Documentation