EFXPay Middleware
Camada intermediária entre o app mobile e a GlobalSCM.
Esta API expõe endpoints estáveis em /api/v1/*, persiste dados localmente
e isola toda comunicação HTTP com o provedor na pasta app/Services/GlobalSCM.
Contrato OpenAPI
Spec v1.0 para o app mobile gerar clientes tipados.
Autenticação
Login JWT e sessão bancária com a GlobalSCM.
PIX
Enviar, cobrar QR e gerir chaves DICT.
Onboarding
Fluxo PF multi-etapa até conta activa.
Fluxo resumido
Arquitetura
Regra central do projeto: nenhum controller chama HTTP diretamente.
Toda integração passa por serviços em App\Services\GlobalSCM.
| Camada | Responsabilidade |
|---|---|
Controllers (app/Http/Controllers/Api) | Validação, JWT, idempotência, resposta JSON ao app |
| Models + migrations | users, accounts, banking_sessions, pix_transactions, onboarding_*, webhook_events |
| GlobalScmClient | Retry 401/5xx, token por utilizador |
| GlobalScmConnector | HTTP bruto + modo stub para testes |
| Jobs | Processamento assíncrono de webhooks |
Stack e configuração
| Tecnologia | Uso |
|---|---|
| PHP 8.3 + Laravel 12 | API REST |
| MySQL 8 | Persistência (SQLite em testes) |
| JWT (RS256) | Autenticação do app — Authorization: Bearer |
Variáveis de ambiente principais
| Variável | Descrição |
|---|---|
GLOBALSCM_BASE_URL | Base da API GlobalSCM (ex.: https://api.globalscm.app.br) |
GLOBALSCM_EMAIL / PASSWORD | Credenciais conta BAAS (dev / testes diretos) |
GLOBALSCM_ISPB | ISPB para listar/excluir chaves PIX (padrão 11165756) |
GLOBALSCM_STUB | true simula respostas sem chamar a rede |
GLOBALSCM_WEBHOOK_SECRET | Header X-Webhook-Secret nos webhooks inbound |
ONBOARDING_LOCAL_ONLY | true — onboarding só local, sem GlobalSCM |
JWT_* | Emissor, audiência e chaves do token EFXPay |
Prefixo da API EFXPay: {APP_URL}/api/v1/
Contrato mobile (OpenAPI)
Para integração do app, use os artefactos versionados nesta pasta — não este HTML como fonte de verdade.
| Ficheiro | Descrição |
|---|---|
openapi.mobile.yaml |
OpenAPI 3.0.3 · v1.0.0 · bearerAuth JWT · rotas públicas sem security |
EFXPay-Mobile.postman_collection.json |
Coleção Postman com login automático e variáveis base_url, jwt |
CHANGELOG-api.md |
Histórico e breaking changes do contrato /api/v1 |
Visualizar/editar o spec: Swagger Editor (importar o YAML).
Autenticação
O login do app usa duas validações: credenciais no banco EFXPay (users)
e login na GlobalSCM com o mesmo email/senha. O token do provider fica em banking_sessions;
o app recebe apenas o JWT EFXPay.
| Endpoint | Auth | |
|---|---|---|
| POST | /api/v1/auth/login |
Público (throttle) |
| POST | /api/v1/auth/logout |
JWT |
Request — login
{
"email": "usuario@exemplo.com",
"password": "senha"
}
Response — login
{
"access_token": "<jwt-efxpay>",
"token_type": "Bearer"
}
Provider: POST /internal/api/v1/auth/login
Contas
Todos os endpoints abaixo exigem Authorization: Bearer {jwt}.
| Endpoint | Descrição | |
|---|---|---|
| GET | /api/v1/accounts/me |
Dados da conta local + provider_client_token |
| GET | /api/v1/accounts/balance |
Saldo via GlobalSCM |
| GET | /api/v1/accounts/statement |
Extrato (start_date, end_date opcionais) |
| POST | /api/v1/accounts/pf |
Cadastro PF (legado / registo) |
| POST | /api/v1/accounts/pj |
Cadastro PJ |
Provider saldo/extrato: GET /internal/api/v1/account/balance, .../statement
PIX — envio e cobrança
Idempotency-Key em POST /pix/send e POST /pix/charge.
No envio PIX, o mesmo valor é enviado à GlobalSCM como clientRequestId.
Enviar PIX — POST /api/v1/pix/send
Fluxo interno (2 passos no provider):
POST /internal/api/v1/keys/dict— consulta chave (payerId= CPF/CNPJ do user,key= chave destino)POST /internal/api/v1/payments— pagamento DICT comendToEndretornado na consulta
Headers:
Authorization: Bearer {jwt}
Idempotency-Key: {uuid-unico}
Body:
{
"pix_key": "destino@email.com",
"amount": 10.50,
"description": "Opcional"
}
Response:
{
"transaction_id": "uuid-local",
"status": "PROCESSING",
"end_to_end": "E..."
}
Status possíveis: PROCESSING, COMPLETED, FAILED.
Atualização de status: modelo webhook-first na GlobalSCM.
GET /api/v1/pix/{id} lê apenas o registro local — não consulta o provider.
Cobrança QR — POST /api/v1/pix/charge
Campo type obrigatório:
dynamic→POST .../payments/qrcode/dynamic(valor + expiração)static→POST .../payments/qrcode/static(valor fixo)
O EFXPay gera automaticamente transactionIdentification (26 caracteres alfanuméricos).
Headers:
Authorization: Bearer {jwt}
Idempotency-Key: {uuid-unico}
Body (exemplo dynamic):
{
"type": "dynamic",
"amount": 129.47,
"description": "Pagamento pedido 123",
"key": "opcional — default: email ou documento do user",
"receiver_name": "opcional — max 25 chars",
"city": "opcional — default Sao Paulo",
"zipcode": "opcional — 8 dígitos",
"expiration_qr": 3600,
"payer_name": "opcional",
"payer_cpf": "opcional",
"reusable": false
}
Response:
{
"transaction_id": "uuid-local",
"status": "PROCESSING",
"qr_code": "...",
"copy_paste": "00020126..."
}
Consultar transação — GET /api/v1/pix/{id}
{
"transaction_id": "uuid",
"status": "PROCESSING"
}
Para cobranças, inclui qr_code e copy_paste se gravados no envio.
Chaves PIX
Gestão de chaves DICT da conta do utilizador autenticado (token banking_sessions).
| Endpoint EFXPay | GlobalSCM | |
|---|---|---|
| GET | /api/v1/pix/keys |
POST /internal/api/v1/keys/list |
| POST | /api/v1/pix/keys |
POST /internal/api/v1/keys/create |
| DELETE | /api/v1/pix/keys |
DELETE /internal/api/v1/keys |
Criar chave — body
{
"key_type": "EVP_ENDERECO_VIRTUAL_DE_PAGAMENTO",
"email": "opcional — só se key_type=E_MAIL e diferente do cadastro"
}
Valores key_type: CPF, CNPJ, CELULAR, E_MAIL, EVP_ENDERECO_VIRTUAL_DE_PAGAMENTO.
Excluir chave — body
{
"key": "chave@email.com"
}
Listagem usa dados da conta do user (agência, conta, CPF/CNPJ, ISPB do .env).
Webhooks
| Endpoint | Descrição | |
|---|---|---|
| POST | /api/v1/webhooks/globalscm |
Recebe eventos GlobalSCM (ex.: PIX recebido) |
Header opcional: X-Webhook-Secret (validado se GLOBALSCM_WEBHOOK_SECRET estiver definido).
Payload é persistido em webhook_events e processado em fila (ProcessGlobalScmWebhookJob).
Deduplicação por hash do payload.
Onboarding (pessoa física)
/core/v2/onboarding/*)
retornaram 404 nos ambientes testados. Use
ONBOARDING_LOCAL_ONLY=true para desenvolver o fluxo do app sem o provider,
ou aguarde habilitação / URL correta com o suporte GlobalSCM.
API EFXPay — prefixo /api/v1/onboarding/:
| Método | Rota | Ação |
|---|---|---|
| POST | pf | Inicia onboarding PF |
| GET | {id} | Estado da aplicação |
| GET | cep/{cep} | Consulta CEP |
| POST | {id}/address | Endereço |
| POST | {id}/documents | Upload documento |
| POST | {id}/proposal | Proposta |
| POST | {id}/electronic-validation | Solicitar código |
| POST | {id}/electronic-validation/confirm | Validar código |
| POST | {id}/prova-vida | Prova de vida |
| GET | {id}/kyc | Status KYC |
| POST | {id}/sync | Sincronizar steps pendentes |
Mapa GlobalSCM (implementado)
| Funcionalidade | Path GlobalSCM | Serviço EFXPay |
|---|---|---|
| Login | POST /internal/api/v1/auth/login | GlobalScmAuth |
| Saldo | GET .../account/balance | GlobalScmAccounts |
| Extrato | GET .../account/statement | GlobalScmAccounts |
| Consulta chave DICT | POST .../keys/dict | GlobalScmPixKeys |
| Pagamento PIX | POST .../payments | GlobalScmPix |
| QR dinâmico | POST .../payments/qrcode/dynamic | GlobalScmPix |
| QR estático | POST .../payments/qrcode/static | GlobalScmPix |
| Chaves CRUD | keys/create|list, DELETE keys | GlobalScmPixKeys |
| Onboarding PF | /core/v2/onboarding/* | GlobalScmOnboarding indisponível no host testado |
Estrutura de código
app/
├── Http/Controllers/Api/
│ ├── AuthController.php
│ ├── AccountController.php
│ ├── PixController.php
│ ├── PixKeysController.php
│ ├── OnboardingController.php
│ └── WebhookController.php
├── Services/
│ ├── GlobalSCM/
│ │ ├── GlobalScmClient.php
│ │ ├── GlobalScmConnector.php
│ │ ├── GlobalScmPix.php
│ │ ├── GlobalScmPixKeys.php
│ │ ├── GlobalScmPaymentRequestMapper.php
│ │ ├── GlobalScmPixResponseMapper.php
│ │ ├── GlobalScmAccountContext.php
│ │ └── ...
│ └── Onboarding/
config/globalscm.php # paths, ISPB, timeouts
routes/api.php # rotas /api/v1
docs/
├── globalscm-pix-endpoint-probes.md
└── pix-manual-validation-checklist.md
Ferramentas de desenvolvimento
Apenas com APP_ENV=local:
| URL | Uso |
|---|---|
/dev/globalscm | Testes login GlobalSCM, EFXPay, conta, PIX |
/dev/onboarding-pf | Wizard onboarding PF passo a passo |
Comando útil: php artisan efxpay:ensure-dev-user — cria user local com credenciais do .env.
Testes e validação
php artisan test
php artisan migrate
Testes usam GLOBALSCM_STUB=true (phpunit.xml). Checklist manual em docs/pix-manual-validation-checklist.md.
Ordem sugerida para homologação PIX
POST /api/v1/auth/login— user onboarded no bancoGET /api/v1/accounts/me— conta com agência/número/documentoGET /api/v1/accounts/balancePOST /api/v1/pix/chargecomtype: dynamicPOST /api/v1/pix/sendcom valor mínimoGET /api/v1/pix/keyse CRUD de chaves
Limitações conhecidas
- Onboarding GlobalSCM — rotas
/core/v2/*e/integracoesnão disponíveis nos hosts testados (404). Integração reversa (webhooks CONTA_CRIADA) ainda não implementada. - Status PIX outbound — sem polling no provider; depende de webhook ou consulta futura ao extrato por
endToEnd. - baas/list — fora do escopo do MVP.
- User precisa de
document,agencyeaccount_numberemaccountsapós login para PIX e chaves.