📦 Postman OpenAPI JSON Swagger UI →

Manual de Integração

Guia didático para integrar sua aplicação com a API HubPay. Siga os passos em ordem para ter sua primeira integração funcionando em minutos, com segurança e seguindo as melhores práticas do mercado.

👋 Introdução e pré-requisitos

A API HubPay é uma API REST que retorna JSON em todos os endpoints. A autenticação é feita via Bearer Token JWT no header Authorization.

Pré-requisitos

  • Servidor local rodando: php artisan serve --port=8000
  • Banco de dados migrado: php artisan migrate --seed
  • Cliente HTTP: Postman Collection ou Swagger UI
  • Base URL: https://fintechpay.developerapi.com.br/api
💡

Todos os exemplos usam https://fintechpay.developerapi.com.br/api como base — definido pela variável APP_URL no arquivo .env.

Credenciais padrão (seeder)

PerfilE-mailSenhaExtra
Adminadmin@smartpay.compassword
Operadorjoao@smartpay.compasswordPIN: 1234
Máquina POS12345 (app)Código: ABC12345

🗺️ Visão Geral da Arquitetura

A API possui 3 guards JWT independentes. Cada guard tem seu próprio endpoint de login e scope de acesso:

GuardLoginAcesso
apiPOST /auth/tokenAdmin, Partner, Sub-partner — gestão global
operatorPOST /operators/loginOperador de caixa — restrito à sua unidade
entregadorPOST /entregadores/loginEntregador — somente suas rotas SmartRoute
⚠️

Importante: tokens de guards diferentes não são intercambiáveis. Um token de operador não funciona em rotas que exigem auth:api, e vice-versa.

⚙️ Configurar o Ambiente

1

Clonar e instalar

git clone https://github.com/SALVADORBBA/FintechPay.git
cd FintechPay
composer install
2

Configurar variáveis de ambiente

cp .env.example .env
php artisan key:generate
php artisan jwt:secret

Edite .env com suas credenciais de banco (DB_DATABASE, DB_USERNAME, DB_PASSWORD).

3

Criar banco e popular dados iniciais

php artisan migrate --seed
4

Iniciar o servidor

php artisan serve --port=8000

Acesse Swagger UI em https://fintechpay.developerapi.com.br/docs para testar os endpoints.

🔑 Autenticação — Admin / Partner

Use este guard para gerenciar parceiros, unidades, operadores, produtos e configurações gerais.

1. Fazer login

POST /api/auth/token
Content-Type: application/json

{
  "email": "admin@smartpay.com",
  "password": "password"
}

Resposta

{
  "access_token": "eyJ0eXAiOiJKV1Qi...",
  "token_type":   "bearer",
  "expires_in":   3600,
  "user": {
    "id": 1,
    "role": "admin",
    "partner_id": 1
  }
}

2. Usar o token nas requisições

# Adicione o header em todas as requisições autenticadas
Authorization: Bearer eyJ0eXAiOiJKV1Qi...

Boa prática: No Postman, salve o token numa variável de coleção (admin_token) e use {{admin_token}}. A collection disponível para download já faz isso automaticamente via script de test.

Endpoints de autenticação admin

MétodoRotaDescrição
POST/api/auth/tokenLogin — retorna access_token
POST/api/auth/registerCriar novo usuário admin/partner
GET/api/auth/mePerfil do usuário autenticado
POST/api/auth/logoutInvalidar token
POST/api/auth/refreshRenovar token sem novo login

👷 Autenticação — Operador

Operadores têm acesso restrito à sua system_unit. São eles quem criam pedidos, registram pagamentos e emitem notas.

Login por e-mail e senha

POST /api/operators/login

{
  "email":    "joao@smartpay.com",
  "password": "password"
}

Login por PIN (terminal POS)

POST /api/operators/login-pin
X-Activation-Key: sua-chave-de-ativacao

{
  "pin": "1234"
}
💡

O header X-Activation-Key identifica o terminal POS. Obtenha-a via GET /api/activation/machine?codigo=ABC12345.

🚚 Autenticação — Entregador (SmartRoute)

Guard exclusivo para entregadores do módulo SmartRoute. O token deste guard só acessa rotas do prefixo /entregador/.

POST /api/entregadores/login

{
  "email":    "entregador@empresa.com",
  "password": "senha"
}

Com o token obtido, o entregador pode consultar suas rotas, iniciar entregas e enviar sua localização em tempo real.

🛡️ Boas Práticas JWT

  • Nunca exponha tokens em logs ou URLs. Sempre use o header Authorization.
  • Renove o token antes de expirar via POST /api/auth/refresh. O TTL padrão é 60 minutos.
  • Faça logout ao encerrar a sessão (POST /api/auth/logout) para invalidar o token no servidor.
  • Armazene tokens de forma segura: em apps mobile use Keychain (iOS) ou Keystore (Android); nunca em localStorage sem criptografia.
  • Não misture guards: use o token correto para cada tipo de usuário.

🛒 Fluxo Completo de Venda

Este é o fluxo principal da plataforma — do login do operador até o fechamento do pedido com nota fiscal emitida.

1

Login do operador

POST /api/operators/login
→ salve o access_token como operator_token
2

Abrir o caixa

POST /api/cash-register/open
{ "opening_balance": 10000 } // valor em centavos
→ salve o cash_register_id
3

Criar pedido

POST /api/sales-orders
{
  "type":             "COUNTER",
  "cash_register_id": 1
}
→ salve o sales_order_id

Tipos disponíveis: TABLE, COUNTER, DELIVERY, PARKING.

4

Adicionar itens

POST /api/sales-orders/{id}/items
{
  "produto_id":     1,
  "quantidade":     2,
  "preco_unitario": 2500 // centavos
}

Repita esta chamada para cada produto. O total do pedido é recalculado automaticamente.

5

Confirmar pedido

POST /api/sales-orders/{id}/confirm
→ status muda para "confirmed"
6

Registrar pagamento

POST /api/pagamentos
{
  "sales_order_id": 42,
  "payment_type":  "pix",
  "amount":        5000
}
→ tickets gerados automaticamente após aprovação
7

Emitir NF-e (opcional)

POST /api/fiscal-documents/gerar
{ "sales_order_id": 42 }
→ NF-e emitida e XML disponível

💳 Registrar Pagamento

Métodos aceitos: credit, debit, pix, cash, voucher.

Criar pagamento

POST /api/pagamentos
{
  "sales_order_id": 42,
  "payment_type":  "credit",
  "amount":        5000,      // em centavos
  "installments":  1
}

Atualizar com retorno do POS (PlugPag SDK)

PUT /api/pagamentos/{id}
{
  "status":         "approved",
  "nsu":            "password",
  "authorization":  "AUTH789",
  "card_brand":     "Visa"
}
💡

Quando status muda para "approved", o pedido é marcado como pago, o caixa é atualizado e os tickets são gerados automaticamente.

🧾 Emissão Fiscal — NF-e / NFC-e

⚠️

Configure o certificado digital A1 (.pfx) em storage/app/certificados/{beneficiary_id}.pfx e preencha os dados fiscais do beneficiário antes de emitir em produção.

Emitir documento fiscal

POST /api/fiscal-documents/gerar
{ "sales_order_id": 42 }

Outros endpoints fiscais

MétodoRotaAção
GET/api/fiscal-documents/{id}Consultar status da nota
GET/api/fiscal-documents/{id}/xmlDownload do XML
POST/api/fiscal-documents/{id}/cancelarCancelar nota emitida

🚚 Módulo SmartRoute — Logística de Entregas

O SmartRoute usa um guard JWT próprio para entregadores. O fluxo envolve dois perfis: o administrador/operador que cria as rotas, e o entregador que as executa.

Parte 1 — Admin cria a rota

# 1. Cadastrar entregador (auth:operator ou auth:api)
POST /api/entregadores
{
  "name":           "João Silva",
  "email":          "joao@empresa.com",
  "password":       "senha123",
  "system_unit_id": 1
}

# 2. Criar rota com paradas
POST /api/delivery-routes
{
  "entregador_id": 1,
  "notes": "Rota turno manhã",
  "stops": [
    {
      "customer_name":  "Maria",
      "address":        "Rua A, 100",
      "latitude":       -23.5505,
      "longitude":      -46.6333,
      "payment_type":   "antecipado"
    }
  ]
}

Parte 2 — Entregador executa a rota

# 1. Login do entregador
POST /api/entregadores/login
→ entregador_token

# 2. Ver minhas rotas
GET  /api/entregador/routes?status=criada

# 3. Iniciar rota
POST /api/entregador/routes/{id}/start

# 4. Enviar localização periodicamente
POST /api/entregador/routes/{id}/location
{ "latitude": -23.551, "longitude": -46.634 }

# 5. Para cada parada:
POST /api/entregador/stops/{id}/start     // iniciar
POST /api/entregador/stops/{id}/arrive    // registrar chegada + distância
POST /api/entregador/stops/{id}/pay       // se payment_type=na_entrega
POST /api/entregador/stops/{id}/deliver   // finalizar entrega

# 6. Finalizar rota (todas as paradas entregues)
POST /api/entregador/routes/{id}/finish
💡

O endpoint /arrive calcula automaticamente a distância em metros entre o local previsto e o local real da entrega usando a fórmula de Haversine.

🅿️ Módulo Parking — Estacionamento

1. Criar tabela de preço

POST /api/parking/pricings
{
  "name":                      "Padrão",
  "type":                      "HOURLY",
  "price_per_hour":            5.00,
  "price_per_minute_exceeded": 0.10,
  "grace_period_minutes":      10,
  "daily_max_price":           30.00
}

2. (Opcional) Cadastrar mensalista

POST /api/parking/monthly
{
  "name":       "Carlos Mensalista",
  "plate":      "XYZ9876",
  "pricing_id": 1,
  "start_date": "2026-04-01",
  "end_date":   "2026-04-30"
}

3. Registrar entrada

POST /api/parking/entry
{
  "plate":        "ABC1234",
  "vehicle_type": "car",
  "pricing_id":   1
}
→ is_monthly: true se placa for mensalista ativo

4. Registrar saída (calcula valor automaticamente)

POST /api/parking/exit/{ticket_id}

// Resposta:
{
  "duration_minutes": 95,
  "total_amount":     9.50,   // 1h × R$5 + 35min × R$0.10
  "sales_order": { "id": 88, "status": "confirmed" }
}
→ SalesOrder tipo PARKING criada automaticamente

Regras de cálculo HOURLY

// Exemplo: 1h30min, R$5/hora, R$0,10/min excedente, 10min tolerância
billable_minutes = 90 - 10 = 80 min
full_hours       = floor(80/60) = 1h
exceeded_minutes = 80 % 60     = 20min
total            = (1 × 5.00) + (20 × 0.10) = R$ 7,00

🏢 Multi-tenant — Conceitos e Escopo

Todo recurso da API pertence a um partner_id. O middleware tenant.scope aplica filtros automaticamente baseado no token:

PerfilAcesso
Admin (role=admin)Todos os dados — sem restrição
Partner / Sub-partnerPróprio tenant + todos os descendentes na hierarquia
OperatorApenas dados do seu partner_id e system_unit_id
EntregadorApenas as rotas atribuídas a ele
🚫

Nunca confie em partner_id enviado pelo cliente. O sistema sempre usa o partner_id extraído do JWT — nunca o do corpo da requisição — para garantir isolamento total entre tenants.

📡 Webhooks

Configure uma URL de webhook no cadastro do beneficiário. A API enviará um POST com payload JSON nos seguintes eventos:

EventoQuando
payment.approvedPagamento aprovado via PUT /pagamentos/{id}
order.createdNovo pedido criado
order.closedPedido fechado

Exemplo de payload recebido

POST https://seu-sistema.com/webhook
Content-Type: application/json

{
  "event":      "payment.approved",
  "amount":     50.00,
  "order_id":   42,
  "payment_id": 7,
  "timestamp":  "2026-04-24T10:30:00Z"
}

Responda com HTTP 200 para confirmar o recebimento. A API registra o log de cada tentativa na tabela webhook_logs.

Tratamento de Erros

CódigoSignificadoComo resolver
401Token ausente ou inválidoFaça login novamente e atualize o token
403Sem permissão para o recursoVerifique se o partner_id do recurso está no escopo do token
404Recurso não encontradoConfirme o ID e se o recurso existe no tenant correto
422Validação falhouLeia o campo errors no response para saber quais campos estão incorretos
500Erro interno do servidorVerifique os logs em storage/logs/laravel.log

Exemplo de erro 422

{
  "message": "The given data was invalid.",
  "errors": {
    "email":    ["The email field is required."],
    "password": ["The password must be at least 6 characters."]
  }
}

Boas Práticas Gerais

Segurança

  • Use HTTPS em produção — nunca exponha a API em HTTP puro.
  • Rotacione o JWT_SECRET periodicamente e após qualquer comprometimento.
  • Nunca logue tokens de acesso completos — use apenas os primeiros e últimos caracteres para debug.

Performance

  • Use os filtros disponíveis (?status=, ?date=) para evitar carregar listas inteiras desnecessariamente.
  • Todas as listas são paginadas (per_page padrão: 20). Use ?page=2 para navegar.
  • Prefira GET /parking/open para listar veículos no estacionamento — é mais eficiente do que GET /parking/tickets?status=OPEN.

Integração

  • Use o Postman Collection como referência — os scripts de test já salvam os IDs automaticamente nas variáveis.
  • Teste sempre em ambiente local antes de apontar para produção.
  • Para NF-e use fiscal_ambiente: 2 (homologação) durante o desenvolvimento e 1 apenas em produção com certificado válido.
  • Implemente retry com backoff exponencial para chamadas de webhook que podem falhar.
📖

Explore todos os endpoints no Swagger UI interativo — você pode testar chamadas diretamente no navegador sem precisar do Postman.