Adaptadores BaaS
Compilar matriz kroz → payload do parceiro BaaS: contrato agnóstico, adaptador plugável por provedor.
Visão geral
A kroz orchestra regras; o BaaS executa Pix, boleto, subcontas e split. O adaptador traduz:
split_matrices.receivers → split[] → POST {BAAS_BASE_URL}/payments
Cliente compartilhado no backend: módulo _baasClient (implementação por parceiro).
| Ambiente | Base URL |
|---|---|
| Sandbox | Configurada via BAAS_BASE_URL (homologação) |
| Produção | Configurada via BAAS_BASE_URL |
| Override | BAAS_BASE_URL |
Headers outbound (típicos):
Authorization: Bearer <BAAS_API_KEY>
User-Agent: kroz.co/1.0.0 (ou BAAS_USER_AGENT)
Requisitos fixos (qualquer BaaS)
| Requisito | Detalhe | Contrato kroz |
|---|---|---|
| Subcontas | 1 recebedor = 1 conta IP | Endpoint de onboarding |
| Split na origem | Repasse na liquidação | split[] na criação da cobrança |
| PIX + boleto | Ambos com webhook | Eventos de liquidação |
| RC 16 | Sem conta-bolsão | Modelo A nativo |
| Sandbox homologável | Cenário 72/18/10 | Ambiente de testes |
Modelos de liquidação
| Modelo | Descrição | kroz |
|---|---|---|
| A: Split na origem | split[] na criação |
✅ Desenho atual |
| B: Conta + P2P | Cash-in → N transferências | ⚠️ RC 16 + reescrita |
| C: Batch manual | Rateio posterior | ❌ |
Modo dry-run vs execução real
Default: dry-run: nenhum efeito no parceiro BaaS.
| Condição | Modo |
|---|---|
dryRun !== false (default) |
Dry-run |
BAAS_API_KEY ausente |
Dry-run forçado |
dryRun: false + flags + confirmação + idempotency |
Real |
Freios operacionais (real)
| Operação | Env flag | confirmation no body |
Header |
|---|---|---|---|
| Cobrança split | BAAS_ALLOW_PAYMENT_CREATION=true |
"CRIAR COBRANCA" |
X-Idempotency-Key |
| Subconta | BAAS_ALLOW_SUBACCOUNT_CREATION=true |
"CRIAR SUBCONTA" |
X-Idempotency-Key |
| Cliente | BAAS_ALLOW_CUSTOMER_CREATION=true |
"CRIAR CLIENTE" |
|
| Transferência | BAAS_ALLOW_TRANSFER_CREATION=true |
"CRIAR TRANSFERENCIA" |
X-Idempotency-Key |
403 bloqueado (exemplo):
{
"ok": false,
"message": "Criação real de cobrança bloqueada. Configure BAAS_ALLOW_PAYMENT_CREATION=true e envie confirmation='CRIAR COBRANCA'."
}
Split payment: POST /api/payments/create-with-split
Cria cobrança com split[] na origem.
Request
curl -s -X POST https://app.kroz.co/api/payments/create-with-split \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Origin: https://app.kroz.co" \
-H "X-Idempotency-Key: split-ps0421-$(date +%s)" \
-d '{
"dryRun": true,
"tenantSlug": "incorp-piloto",
"contractReference": "PS-0421",
"customer": "cus_demo_comprador",
"billingType": "PIX",
"dueDate": "2026-07-15",
"value": 50000,
"installmentNumber": 2,
"description": "Jardim Oeste | PS-0421",
"externalReference": "KROZ-PS-0421-P02",
"split": [
{ "walletId": "wallet_terrenista_demo", "percentualValue": 18 },
{ "walletId": "wallet_vendas_demo", "percentualValue": 10 }
]
}'
Aceita split ou splits no body.
Formato split[]
Cada item: exatamente um campo de valor:
{ "walletId": "wal_...", "percentualValue": 18.0 }
Alternativas: fixedValue ou totalFixedValue (não combinar).
| Validação | Erro 400 |
|---|---|
| Sem walletId | Cada split precisa de walletId. |
| Wallet emissor | Não envie o walletId da própria conta emissora no split. |
| Múltiplos campos valor | Cada split deve usar exatamente um campo: fixedValue, totalFixedValue ou percentualValue. |
| % inválido | percentualValue deve ser maior que 0 e menor ou igual a 100. |
| Soma > 100% | A soma dos splits percentuais não pode ultrapassar 100%. |
SPE emissora = remainder implícito (não entra em split[] se for BAAS_OWN_WALLET_ID).
Payload enviado ao BaaS
{
"customer": "cus_...",
"billingType": "PIX",
"dueDate": "2026-07-15",
"description": "...",
"externalReference": "KROZ-PS-0421-P02",
"value": 50000.00,
"split": [
{ "walletId": "wal_terrenista", "percentualValue": 18 },
{ "walletId": "wal_vendas", "percentualValue": 10 }
]
}
billingType: PIX | BOLETO | CREDIT_CARD | UNDEFINED
Response dry-run 200
{
"ok": true,
"dryRun": true,
"idempotencyKey": "...",
"target": "{BAAS_BASE_URL}/payments",
"payload": { "...": "..." },
"rule_execution": { "...": "..." },
"warning": "BAAS_API_KEY ausente ou dryRun=true; nenhuma cobrança real foi criada."
}
Response real 200
{
"ok": true,
"idempotencyKey": "...",
"payment": { "id": "pay_...", "status": "PENDING" },
"paymentLink": "https://...",
"pixCopyPaste": "00020126..."
}
Pagadoria: POST /api/pagadoria-payment
Monta split[] automaticamente a partir de split_matrices.receivers.
Request
curl -s -X POST https://app.kroz.co/api/pagadoria-payment \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Origin: https://app.kroz.co" \
-d '{
"dryRun": true,
"pagadoriaType": "parcela",
"contractReference": "PS-0421",
"tenantSlug": "incorp-piloto",
"customerId": "cus_...",
"value": 50000,
"dueDate": "2026-07-15",
"brokerName": "Ana Corretora",
"agencyName": "Imob Parceira"
}'
| Campo | Obrigatório | Valores |
|---|---|---|
pagadoriaType |
✅ | sinal, entrada, pre_venda, parcela |
contractReference |
✅ | ex.: PS-0421 |
customerId |
✅ | ID do pagador no BaaS |
value |
✅ | > 0 |
dueDate |
✅ | ISO date |
tenantSlug |
✅* | *Ou KROZ_DEMO_MODE=true |
Response 200
{
"ok": true,
"dryRun": true,
"externalReference": "KROZ-PAG-...",
"payload": { "...": "..." },
"brokerCopy": "Cobrança parcela · PS-0421 · dry-run validado",
"matrix": { "spe": 72, "landbank": 18, "sales": 10 },
"fiscalRegime": "CPC_47_POC"
}
Subcontas: POST /api/receivers/create-subaccount
Cria recebedor na IP → retorna walletId + credenciais (única vez).
Campos obrigatórios
| Campo | Descrição |
|---|---|
name |
Razão social |
email |
E-mail principal |
cpfCnpj |
CNPJ 14 dígitos |
companyType |
MEI, LIMITED, INDIVIDUAL, ASSOCIATION |
mobilePhone |
Celular com DDD |
incomeValue |
Faturamento mensal |
address, addressNumber, province, postalCode |
Endereço |
Response real 200
{
"ok": true,
"dryRun": false,
"subaccount": {
"id": "acc_...",
"walletId": "wal_...",
"apiKey": "..."
},
"warning": "Guarde imediatamente apiKey e walletId. A apiKey da subconta é retornada uma única vez."
}
UI equivalente: Oficina de Recebedores.
Clientes: POST /api/customers/create
Pagador (comprador): não recebedor.
Confirmação real: "CRIAR CLIENTE" + BAAS_ALLOW_CUSTOMER_CREATION=true.
Transferências e sweep
POST /api/transfers/create
Confirmação: "CRIAR TRANSFERENCIA" + BAAS_ALLOW_TRANSFER_CREATION=true
Usado para sweep SPE pós-liquidação quando BAAS_AUTO_SWEEP_ENABLED=true.
Auto-sweep (webhook)
Ref: SWEEP-{externalReference} · Valor: payment.value × spe_percent / 100
Consultar pagamento: GET /api/payments/get
curl -s "https://app.kroz.co/api/payments/get?id=pay_xyz" \
-H "Authorization: Bearer $TOKEN"
Read-only: proxy para o endpoint de consulta do BaaS.
Variáveis de ambiente (completo)
# BaaS core
BAAS_API_KEY=
BAAS_ENV=sandbox # sandbox | production
BAAS_USER_AGENT=kroz.co/1.0.0
BAAS_BASE_URL= # URL base do parceiro
BAAS_OWN_WALLET_ID= # blocks issuer in split[]
BAAS_WEBHOOK_TOKEN=
BAAS_REQUEST_TIMEOUT_MS=15000 # 3000–30000
# Freios operacionais (default false)
BAAS_ALLOW_CUSTOMER_CREATION=false
BAAS_ALLOW_SUBACCOUNT_CREATION=false
BAAS_ALLOW_PAYMENT_CREATION=false
BAAS_ALLOW_TRANSFER_CREATION=false
BAAS_AUTO_SWEEP_ENABLED=false
# Plataforma
SUPABASE_URL=
SUPABASE_SERVICE_ROLE_KEY=
KROZ_DEMO_MODE=false # tenantSlug fallback "incorp-piloto"
Health check: GET /api/config-health
Envelope de erro padrão
{
"ok": false,
"error": "VALIDATION_ERROR",
"message": "Mensagem legível",
"details": { }
}
Código error |
Status típico |
|---|---|
VALIDATION_ERROR |
400 |
INVALID_INTERNAL_TOKEN |
401 |
ORIGIN_REQUIRED |
403 |
| Conflito idempotency | 409 |
| Timeout BaaS | 504 |
| BaaS indisponível | 502 |
Onboarding de novo parceiro BaaS
Checklist para homologação:
- Split nativo?: endpoint equivalente a
split[]na criação - Subcontas: API de onboarding por recebedor +
walletId - Webhooks: eventos de liquidação + auth header
- Idempotency: chaves de dedup
- Sandbox: homologar PS-0421 72/18/10
- Adaptador: implementar interface:
compileSplit(rule_version, amount) → BaaSSplitPayload
createPayment(payload, dryRun) → PaymentResult
createSubaccount(receiver, dryRun) → SubaccountResult
RC 16: rejeitar modelo B (P2P pós-cash-in) sem validação escrita.
Relacionado
- Webhooks: inbound liquidação
- Rule Engine: compilação matriz →
baas_split - Autenticação: sessão + idempotency
- Referência de API