A API v3 do Asaas no localhost, com as regras de negócio capturadas do sandbox real. Avance dias e veja a cobrança acontecer sozinha: a assinatura cobra o cartão salvo no vencimento e retenta quando ele recusa, o boleto vence com multa e juros, o cartão cai em D+32, e cada webhook chega na sua máquina. Depure a máquina de estados de pagamento de ponta a ponta, em vez de chutar.
POST /v3/creditCard/tokenizeCreditCard 200 MASTERCARD 8829, token 4e0459fd…
PUT /_admin/credit-cards/4e0459fd… 200 {"approvalsLeft":3}
POST /v3/subscriptions 200 CREDIT_CARD R$ 129,90 MONTHLY primeiro vencimento 05/11
webhook PAYMENT_CREATED 200
05/11/2026
webhook PAYMENT_CONFIRMED 200
05/12/2026
webhook PAYMENT_CONFIRMED 200
05/01/2027
webhook PAYMENT_CONFIRMED 200
05/02/2027
webhookPAYMENT_CREDIT_CARD_CAPTURE_REFUSED
webhookPAYMENT_CREDIT_CARD_CAPTURE_REFUSED
webhookPAYMENT_CREDIT_CARD_CAPTURE_REFUSED cobrança ainda PENDING
06/02/2027
webhookPAYMENT_CREDIT_CARD_CAPTURE_REFUSED
webhookPAYMENT_CREDIT_CARD_CAPTURE_REFUSED
webhookPAYMENT_CREDIT_CARD_CAPTURE_REFUSED
webhook PAYMENT_OVERDUE 200
3 pagas, 6 tentativas recusadas, 1 vencida
Uma execução real da imagem: um cartão salvo configurado para aprovar três cobranças paga três faturas no vencimento; a quarta é recusada às 8h, 14h e 20h e mais três vezes no dia seguinte, como o Asaas retenta, e vence. Só o papel é desenhado.
Rode na sua máquina.
Quatro jeitos, do mais rápido ao mais completo. A imagem é pública: nenhum login.
Painel e API em localhost:45445, com o relógio virtual ligado. Com o mock do WhatsApp (porta 3010), o mock de SMS (porta 8899) e um Mailpit (porta 8025) no ar, ele acha os três sozinho e cada cobrança já avisa o pagador.
No seu docker-compose
Para subir junto com a sua aplicação, no compose dela. Nada para ligar: o Asaas acha o WhatsApp, o SMS e o Mailpit pelo nome do serviço.
Da sua aplicação: http://asaas:45445/v3. Os avisos ao pagador em localhost:8025 (e-mail), localhost:3010 (WhatsApp) e localhost:8899 (SMS).
Gerar do código
Para rodar a partir do código-fonte, ou depois de alterar o mock.
git clone https://github.com/Instituto-AMA/ama4devs.git
cd ama4devs
docker build -t asaas-mock mocks/asaas
docker run -d -p 45445:45445 -e CLOCK_MODE=VIRTUAL_FLOWING asaas-mock
Painel e API em localhost:45445; o WhatsApp, o SMS e o Mailpit, se estiverem no ar, ele acha sozinho
Subir tudo junto
Junto com o mock do WhatsApp, o mock de SMS e o Mailpit, já conectados: cada cobrança avisa o pagador por e-mail, por WhatsApp e por SMS.
git clone https://github.com/Instituto-AMA/ama4devs.git
cd ama4devs
make setup
Asaas em localhost:45445, WhatsApp em localhost:3010, SMS em localhost:8899, e-mails em localhost:8025
O relógio é o diferencial.
No sandbox real o tempo é real: um pagamento no cartão cai em 32 dias e um boleto vencido leva um dia para aparecer. Aqui cada dia simulado roda os jobs que o Asaas roda, em ordem, e você vê seu sistema reagir a meses de cobrança em segundos.
Cada dia, um tick
Assinaturas criam as próximas cobranças, 40 dias antes.
O cartão salvo é cobrado no vencimento às 8h, 14h e 20h, e retentado no dia seguinte.
Cobranças em aberto viram OVERDUE; a multa uma vez, os juros por dia.
Boleto cai em D+1 útil, cartão em D+32, débito em D+3.
Webhooks disparam e retentam no cronograma do próprio Asaas.
Lembretes e avisos ao pagador saem por e-mail, WhatsApp e SMS.
REAL: a hora da máquina, como o sandbox; o relógio não deixa pular.
VIRTUAL_FLOWING: o tempo corre, e você pula para a frente quando quiser. O padrão do compose do repositório.
VIRTUAL_FROZEN: o relógio só anda quando o teste manda. Feito para CI: a mesma execução dá o mesmo resultado.
Casos de uso.
Cenários que o seu código de pagamento precisa aguentar, cada um a poucas chamadas de distância. Eles partem do container do quick start: chave $aact_hmlg_local, relógio em VIRTUAL_FLOWING.
Um cartão salvo que paga três meses e falha no quarto
Prova a máquina de estados da sua assinatura de ponta a ponta, em vez de no chute: faturas pagas pelo cartão salvo no vencimento, e depois uma renovação recusada. O Asaas tenta o cartão às 8h, 14h e 20h no vencimento e mais três vezes no dia seguinte; cada recusa é um PAYMENT_CREDIT_CARD_CAPTURE_REFUSED com a cobrança ainda PENDING, depois PAYMENT_OVERDUE e nenhuma tentativa a mais. O seu app avisa o cliente na primeira recusa, mantém o acesso durante as retentativas e só suspende quando a cobrança vence?
# um cartão salvo que aprova três cobranças e depois recusa
curl -X PUT localhost:45445/_admin/credit-cards/<creditCardToken> \
-H 'content-type: application/json' -d '{"approvalsLeft":3}'
curl localhost:45445/v3/subscriptions -H 'access_token: $aact_hmlg_local' \
-H 'content-type: application/json' -d '{"customer":"cus_…","billingType":"CREDIT_CARD",
"value":129.9,"nextDueDate":"2026-11-05","cycle":"MONTHLY","creditCardToken":"<creditCardToken>",
"creditCardHolderInfo":{…},"remoteIp":"127.0.0.1"}'
curl -X POST localhost:45445/_admin/clock/advance -d '{"days":102}' -H 'content-type: application/json'
# de 27/10 a 06/02, o dia seguinte ao quarto vencimento:# → 3 × PAYMENT_CONFIRMED, depois 6 × PAYMENT_CREDIT_CARD_CAPTURE_REFUSED e PAYMENT_OVERDUE
Troque o cartão com PUT /v3/subscriptions/{id}/creditCard durante as retentativas e a próxima tentativa captura com o novo. O cronograma é configuração: CARD_CAPTURE_SCHEDULE ou a página de cartões de teste do painel.
Uma cobrança no cartão que cai 32 dias depois
Prova que o seu fluxo de pedido distingue PAYMENT_CONFIRMED (o cliente pagou) de PAYMENT_RECEIVED (o dinheiro é seu), e que a tela de saldo espera o segundo.
Prova que você cobra o que o Asaas cobra: a multa de 2% uma vez, no primeiro dia de atraso, e os juros de 1% ao mês pro rata sobre o mês comercial de 30 dias. R$ 120,00 pagos seis dias depois viram R$ 122,64.
curl localhost:45445/v3/payments -H 'access_token: $aact_hmlg_local' \
-H 'content-type: application/json' -d '{"customer":"cus_…","billingType":"BOLETO",
"value":120,"dueDate":"2026-12-02","fine":{"value":2},"interest":{"value":1}}'
curl -X POST localhost:45445/_admin/clock/advance -d '{"days":6}' -H 'content-type: application/json'
# → webhook PAYMENT_OVERDUE em 03/12
curl -X POST localhost:45445/v3/sandbox/payment/pay_…/confirm -H 'access_token: $aact_hmlg_local'
# → CONFIRMED, value 122.64; um dia depois, PAYMENT_RECEIVED
O seu webhook responde 204
Prova que o seu endpoint responde o que o Asaas aceita. Só HTTP 200 conta: 201 e 204 são falhas, a regra real. Uma entrega com falha é retentada 15 vezes na tabela do Asaas (na hora, +30 s, +1 min, +3 min 30 s, +5 min, +15 min, +25 min, +1 h cinco vezes, +2 h duas vezes, +3 h). Com SEQUENTIALLY, o evento de trás espera; depois da 15ª o webhook fica interrupted e a fila inteira para.
curl localhost:45445/_admin/webhooks/deliveries # cada tentativa, com o status e o corpo que o seu endpoint devolveu
Uma assinatura, um ano à frente
Prova a sua lógica de recorrência em doze ciclos, em segundos. A primeira cobrança nasce com a assinatura; as seguintes nascem 40 dias antes do vencimento, como no sandbox real.
No sandbox real, um cartão que recusa nunca vira token, então um cartão salvo sempre aprova. Aqui o cartão de teste 4000000000000341 tokeniza e depois recusa toda cobrança feita com o token, com o erro real (invalid_action, mesma frase): a renovação que falha meses depois, antes de acontecer em produção.
Prova que a sua divisão de um total bate com a do Asaas: a sobra do arredondamento vai para a última parcela, a taxa do cartão trunca (R$ 350 em 12x dá R$ 1,20 de taxa por parcela, não R$ 1,21), e no cartão a parcela n cai em D+32×n.
Todo evento de cobrança avisa o pagador por e-mail (no Mailpit), por um template de WhatsApp (no mock do WhatsApp) e por SMS (no mock de SMS, com o remetente ASAAS). Um parcelamento é avisado uma vez só. Suba o compose do repositório e abra as telas lado a lado.
O painel: veja o que a API real esconde.
Abra http://localhost:45445. Gerencie clientes, cobranças, pagamentos com cartão, webhooks, notificações e simule a passagem do tempo com o relógio virtual.
01/15
Zoom
Dashboard
Painel de Controle
Visão geral de cobranças por status com totais, carteiras e chaves de API.
Zoom
Clientes
Lista de Clientes
Gestão de pagadores com CPF/CNPJ, e-mail, celular e histórico financeiro.
Zoom
Cadastro
Criar Cliente
Cadastro rápido de clientes com validação de campos em tempo real.
Zoom
Cobranças
Cobranças e Faturas
Acompanhamento em tempo real de Pix, Boleto e cartão de crédito.
Zoom
Emissão
Criar Cobrança
Configure valor, vencimento, parcelamento, juros e forma de pagamento.
Zoom
Pagador
Link da Fatura
A tela pública em invoiceUrl com simulação de pagamento pelo pagador.
Zoom
Pix
Pagamento Instantâneo Pix
QR Code dinâmico com payload EMV real e confirmação instantânea.
Zoom
Boleto
Boleto Bancário
Fatura com linha digitável válida e visualização para impressão.
Zoom
Webhooks
Webhooks e Integrações
Endpoints cadastrados, token de autenticação e status da fila.
Zoom
Assinaturas
Criar Webhook
Seleção de eventos de cobranças, transferências e assinaturas.
Zoom
Entregas
Logs de Webhooks
Inspeção detalhada de payloads enviados, respostas HTTP e retentativas.
Zoom
Auditoria
Logs de Requisições
Histórico de todas as chamadas HTTP recebidas pelo mock server.
Zoom
Simulação
Relógio Virtual
Avance o tempo na mão para testar vencimentos, juros e liquidação.
Zoom
Cartões
Cartões de Teste
Cartões para simular aprovação, recusa, limite insuficiente e roubo.
Zoom
Financeiro
Extrato e Saldo
Lançamentos completos com desconto de taxas e saldo conciliado.
As regras foram capturadas do sandbox do Asaas, e uma suíte de paridade as reproduz campo a campo, até o conjunto exato de chaves de cada objeto. A captura derrubou 20 regras que a documentação sugere. Toda operação da especificação oficial responde: 135 de 213 com motor de negócio, o resto com 501 nomeando a operação, nunca dado falso.