Pagamento por Boleto (bolix EFI)

A partir da Loja 1.1 (em conjunto com o FUJI 4.24), vendas com a forma de pagamento EfiPay - Boleto emitem um boleto com QR Pix (bolix) na hora. A venda passa a Pago automaticamente quando o aluno paga, e todos os gestores conectados recebem o aviso em tempo real.

Para o gestor

Pré-requisitos

  • EfiPay habilitada e com uma carteira ativa nas configurações do FUJI (ver Carteiras EFI). A Loja não guarda credenciais: ela usa a conta da academia configurada no FUJI.

  • Em Configurações da Loja, a seção EfiPay aparece quando o FUJI informa que a EFI está configurada. Ela mostra a carteira em uso e o selo Sandbox quando a conta é de homologação.

  • O campo Vencimento do boleto (dias) define o prazo do boleto: de 1 a 30 dias, com padrão de 3.

Na venda

  1. Registre a venda com a forma de pagamento EfiPay - Boleto. Enquanto o boleto é registrado na EFI, a tela mostra um indicador com o aviso para não fechar a janela.

  2. A janela Pagamento via boleto mostra o QR Code Pix, a linha digitável (com botão Copiar), o valor, o vencimento, o link Abrir PDF do boleto e, no celular, o botão Compartilhar.

  3. Quando o aluno paga, a venda passa a Pago sozinha. Se a janela do boleto ainda estiver aberta, ela fecha automaticamente.

A entrega só deve ser feita depois da confirmação. A Loja não aceita marcar como Pago manualmente uma venda que tem boleto emitido: quem confirma é a EFI. Vendas EfiPay - Boleto anteriores à integração, que não têm boleto emitido, continuam com confirmação manual.

Cancelamento, vencimento e divergências

  • Cancelar a venda cancela o boleto. Se o boleto já estiver pago, o cancelamento é recusado.

  • Um boleto vencido sem pagamento, ou cancelado na EFI, cancela a venda que ainda não foi paga.

  • Se o aluno pagar o boleto de uma venda já cancelada, o pagamento é registrado, a venda continua Cancelada e a divergência é sinalizada para o gestor tratar o estorno.

Tempo real

A lista de pedidos e o detalhe da venda se atualizam sozinhos para todos os gestores do mesmo tenant com a Loja aberta, sem recarregar a página.

Detalhes técnicos

Fluxo

Emissão e confirmação de um boleto da loja
Figura 1. Emissão e confirmação de um boleto da loja

Responsabilidades

Componente Papel

fuji-loja

Diálogo do boleto, status na lista e no detalhe, e a seção EfiPay guiada por capacidades. Também assina o WebSocket /store/ws/pagamentos.

backend-store

Registra o pagamento da venda, pede a emissão ao principal com a referência externa venda-<id>, recebe o callback assinado em /internal/pagamentos/eventos e publica o evento aos gestores (ADR 0005 e ADR 0006 do repositório).

backend (app cobrancas)

Model Cobranca, desacoplado de Titulo. Emite o bolix pela carteira ativa e carimba efi_carteira. Recebe o webhook da EFI e notifica a origem com um job RQ que tem retry.

bff (gateway)

Expõe /v2/cobrancas/ à loja (JWT, role gestor-loja), roteia o WebSocket validando JWT e Origin, e mantém /internal/ fora do catálogo público.

API de cobranças (backend principal)

Endpoint Comportamento

GET /v2/cobrancas/capacidades/

{efi: {configurado, carteira_ativa_id, sandbox, bolix}}. configurado exige a EFI habilitada e uma carteira ativa.

POST /v2/cobrancas/

Emite o bolix. É idempotente por referencia_externa enquanto houver cobrança pendente ou paga (200 com a existente, 201 quando emite). Responde 422 sem EFI configurada ou com recusa do gateway, e 502 com o gateway indisponível.

GET /v2/cobrancas/ e /v2/cobrancas/<id>/

Consulta, com filtros origem, referencia_externa e status.

POST /v2/cobrancas/<id>/cancelar/

Cancela na EFI pela carteira carimbada. Responde 409 se a cobrança já estiver paga e é idempotente se ela já estiver encerrada.

Máquina de estados da cobrança

pendente → paga | cancelada | expirada. Estados terminais não reabrem, exceto pelo pagamento: dinheiro recebido prevalece sobre um cancelamento ou uma expiração local.

Callback para a loja

A cada status terminal, o principal faz POST em COBRANCAS_CALLBACK_LOJA_URL com o corpo JSON do evento. O evento_id (cobranca:<id>:<status>) é determinístico, e a loja deduplica por ele. A requisição leva os cabeçalhos X-Fuji-Timestamp e X-Fuji-Signature (HMAC-SHA256 de "<timestamp>.<corpo>"). Na loja, o segredo é PAGAMENTOS_CALLBACK_SECRET (igual a COBRANCAS_CALLBACK_SECRET do principal), com janela anti-replay. O que não foi entregue é reenviado pelo sync-efi-cobrancas, e as cobranças vencidas são encerradas pelo expirar-cobrancas (ambos CronJobs no gitops).

Timeout na emissão

Se a emissão estourar o timeout e a transação da venda for desfeita, a loja pede ao principal o descarte da cobrança por referência, para que o boleto não fique pagável. A referência venda-<id> é usada no lugar do código PED-NNNN porque o código sequencial pode ser reaproveitado depois de um rollback.

Tempo real

WS /ws/pagamentos (via gateway, /store/ws/pagamentos) só envia do servidor para o cliente. Entre as réplicas, um barramento Redis pub/sub por saas_id (com batimento para detectar assinatura muda) entrega o evento ao hub de conexões de cada réplica. Há ping a cada 30s, abaixo do idle_timeout de 300s do gateway.