O cara escolheu o produto, preencheu os dados, clicou em pagar, gerou o PIX. E sumiu. Vinte minutos depois o código venceu. No dia seguinte, às nove da manhã, sua automação de recuperação de PIX pendente no WhatsApp dispara a mensagem: "oi, vi que você não finalizou sua compra, ficou com alguma dúvida?".
Dúvida nenhuma. Ele não tinha dúvida, ele tinha um código na mão e não conseguiu pagar. Estava no computador com o app do banco no celular, ou bateu no limite noturno, ou copiou errado, ou foi atender alguém e esqueceu. A mensagem chegou tarde, chegou com o tom errado e chegou com um link que aponta pra uma cobrança morta.
Isso acontece porque a maior parte das ferramentas trata "PIX gerado e não pago" e "olhou a página e foi embora" como o mesmo estado: não comprou. Aí ambos caem na mesma esteira, com o mesmo campo "esperar X horas" e o mesmo texto de quebra de objeção. É o erro que mais custa dinheiro na recuperação de infoproduto, porque o PIX pendente é o lead mais quente que existe no seu funil e você está tratando ele como quem passou na vitrine.
A resposta curta
São duas máquinas de estado diferentes, com relógios opostos.
Carrinho abandonado é intenção sem compromisso. O relógio conta pra frente a partir do abandono (30 minutos, 4 horas, 24 horas), nada expira, e o trabalho da mensagem é convencer.
PIX pendente é compromisso com prazo. O relógio conta pra trás a partir da expiração da cobrança, o objeto central (o código) morre na hora marcada, e o trabalho da mensagem não é convencer, é tirar obstáculo do caminho. Ele já disse sim. Falta ele conseguir executar.
Isso muda cinco coisas concretas: o gatilho que abre a régua, a âncora do agendamento, a quantidade de toques, o texto de cada toque e a condição de parada. Se a sua ferramenta só oferece "aguardar N horas depois do evento", ela não sabe fazer PIX, ela sabe fazer abandono e está reciclando a régua.
Os dois estados não são o mesmo estado
Vale separar friamente o que o lead já fez em cada caso:
- Abandono: ele não decidiu. O obstáculo é preço, confiança, comparação, "depois eu vejo". Nada tem validade, o link de checkout continua vivo amanhã e semana que vem. Recuperar aqui é trabalho de persuasão.
- PIX pendente: ele decidiu, aceitou o preço, digitou o CPF e pediu a cobrança. O obstáculo é operacional: saldo, limite, dispositivo errado, app do banco pedindo aprovação, distração. Existe um objeto com hora da morte. Recuperar aqui é trabalho de logística.
Grava essa frase, porque ela decide todo o resto do desenho: abandono é problema de convencimento, PIX pendente é problema de execução. Mandar argumento de venda pra quem já comprou mentalmente é ruído. Pior, é ruído que faz o cara reabrir a decisão que ele já tinha fechado.
O gatilho: qual evento abre cada régua
Na Hotmart, abandono e PIX pendente chegam por eventos diferentes, e o de PIX é compartilhado com boleto. O evento de aguardando pagamento cobre os dois métodos, então o nome do evento sozinho não te diz nada. Você precisa ler o método de pagamento e o status dentro do payload. Em formato geral, mascarado:
{
"event": "PURCHASE_BILLET_PRINTED",
"data": {
"purchase": {
"transaction": "HP*********90",
"status": "WAITING_PAYMENT",
"order_date": 1756996400000,
"payment": {
"type": "PIX",
"pix_expiration_date": 1757000000000
}
},
"buyer": { "name": "M*****", "phone": "+5541*****9999" }
}
}
Os nomes exatos dos campos variam com a versão da API e com a plataforma de checkout, então confira no payload que você recebe antes de escrever qualquer regra. O que importa é o par: status em espera de pagamento mais type igual a PIX. Se você ramifica só pelo nome do evento, o boleto (que vive dias) cai na mesma régua do PIX (que vive minutos) e vira bagunça. Se quiser o mapa completo de quais eventos existem e o que fazer com cada um, escrevi isso em webhook da Hotmart: todos os eventos e o que fazer com cada um.
O campo mais valioso desse payload é a data de expiração. Ela é a âncora da régua inteira. Se a sua plataforma não manda esse campo, você precisa saber de cor qual janela está configurada no seu checkout e calcular a expiração no seu lado. A especificação do PIX de cobrança imediata usa um campo de expiração em segundos, com padrão de 86400 (24 horas) quando não é informado, mas quase todo checkout de infoproduto encurta isso pra algo entre 15 minutos e 24 horas. Vá no painel e olhe qual é o seu número, porque toda a régua depende dele.
A régua de PIX conta o tempo ao contrário
Régua de abandono é uma lista de esperas a partir do evento: mais 30 minutos, mais 4 horas, mais 24 horas. Simples de agendar, porque o ponto zero é a única coisa que existe.
Régua de PIX é ancorada no fim. Você recebe o evento, calcula a janela de vida do código e distribui os toques dentro dela em proporção, não em valor fixo:
const agora = Date.now();
const janela = expiraEm - agora; // vida útil do código, em ms
const toques = [
{ quando: agora + 0.08 * janela, tipo: 'reenvio_codigo' },
{ quando: agora + 0.45 * janela, tipo: 'ajuda_operacional'},
{ quando: expiraEm - 15 * 60000, tipo: 'ultimo_aviso' },
];
Repare no terceiro toque: ele não é uma espera, é uma contagem regressiva a partir da expiração. Numa janela de 1 hora, essa régua vira 5 minutos, 27 minutos e 45 minutos. Numa janela de 24 horas, vira 2 horas, 11 horas e 23h45. O mesmo esqueleto, esticado. É por isso que amarrar toque em valor fixo ("sempre 3 horas depois") quebra: com janela de 30 minutos você nunca manda nada, e com janela de 24 horas você manda tudo de madrugada e some no dia seguinte.
Três toques é o teto razoável dentro da janela. Não é regra sagrada, é consequência de duas coisas: a mensagem de PIX é curta e repetitiva por natureza (você está basicamente reenviando um código), e o WhatsApp castiga quem manda três mensagens seguidas em quinze minutos pra alguém que não respondeu. Se a sua janela é de 15 ou 20 minutos, faça dois toques, ou até um só. Densidade de toque é função do tamanho da janela, não da sua ansiedade.
Horário: quando a janela é curta, aceite a perda
Quiet hours é o ponto onde as duas réguas divergem de novo. Na de abandono é fácil: chegou às 2h da manhã, você segura e dispara às 9h, não perdeu nada, o link não vence.
Na de PIX não dá pra segurar uma coisa que morre em 40 minutos. Você tem duas saídas honestas. Se a janela é curta (menos de 2 horas) e o PIX nasceu de madrugada, não mande nada: deixe expirar e trate no dia seguinte pela régua de expirado, com cobrança nova. Se a janela é longa (12 ou 24 horas), empurre os toques pra faixa útil mais próxima possível da expiração, mesmo que isso comprima os três num intervalo menor.
E tem o detalhe brasileiro que ninguém programa: desde 2021 o Banco Central mantém um limite noturno padrão de R$ 1.000 pra transferências entre pessoas físicas das 20h às 6h (o usuário pode pedir ao banco pra o período começar às 22h). Se o seu ticket é R$ 1.497 e o cara gerou o PIX às 21h, ele pode literalmente não conseguir pagar hoje, por mais que queira. Nenhuma mensagem de "corre que vai vencer" resolve isso. A régua certa ali é oferecer cobrança nova pra manhã seguinte, não insistir três vezes na mesma noite.
O texto muda porque o obstáculo é outro
Na régua de abandono você escreve pra vencer objeção: prova, garantia, resposta a dúvida, eventualmente uma condição melhor.
Na régua de PIX pendente você escreve pra reduzir cliques. O objetivo de cada toque é diminuir o trabalho que falta pra ele pagar. Três decisões práticas que fazem diferença:
- Mande o copia e cola numa mensagem separada, sozinho. No WhatsApp, copiar uma mensagem copia a mensagem inteira. Se você grudar "aqui está seu código: 00020126..." num parágrafo só, o cliente cola no app do banco com o texto junto e dá erro. Uma mensagem curta explicando, outra mensagem contendo só o código.
- Faça perguntas que se respondem com uma palavra. "Quer que eu gere um código novo?" é melhor que "posso te ajudar em algo?", e não só por conversão: qualquer resposta do cliente abre a janela de conversa e te dá liberdade de texto livre por 24 horas.
- Não dê desconto em PIX pendente. Nunca. A pessoa já aceitou o preço, o obstáculo não é preço, e você acabou de ensinar todo mundo que travar o pagamento por 20 minutos vale 10% de abatimento. Fora que quem pagou na hora vai descobrir e pedir a diferença. Desconto, se for usar, é da régua de expirado pra frente, como oferta nova.
Tem uma restrição técnica que decide o texto antes de você escrever a primeira palavra: quem inicia a conversa. Se você opera na Cloud API oficial e o cliente nunca te mandou mensagem, você não pode escrever livre, precisa de um template utilitário já aprovado, com variáveis. A documentação da Meta hoje diz que mensagens não-template dentro de uma janela de atendimento aberta são gratuitas, e que template utilitário entregue dentro dessa janela também é gratuito; fora da janela, o utilitário é cobrado. A Meta mexe nessa tabela com frequência, então confira a atual antes de dimensionar custo por toque. Numa stack não oficial (Baileys, Evolution API) você escreve o que quiser, mas paga em risco de bloqueio de número. Já comparei os dois caminhos em Evolution API vs Cloud API vs Baileys, e pra régua de PIX o ponto crítico é esse: template não improvisa, então você aprova antes os textos dos três toques, com o código como variável.
A condição de parada é a parte que mais quebra
Régua de abandono errando o ponto de parada é chato. Régua de PIX errando é grave: você manda "seu pagamento está pendente, corre que vai vencer" pra quem pagou dez minutos atrás. O cara acha que pagou errado, pagou duas vezes, ou foi golpe. Aí não é venda perdida, é reembolso pedido e reputação queimada.
A tentação é resolver isso cancelando o agendamento quando chega a confirmação de pagamento. Faça isso, mas não confie nisso. Cancelamento de job é frágil por natureza: o worker pode já ter puxado a tarefa, o webhook de aprovado pode estar atrasado na fila, sua instância pode ter reiniciado no meio. A trava que funciona é checar o estado no instante do envio, não no agendamento:
// roda no worker, no momento exato do disparo
async function enviarToque(transacao, toque) {
const pedido = await db.getPedido(transacao);
if (pedido.status !== 'WAITING_PAYMENT') return; // pagou, cancelou ou expirou
if (pedido.expiraEm <= Date.now()) return; // código já morreu
if (await jaEnviou(transacao, toque)) return; // idempotência do toque
await marcarEnviado(transacao, toque); // marca ANTES de enviar
await enviarWhatsApp(pedido.telefone, montar(toque, pedido));
}
Três guardas, cada uma tapando um buraco diferente. A primeira mata a corrida clássica: o pagamento cai três segundos antes do seu último aviso e o evento ainda está na fila. Por isso, aliás, o toque final fica uns 15 minutos antes da expiração, e não 60 segundos antes: você compra folga pro webhook de aprovação chegar e atualizar o estado. A segunda evita mandar código morto. A terceira é idempotência de toque, que importa porque plataforma de checkout reenvia webhook e um mesmo pedido pode gerar o mesmo evento várias vezes. Se esse ponto é novo pra você, o mecanismo está detalhado em idempotência em webhook: nunca mandar a mesma mensagem duas vezes.
Repare também na ordem: marcar como enviado antes de chamar a API de mensagem. Se a API falhar, você perdeu um toque; se você marcasse depois e o processo caísse no meio, você mandaria de novo. Entre perder um toque e duplicar cobrança pro cliente, perder é o erro barato.
Essa separação de estados (aguardando pagamento com PIX, expirado, abandono), cada um com relógio, número de toques e condição de parada próprios, é exatamente o desenho que o Recupera, o motor de recuperação que eu mantenho, usa por dentro: o agendamento é derivado da expiração e a checagem de estado acontece no disparo, não no agendamento. Mas nada disso depende de ferramenta minha. É uma tabela de estados, uma fila com agendamento e três if antes de enviar.
PIX expirado é um terceiro estado, não o quarto toque
Depois que o código vence, você não está mais numa régua de PIX. O objeto que ancorava tudo deixou de existir e mandar o mesmo link de novo só entrega uma tela de erro pro cliente.
O estado expirado abre uma régua própria, e essa sim parece com abandono: ritmo em horas, texto de persuasão, uma cobrança nova gerada (não a antiga reciclada) e, se fizer sentido pro seu negócio, uma condição diferente. É aqui que o desconto pode entrar, se entrar. E é aqui que faz sentido perguntar de verdade o que aconteceu, porque agora existe chance real de o motivo ter sido dúvida, e não limite de banco.
O que dá errado
- Reciclar a régua de abandono com outro texto. O sintoma é fácil de reconhecer: seus toques de PIX são configurados em horas fixas. Se são horas fixas, não estão ancorados na expiração, e uma hora vão disparar depois do código morrer.
- Ancorar o último toque no evento em vez de na expiração. Parece detalhe, é o coração. "3 horas depois do PIX gerado" e "15 minutos antes de vencer" são a mesma coisa em exatamente uma configuração de janela, e coisas diferentes em todas as outras.
- Comprimir toque demais numa janela curta. Três mensagens em quinze minutos pra quem não respondeu nenhuma não é urgência, é comportamento de robô de spam. O WhatsApp lê isso, o cliente também.
- Checar o estado só no agendamento. É o caminho direto pra cobrar quem já pagou. Cheque no envio, sempre, mesmo que você também cancele o job.
- Tratar boleto e PIX na mesma ramificação. O evento de aguardando pagamento cobre os dois, mas boleto vive dias e PIX vive minutos. Mesma régua nos dois é sempre errada pra um deles.
- Achar que quem não pagou em 5 minutos desistiu. Limite noturno, aprovação no app do banco, PC sem o app, saldo que entra amanhã. Fricção não é desistência, e é justamente isso que a régua de PIX existe pra resolver.
- Não separar a métrica. Se o seu relatório mostra "vendas recuperadas" num número só, você não sabe se está recuperando PIX (fácil, quase logística) ou abandono (difícil, persuasão). Contadores separados por estado, senão o número é fumaça e você não tem como saber qual régua ajustar.
E o quando não usar: se o seu ticket é baixo e a janela de PIX é de 15 minutos, o custo de mensagem pode comer a margem antes de a régua se pagar. Faça a conta por toque antes de montar. No outro extremo, se a sua cobrança tem vencimento longo, tipo dias, aquilo não é régua de PIX pendente, é régua de cobrança, e o desenho certo é outro (lembretes espaçados, não contagem regressiva).
Fechando
A diferença toda cabe numa pergunta: o que está impedindo essa pessoa de pagar agora? Se for a cabeça dela, você está no carrinho abandonado e o remédio é argumento espalhado no tempo. Se for a mão dela, você está no PIX pendente e o remédio é código reenviado, mensagem curta e um relógio que conta pra trás a partir da expiração.
Quem monta as duas réguas como se fossem uma perde nos dois lados: manda argumento pra quem já decidiu e manda urgência pra quem nem escolheu ainda. Separar os estados dá umas duas horas de trabalho no seu fluxo. É provavelmente a melhor troca de tempo por dinheiro que existe na recuperação de venda de infoproduto.
Fontes primárias consultadas na escrita: documentação de webhook e tabela de status de transação da Hotmart (status WAITING_PAYMENT e evento de aguardando pagamento cobrindo boleto e PIX), especificação de cobrança imediata do PIX (campo de expiração em segundos, padrão de 86400), documentação de preço da WhatsApp Business Platform (janela de atendimento de 24 horas e template utilitário) e regra do Banco Central sobre limite noturno padrão de R$ 1.000 entre 20h e 6h.