kroz docs

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"
}

Ver Cobranças (Pagadoria).


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:

  1. Split nativo?: endpoint equivalente a split[] na criação
  2. Subcontas: API de onboarding por recebedor + walletId
  3. Webhooks: eventos de liquidação + auth header
  4. Idempotency: chaves de dedup
  5. Sandbox: homologar PS-0421 72/18/10
  6. 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