7.5 KiB
Integração Asaas Payment Gateway - AgendaPRO
Este documento serve como guia técnico ("Skill") para a integração do gateway de pagamento Asaas na plataforma SaaS multi-tenant AgendaPRO. Ele detalha os fluxos de trabalho, estruturas de API, segurança do Webhook e regras de conciliação financeira em banco de dados PostgreSQL.
1. Visão Geral da Arquitetura
A integração é baseada no modelo SQL-First, onde o banco de dados PostgreSQL é a única fonte da verdade. O mapeamento é feito associando os IDs internos do sistema (UUID) ao campo externalReference fornecido pela API do Asaas.
sequenceDiagram
participant Cliente/Tenant as App/Painel (AgendaPRO)
participant Lib as Serviço Asaas (src/lib/asaas.ts)
participant Asaas as Asaas API (Sandbox/Prod)
participant DB as PostgreSQL
Cliente/Tenant->>Lib: Solicita Cobrança/Assinatura
Lib->>DB: Busca Configuração do Tenant (API Key)
DB-->>Lib: Retorna Configuração do Tenant
Lib->>Asaas: POST /v3/payments (ou /subscriptions) com externalReference
Asaas-->>Lib: Retorna Dados da Transação (ID do Asaas)
Lib-->>Cliente/Tenant: Retorna Link/QR Code Pix para o Cliente
2. Ambientes e Autenticação
O Asaas possui dois ambientes distintos. As chaves de API (API Keys) geradas no Sandbox não funcionam em Produção e vice-versa.
| Ambiente | URL Base da API v3 | Variável de Ambiente |
|---|---|---|
| Sandbox (Homologação) | https://api-sandbox.asaas.com/v3 |
ASAAS_API_KEY (Prefixo de teste) |
| Produção | https://api.asaas.com/v3 |
ASAAS_API_KEY |
Cabeçalhos HTTP Obrigatórios
Todas as chamadas à API devem conter:
access_token: Sua chave de API do Asaas (específica para o tenant ou plataforma).Content-Type:application/json.User-Agent: Nome da aplicação (ex:AgendaPRO-Integration).
3. Fluxo de Clientes (Customers)
Antes de emitir qualquer cobrança ou assinatura, o cliente (consumidor final) deve ser cadastrado no Asaas. O ID do cliente retornado (cus_...) deve ser salvo no banco local (ex: no cadastro de inquilino/tenant ou no cadastro de cliente do estabelecimento).
- Endpoint:
POST /v3/customers - Payload Exemplo:
{ "name": "João Mendes", "cpfCnpj": "00000000000", "email": "joao@email.com", "phone": "11999991234", "mobilePhone": "11999991234", "externalReference": "local-client-uuid", "notificationDisabled": false } - Response de Sucesso: Retorna o objeto do cliente contendo o
"id": "cus_000005219613".
4. Fluxo de Cobranças Avulsas (Payments - Pix/Boleto/Cartão)
Usado para pagamentos individuais, como a cobrança por um agendamento específico.
- Endpoint:
POST /v3/payments - Payload Exemplo (Pix/Boleto):
{ "customer": "cus_000005219613", "billingType": "PIX", "value": 55.00, "dueDate": "2026-06-10", "description": "Corte Masculino - Barbearia Premium", "externalReference": "local-payment-uuid" } - Response de Sucesso: Retorna o ID da transação (ex:
"id": "pay_080225913252").
Obtenção do QR Code Dinâmico Pix
Se a cobrança for do tipo PIX, você pode buscar a imagem em Base64 e a linha digitável ("copia e cola"):
- Endpoint:
GET /v3/payments/{id}/pixQrCode(Sem corpo na requisição) - Response Exemplo:
{ "encodedImage": "iVBORw0KGgoAAAANSUhEUgAA...", "payload": "00020101021126660014br.gov.bcb.pix...", "expirationDate": "2026-06-10T23:59:59Z" }
5. Fluxo de Assinaturas Recorrentes (Subscriptions)
Usado pelo SaaS para cobrar a mensalidade do próprio inquilino (Tenant) ou pelos inquilinos para oferecer planos recorrentes.
- Endpoint:
POST /v3/subscriptions - Payload Exemplo (Cartão de Crédito):
{ "customer": "cus_0T1mdomVMi39", "billingType": "CREDIT_CARD", "nextDueDate": "2026-07-03", "value": 99.90, "cycle": "MONTHLY", "description": "Assinatura AgendaPRO - Plano Professional", "externalReference": "local-subscription-uuid", "creditCard": { "holderName": "TITULAR DO CARTAO", "number": "0000000000000000", "expiryMonth": "12", "expiryYear": "2030", "ccv": "123" }, "creditCardHolderInfo": { "name": "TITULAR DO CARTAO", "email": "titular@email.com", "cpfCnpj": "00000000000", "postalCode": "01310000", "addressNumber": "123", "phone": "11999991234" } }
6. Webhook e Segurança
O webhook do Asaas garante a conciliação automática do status de pagamentos de forma assíncrona.
Validação de Autenticidade (Signature)
Diferente de gateways que usam assinaturas HMAC, o Asaas utiliza um Token de Acesso Simples configurado na interface do webhook.
- Configure um Token Secreto no Painel do Asaas (ou salve em
settingsno banco local do tenant). - O Asaas enviará este token no cabeçalho
asaas-access-tokenem cada requisição de Webhook. - A aplicação deve validar:
req.headers.get('asaas-access-token') === webhookSecret.
Estrutura de Payload do Webhook
{
"id": "evt_05b708f961d739ea7eba7e4db318f621",
"event": "PAYMENT_RECEIVED",
"dateCreated": "2026-06-03 20:20:00",
"payment": {
"id": "pay_080225913252",
"customer": "cus_000005219613",
"subscription": "sub_VXJBYgP2u0eO",
"value": 100.00,
"netValue": 95.00,
"externalReference": "local-payment-uuid",
"billingType": "PIX",
"confirmedDate": "2026-06-03"
}
}
Eventos Críticos a Processar
PAYMENT_RECEIVED/PAYMENT_CONFIRMED: Pagamento efetuado com sucesso.PAYMENT_REFUNDED: Pagamento estornado pelo painel ou pelo banco.PAYMENT_OVERDUE: Vencimento expirado sem quitação.PAYMENT_DELETED: Cobrança removida manualmente.SUBSCRIPTION_DELETED/SUBSCRIPTION_CANCELLED: Cancelamento de recorrência.
7. Estrutura do Código Implementado
A. Camada de Serviço (src/lib/asaas.ts)
Fornece funções isoladas e parametrizadas que realizam as chamadas seguras para a API, respeitando a separação de chaves por inquilino (tenant_id).
B. Handler de Webhook (src/app/api/webhooks/asaas/route.ts)
Endpoint público que recebe requisições do Asaas. Executa os seguintes passos:
- Valida o token
asaas-access-tokencontra o token do Tenant (se enviado com?tenant_id=...) ou contra o token mestre do sistema. - Cria e utiliza a tabela
asaas_webhook_eventspara garantir idempotência (ignora eventos duplicados). - Atualiza o status financeiro local em uma transação segura (
BEGIN/COMMIT).
8. Guia de Teste no Sandbox
- Configuração de Chaves:
- Vá em Asaas Sandbox > Minha Conta > Integrações.
- Gere uma chave de API e insira o webhook apontando para a sua URL pública exposta pelo Ngrok/Cloudflare Tunnel (ex:
https://seu-dominio.trycloudflare.com/api/webhooks/asaas?tenant_id=UUID-DO-TENANT).
- Simulação de Pagamentos:
- Crie uma cobrança do tipo Pix/Boleto pela API.
- Acesse o painel de Sandbox do Asaas.
- Procure a cobrança emitida e clique em Confirmar Recebimento (Botão de teste que simula o pagamento do cliente).
- Validação de Banco de Dados:
- Execute:
SELECT status, paid_at FROM payments WHERE id = 'seu-uuid'; - Verifique se o status mudou para
completede a colunapaid_atfoi preenchida corretamente.
- Execute: