← Voltar para Docs

GhostPayMesh — Diagnóstico B2B Core

Auditoria técnica e comercial · Jun/2026 · Baseado exclusivamente em código e evidências do repositório

Prontidão Geral B2B
~40%
40%

Core B2B · média de 3 dimensões

SDK Dart (gpm_pcl_core)
~58%
58%

SDK externo · packages/gpm_pcl_core/

APIs B2B Backend
~43%
43%

Endpoints externos · FastAPI · Railway

Fluxo Offline-first
~56%
56%

PCL + PLC + Identity end-to-end

5 Bloqueadores Críticos para Venda B2B
Três fluxos offline paralelos com nomenclatura sobreposta

SDK Dart — gpm_pcl_core ~58% médio packages/gpm_pcl_core/ · v0.1.0 · publish_to: none · 22 arquivos · 32 testes
MóduloProntoStatusO que existeEvidênciasGapsRiscoVendávelPróximo passo
Modelos PCL (payload, order, sync)
75%
Funcional PclCommercialPayload, OrderPayload, SyncBatch, SyncBatchItem pcl_commercial_payload.dart, order_payload.dart, sync_batch.dart Sem payload customizado/extensível; sem fromJson em SyncBatch Médio — campos fixos limitam extensão por parceiro Com restrição Adicionar extras Map<String,dynamic>; testar round-trip JSON
Hash SHA-256 / CanonicalJson
85%
Pronto OrderHashCalculator, ReceiptHashCalculator, CanonicalJson order_hash_calculator.dart, canonical_json.dart Sem teste de adulteração de campo individual; sem doc formal Baixo — algoritmo determinístico e bem testado (4 testes) Sim Documentar estrutura canônica para integradores externos
Assinatura Ed25519
15%
Mock / POC Interface SignatureAdapter; MockSignatureAdapter (sign → 'MOCK_SIG_POC_<len>') signature_adapter.dart:18-31 — verify() só checa prefixo string, sem crypto real Ed25519SignatureAdapter ausente; OfflineRiskValidator NÃO chama verify() CRÍTICO — PCL forjável: qualquer string com prefixo mock passa na validação offline Não Implementar Ed25519SignatureAdapter; integrar verify() no OfflineRiskValidator
Nonce / Replay Protection
60%
Parcial — in-memory NonceValidator (Set<String> in-memory), registerAndCheck, restoreFrom nonce_validator.dart:10-27 In-memory puro — reinicialização limpa Set; integração com RiskValidator é manual Médio — janela de replay entre restarts do app Com restrição Expor factory de nonce no SDK; clarificar contrato de persistência
TTL / Expiração
80%
Pronto TtlValidator.isValid(), isExpired(), remaining(); parâmetro 'now' injetável ttl_validator.dart:6-20 Sem constantes de TTL recomendadas no SDK; apps definem seus próprios valores Baixo — lógica simples; suscetível a clock skew de dispositivo Sim Documentar responsabilidade do clock; adicionar constantes de TTL sugeridas
Risco offline (limites/tx/dia)
65%
Funcional — sem sig verify OfflineRiskValidator, TerminalRiskConfig (R$500/tx, R$5.000/dia default) offline_risk_validator.dart:26-124 NÃO verifica assinatura; dailyAccumulated passado externamente; sem limite por usuário Médio — valida estrutura e limites mas não integridade criptográfica offline Com restrição Integrar verify() Ed25519; documentar modelo de limites para parceiros
QR encode / decode
70%
Funcional — JSON puro PclQrEncoder.encodePcl/encodeOrder, PclQrDecoder.decode pcl_qr_encoder.dart, pcl_qr_decoder.dart:27-42 Sem compressão/base64; sem chunking; sem teste de payloads grandes Médio — ordens com muitos itens podem exceder capacidade QR v40 Com restrição Definir limite máximo de campos; avaliar zlib+base64 ou CBOR
SyncBatch (offline→online)
70%
Funcional — HTTP no app SyncBatchBuilder.add(), build(); SyncBatch.toJson() sync_batch_builder.dart:17-37 Sem fromJson; schema de resposta do servidor não definido no SDK Baixo no SDK — parceiro precisa implementar o POST Com restrição Documentar schema de request/response para endpoint de sync
Testes do SDK
55%
32 testes — gaps em crypto 8 grupos: CanonicalJson, OrderHash, QR, TTL, Nonce, RiskValidator, SyncBatch, ReceiptHash test/gpm_pcl_core_test.dart — 32 casos; execução isolada 0 testes para SignatureAdapter; sem testes de adulteração Médio — gaps específicos em segurança criptográfica Com restrição Adicionar testes de assinatura real, adulteração de hash, round-trip
Documentação e empacotamento
10%
Ausente pubspec.yaml v0.1.0; dartdoc parcial em classes; comentários internos publish_to: none em pubspec.yaml:4; 0 arquivos README/CHANGELOG Sem README, CHANGELOG, example/, analysis_options.yaml; não publicável no pub.dev Alto — integrador externo não consegue usar sem orientação manual Não Criar README com quickstart, campos obrigatórios, exemplo mínimo

APIs B2B Backend ~43% médio backend/app/routes/ · FastAPI · Railway · /openapi.json disponível
MóduloProntoStatusO que existeEvidênciasGapsRiscoVendávelPróximo passo
PLC — create, status, chain, cancel
65%
Funcional / sem auth B2B POST /plc/create, GET /plc/{id}/status, GET /plc/{id}/chain, POST /plc/{id}/cancel routes/plc.py — sem Depends B2B; Idempotency-Key via Redis 300s Sem autenticação B2B; sem b2b_customer_id no modelo PromissoryToken Alto — endpoint público; qualquer agente externo cria PLCs sem rastreio Com restrição Conectar authenticate_by_key() como Depends; gravar customer_id em cada PLC
Transfer / Redeem
60%
Funcional / sem auth B2B POST /transfer (valida Ed25519), POST /redeem; idempotência habilitada routes/transfer.py, routes/redemption.py Sem auth B2B; sem multi-tenancy; sem logging de customer_id Médio — transfer já exige Ed25519, mas sem rastreio de parceiro Com restrição Auth B2B + log de customer_id por operação
Balance / Ledger
50%
Público / sem isolamento GET /balance/{owner_id}, /transactions, /promises; POST /reconcile routes/balance.py:73-77 — sem Depends; owner_id na URL expõe saldo de qualquer conta CRÍTICO: qualquer owner_id acessível sem auth; parceiro A lê dados do parceiro B CRÍTICO — vazamento de dados de saldo/transações entre parceiros Não Exigir auth B2B; validar que owner_id pertence ao customer autenticado
B2B Onboarding / Admin
75%
Funcional POST /b2b/signup, GET /b2b/status/{id}, GET /b2b/plans; admin: approve/suspend/block routes/b2b.py GET /b2b/status/{id} público expõe metadados de credenciais; sem paginação Médio — vaza metadados de credenciais sem auth Com restrição Proteger /b2b/status com auth; rate limit no signup público
API Keys — Geração e revogação
55%
Gerado / não enforced create_credentials() → key_id + api_secret (SHA-256 hash); revoke_credential(); scopes definidos b2b_service.py:218-268 — authenticate_by_key() implementado mas sem wiring em NENHUMA rota authenticate_by_key() órfão; scopes gravados mas nunca verificados em runtime CRÍTICO — API keys existem no banco mas não protegem absolutamente nada Não Criar Depends(require_b2b_api_key) e aplicar nas rotas PLC/transfer/balance
Multi-tenancy (isolamento de dados)
10%
Não implementado Modelo B2BCustomer, ApiCredential com customer_id; metering e audit no modelo models/plc.py:14-41 — PromissoryToken SEM b2b_customer_id PLCs, transfers, balance sem tenant_id; parceiro A acessa dados do parceiro B CRÍTICO — violação de privacidade entre parceiros para produto comercial Não Adicionar b2b_customer_id em PromissoryToken + migration Alembic
Webhooks outbound para parceiros
5%
Inexistente Scopes incluem 'webhooks'; SDK Python define HMAC verify; Supabase Realtime para PLC GAP_ANALYSIS.md:123 — 'Webhooks customizados por parceiro: ❌' Sem endpoint de registro de URL; sem dispatcher outbound; sem retry/backoff para parceiros Alto — integração event-driven impossível; parceiro fica em polling Não POST /b2b/webhooks (registro URL) + dispatcher async + HMAC payload
Rate limit por API key
20%
Só por IP Middleware rate_limit.py; /plc: 60/min, /transfer: 30/min, /redeem: 20/min rate_limit.py:80-82 — key Redis = 'ratelimit:{prefix}:{ip}:{device_id}' Sem rate limit por API key; parceiros em IPs compartilhados afetam-se mutuamente Médio — abuso de plano básico não rastreável Não Estender rate_limit.py para incluir api_key_id na key do Redis
Sandbox self-service B2B
20%
Global / sem self-service ASAAS sandbox via key prefix; /api/v1/dev/* (requer DEV_SIM_SECRET) config.py:244-255; dev_sandbox.py Sem sandbox por parceiro; parceiro não consegue testar sem suporte manual Alto para venda — parceiro não valida integração sem nós Não Campo sandbox_mode em B2BCustomer + mock Asaas per-tenant
OpenAPI e documentação técnica
60%
Auto gerado / divergente FastAPI /openapi.json; docs developers/ (getting-started, sdk-overview, transfer-signing) test_security_hardening.py:264-269; docs/developers/ Divergência SDK vs backend; sem doc PCL comercial; sem Postman Médio — integrador segue docs e encontra inconsistências no runtime Com restrição Sincronizar docs com implementação; publicar Postman; criar guia PCL comercial
Idempotência
75%
Implementado — header opcional Idempotency-Key header; Redis NX EX 300s; fallback in-memory; X-Idempotency-Replayed middleware/idempotency.py:18-81 — cobre /plc/create, /transfer, /redeem Header opcional — sem key cada POST processa novamente; TTL curto (300s) Baixo quando usado; parceiro precisa saber implementar Sim Considerar Idempotency-Key obrigatório para parceiros B2B
Audit / metering por parceiro
30%
Admin only AuditLog (B2B_SIGNUP, CREDENTIAL_CREATED); UsageMetering (PLCs/mês) no modelo b2b_service.py:27-42 — check_plc_limit() e increment_metering() NUNCA chamados nas rotas Parceiro não acessa seus logs; metering não enforced; sem GET /b2b/me/usage Médio — billing difícil sem metering; compliance sem auditoria do parceiro Não GET /b2b/me/usage + GET /b2b/me/audit; enforçar increment_metering() no plc_service

Fluxo Offline-first end-to-end ~56% médio
MóduloProntoStatusO que existeEvidênciasGapsRiscoVendávelPróximo passo
PCL comercial — Geração (ghostpay_app)
70%
Funcional / app interno ConfirmPclScreen._signAndConfirm(); PclCommercialPayload + CanonicalJson + GhostCrypto ghostpay_app/.../confirm_pcl_screen.dart:57-106 Lógica acoplada ao app interno; sem factory no SDK; chave privada em Hive local Alto — parceiro precisa reimplementar ou usar app interno Com restrição Mover _signAndConfirm() para PclFactory no gpm_pcl_core
PCL comercial — Assinatura Ed25519 real
60%
Real no app / mock no SDK GhostCrypto.sign() real (ed25519_edwards) no ghostpay_app; MockSignatureAdapter no SDK ghostpay_app/.../ghost_crypto.dart:37-44 Ed25519SignatureAdapter ausente no SDK; parceiro não assina sem usar internals do ghostpay_app Alto — sem implementação oficial de assinatura no SDK público Não Implementar Ed25519SignatureAdapter no gpm_pcl_core
PCL comercial — Validação offline (POS)
75%
Funcional — sem sig verify ScanPclScreen + OfflineRiskValidator + NonceValidator; PosLocalDb (Hive) ghostpay_pos_app/.../scan_pcl_screen.dart:38-132 verify() Ed25519 não chamado no OfflineRiskValidator; validação acoplada ao app POS Médio — valida estrutura e limites; NÃO valida integridade criptográfica offline Com restrição Integrar verify() no OfflineRiskValidator; doc para parceiros criarem validador próprio
PCL comercial — Sync offline→online
70%
Funcional / endpoint POS SyncBatchBuilder.build() → PosApiClient.syncBatch() → POST /api/v1/pos/sync pos_api_client.dart:58-68, 141-163 Endpoint /pos/sync é merchant SaaS; parceiro externo sem terminal cadastrado não tem acesso Alto — sync depende de contexto POS interno (merchantId, terminalId) Com restrição Criar POST /api/v1/b2b/sync-batch independente de contexto POS interno
PCL comercial — Validação backend
70%
Implementado — registro manual _verify_ed25519_signature() em pos.py:162-203; verifica KeyBackup.public_key vs device_id routes/pos.py:162-203 Exige public_key registrada via POST /security/key/backup ANTES do sync; sem automação Médio — onboarding de dispositivo B2B sem fluxo self-service Com restrição Criar fluxo self-service de registro de chave pública por parceiro B2B
PLC Mesh — Protocolo completo
70%
Funcional / sem tenant create/transfer/redeem/cancel; ledger double-entry; fila offline (OutboxQueue, SyncService) routes/plc.py; services/plc_service.py; .../sync_service.dart Sem auth B2B; sem isolamento por parceiro; notificação via Supabase Realtime (não webhook) Médio — protocolo sólido mas sem camada enterprise B2B Com restrição Adicionar auth B2B e b2b_customer_id nos endpoints PLC
Identity — Pagamento offline
15%
GAP crítico — sem sync Débito local Hive (PinValidationScreen._pay); offlinePaymentLimitCents=5000 pin_validation_screen.dart:220-241 Pagamentos offline NÃO têm fila de replay; http_ledger chama HTTP imediato; saldo diverge CRÍTICO — inconsistência de saldo; pagamento sem registro no backend Não Implementar OfflinePaymentQueue + replay em IdentitySyncService
Transporte BLE / NFC
10%
Apenas QR funcional Enum BLE, NFC, MESH, QR, KEY no backend; NFC só para UID no Identity nfc_service.dart — 'bloqueado para pagamento'; 0 código BLE no SDK BLE/NFC para transporte de PCL/PLC NÃO implementado; material marketing pode mencionar BLE Alto — promessa de marketing sem implementação real Não Alinhar material de marketing; roadmap BLE explícito com data

Respostas Finais — 12 Perguntas
1 Possui SDK real hoje? Parcial gpm_pcl_core v0.1.0 existe com modelos, hash, TTL, nonce, QR. Assinatura é mock. Sem README. publish_to: none.
2 SDK desacoplado ou preso ao app? Parcial SDK Dart desacoplado (zero imports internos). Porém geração + assinatura real da PCL está no ghostpay_app (ConfirmPclScreen), não no SDK.
3 Empresa consegue integrar sozinha? Não / Crítico Não. Sem README, sem Ed25519 real no SDK, sem auth B2B enforced, sem sandbox self-service, sem webhooks. Inviável sem suporte.
4 Empresa consegue integrar com suporte? Parcial Sim, com suporte intensivo. Python SDK para PLC mesh funciona. PCL comercial exige orientação manual. Estimativa: 2–4 semanas.
5 Core offline/PCL é vendável hoje? Parcial PCL comercial: piloto assistido (55%). PLC mesh: com suporte (55–60%). Identity offline: não vendável (15%).
6 As APIs são vendáveis hoje? Não / Crítico Não. Endpoints PLC/balance públicos sem auth. API keys geradas mas não enforced. Multi-tenancy ausente. Webhooks inexistentes.
7 Percentual do Core técnico? ~62% Protocolo PLC sólido, hash, ledger double-entry, Ed25519 em transfers, sync batch. Gaps: mock offline, sem tenancy, Identity incompleto.
8 Percentual do SDK externo? ~35% Modelos, hash, TTL, nonce, QR funcionam. Sem Ed25519 real, sem README, sem pub.dev, assinatura acoplada ao app.
9 Percentual das APIs externas? ~30% Endpoints existem internamente. Sem auth B2B enforced, sem multi-tenancy, sem webhooks, sem sandbox por parceiro.
10 Prontidão comercial B2B Core? ~40% Produto demonstrável mas sem empacotamento comercial: sem auth, sem sandbox, sem webhooks, docs divergentes.
11 7 dias para piloto B2B? Plano 1) Conectar authenticate_by_key() nas rotas PLC/transfer/balance. 2) Implementar Ed25519SignatureAdapter. 3) README mínimo do SDK. 4) Provisionar parceiro piloto manualmente com credencial + KeyBackup.
12 30 dias para SDK/API vendável? Plano 1) Webhooks outbound. 2) Sandbox self-service. 3) Rate limit por API key. 4) /b2b/me/usage + audit. 5) Multi-tenancy PLC. 6) Docs + Postman. 7) Remover mock de assinatura.

Planos de Ação
7 dias — Piloto B2B assistido
1
Conectar authenticate_by_key() como Depends nas rotas /plc, /transfer, /balance
2
Implementar Ed25519SignatureAdapter no gpm_pcl_core (~30 linhas usando ed25519_edwards)
3
Adicionar b2b_customer_id em PromissoryToken + migration Alembic
4
Criar README mínimo do gpm_pcl_core (quickstart + campos obrigatórios + exemplo)
5
Provisionar parceiro piloto manualmente: B2BCustomer → approve → credencial → KeyBackup
30 dias — SDK/API vendável
1
Webhooks outbound: POST /b2b/webhooks + dispatcher async + HMAC payload
2
Sandbox self-service: sandbox_mode em B2BCustomer + mock Asaas per-tenant
3
Rate limit por api_key_id no Redis (extensão simples do middleware)
4
GET /b2b/me/usage + GET /b2b/me/audit (endpoints do próprio parceiro)
5
Mover PclFactory para gpm_pcl_core; enforçar increment_metering() no plc_service
6
README completo + Postman collection + guia PCL comercial em docs/developers/
7
Remover MockSignatureAdapter de caminhos de produção
8
Sync de pagamento offline no IdentitySyncService (OfflinePaymentQueue + replay)