Pular para o conteúdo

Integracao Asaas (PIX + boleto + cartao Brasil)

Asaas e o provider de pagamento brasileiro do Studeia: PIX (95% do mercado), boleto bancario, cartao nacional. Webhooks fail-closed, customer split por provider, integracao paralela com Stripe (USD/cartao internacional).

2026-05-24 5 min
Resposta curta

Asaas e provider brasileiro de pagamento do Studeia: PIX instantaneo (1.99% taxa), boleto (R$3.49), cartao nacional (4.99% + R$0.49). Para clientes BR e mais barato e nativo que Stripe. Webhooks fail-closed (503 se token ausente). Customer split por provider (stripeCustomerId vs asaasCustomerId). Para internacional: Stripe USD em paralelo.

Setup

1. Asaas Dashboard

  1. https://asaas.com (ou sandbox: https://sandbox.asaas.com)
  2. Configuracoes > Integracoes > API > copie Access Token
  3. Configuracoes > Webhooks > Add:
    • URL: https://[tenant].studeia.com/api/webhooks/asaas?token=<SEU_TOKEN>
    • Eventos: PAYMENT_RECEIVED, PAYMENT_OVERDUE, PAYMENT_REFUNDED, SUBSCRIPTION_CREATED/UPDATED/DELETED
  4. Customize token (string aleatoria, criptograficamente forte)

2. Env vars

ASAAS_API_KEY=$aact_...
ASAAS_WEBHOOK_TOKEN=...gerado-no-passo-3...
ASAAS_SANDBOX=true  # opcional, default false

3. Criar produtos no Asaas

Asaas usa modelo de cobrança recorrente diferente do Stripe. Em Studeia, planos sao mapeados via codigo (nao precisa criar product no Asaas dashboard).

Fluxo PIX

Admin clica "Pagar com PIX" em /institution/billing
  ↓
POST /api/institution/billing/checkout
  Body: { planSlug: "mini", provider: "asaas" }
  ↓
Studeia AsaasBillingProvider.createCheckout():
  1. Resolve asaasCustomerId (cria se nao existe — POST /customers)
  2. POST /subscriptions com billingType=PIX
  3. Asaas retorna QR Code + copy-paste payload PIX
  4. Studeia retorna { url } pagina hosted Asaas com QR
  ↓
Admin escaneia QR no app bancario, paga
  ↓
PIX confirma em ~30s (instantaneo)
  ↓
Webhook PAYMENT_RECEIVED → applyWebhookEvent → promove Tenant.plan

Hardening (regras 138, 139)

  • Fail-closed: ausencia de ASAAS_WEBHOOK_TOKEN env = 503 asaas_not_configured (regra 138). Anti-bypass.
  • Token validation: query param ?token=<...> comparado com env (timing-safe comparison)
  • 5xx em falha: re-tenta automaticamente
  • PaymentLog idempotente: unique [provider, externalEventId]
  • PII redact: rawPayload passa por redactPaymentPayload() — remove cpfCnpj, email, name, address, billing_details (regra 139)

Customer split por provider

TenantSubscription tem campos separados:

  • stripeCustomerId — para Stripe
  • asaasCustomerId — para Asaas
  • externalCustomerId — legado (mantido como fallback se provider bater)

resolveCustomerIdForProvider() em create-checkout.ts usa novos campos — NUNCA reuse ID cross-provider.

Quando usar Asaas vs Stripe

CenarioRecomendado
Cliente brasileiro com PIXAsaas
Cliente brasileiro com boletoAsaas
Cliente brasileiro com cartaoAsaas (mais barato) ou Stripe
Cliente internacionalStripe USD obrigatorio (Asaas bloqueado)
Conta empresarial enterprise grandeStripe (mais ferramentas — Sigma, custom reports)

Taxas comparadas

MetodoAsaasStripe
PIX1.99%NAO oferece nativo
BoletoR$3.49 fixoNAO oferece nativo
Cartao credito4.99% + R$0.493.99% + R$0.59 (USD)
Cartao debito1.99% + R$0.39NAO oferece (BR)
Antecipacao recebivelDisponivelNAO

Para volume B2B brasileiro tipico: Asaas e ~20-40% mais barato em taxas totais.

Veja tambem

FAQ

Por que Asaas e nao so Stripe?

Para mercado brasileiro: 95% das transacoes B2B usam PIX (instantaneo, sem taxa) ou boleto. Stripe nao tem PIX nativo (oferece via 3rd parties mais caras). Asaas e brasileiro, integra PIX/boleto/cartao nacional nativamente com taxas menores (1.99% PIX, R$3.49 boleto, 4.99% cartao + R$0.49 vs Stripe 3.99% + R$0.59).

Studeia detecta automaticamente qual provider usar?

Sim. getCurrencyFromHeaders() server-side via x-vercel-ip-country / cf-ipcountry: BR = Asaas oferecido na UI (PIX/boleto/cartao). Fora do BR = Stripe USD obrigatorio (Asaas bloqueado server-side com 400 'asaas_not_for_international').

Webhooks Asaas sao seguros?

Sim, mas com hardening. Token via query param ASAAS_WEBHOOK_TOKEN. Sem token configurado: webhook retorna 503 asaas_not_configured (fail-closed — regra 138). Idempotencia via PaymentLog unique. Asaas re-tenta com backoff em case de 5xx.

Posso testar Asaas em sandbox?

Sim, Asaas tem ambiente sandbox separado: https://sandbox.asaas.com. Token e API key sao separados. Configure ASAAS_SANDBOX=true no env pra rotear para sandbox endpoint.

Veja tambem

Integracao Asaas (PIX + boleto + cartao Brasil) | Studeia Docs