"Quero cobrar assinatura mensal automática" é uma das perguntas mais comuns de dev integrando PixGo. A resposta curta: a PixGo não tem endpoint nativo de subscription (tipo Stripe Subscriptions), e a cobrança da PixGo é sempre um PIX comum: o Pix Automático do Banco Central existe, mas a PixGo não opera com ele — cada cobrança precisa do cliente confirmando o pagamento. Mas dá pra implementar recorrência de forma robusta. Esse guia mostra dois caminhos: a API direta + o módulo pronto de cobrança recorrente Pix.

Em resumo
  • Não é débito automático: o Pix Automático do Banco Central existe, mas a cobrança recorrente da PixGo funciona por cobrança a cada ciclo — o cliente paga cada uma
  • 2 caminhos: módulo pronto /recurrence (sem código) ou rotina custom via API
  • Custom: cron job + POST /payment/create no vencimento + retry/grace period
  • Notificação ao cliente: WhatsApp/email com link de pagamento N dias antes
  • Tratar churn: política clara de "não pagou em N dias → suspende"

Por que a cobrança PixGo não é débito automático

Antes de implementar, entenda o modelo: a PixGo trabalha com o PIX comum, em que o lojista não debita a conta do cliente. Cada PIX exige:

  • QR Code (ou Copia-e-Cola) gerado pelo lojista
  • Cliente abrindo o app do banco dele
  • Cliente escaneando/colando e confirmando o pagamento

É assim que o PIX comum funciona, cobrança a cobrança. O que a PixGo entrega é uma recorrência facilitada: o sistema gera a cobrança automaticamente a cada ciclo, avisa o cliente, e ele paga o PIX.

"E o Pix Automático do Banco Central?" Ele existe desde 2025 e permite débito recorrente autorizado pelo pagador. A PixGo não oferece essa modalidade: a cobrança recorrente da PixGo funciona por cobrança a cada ciclo — o assinante recebe o aviso por e-mail e paga o Pix.

Cobre mensalidades e assinaturas por Pix, com lembrete por e-mail antes de cada vencimento. Conheça a cobrança recorrente Pix.

Criar conta

Caminho 1 — Módulo /recurrence pronto (sem código)

Se você não quer programar, a PixGo tem um módulo completo de cobrança recorrente Pix com:

  • Cadastro de plano (valor, frequência: mensal/semanal/anual)
  • Cadastro de cliente (nome, email, telefone, CPF)
  • Geração automática de QR no vencimento
  • Notificação por email/WhatsApp (configurável)
  • Página de gestão de assinaturas (status, pagamentos passados, suspender, reativar)
  • Link público de "Assinar" que o cliente acessa pra entrar no plano

Resolve 80% dos casos sem precisar tocar em código. Veja o vídeo introdutório no Guia PixGo.

Caminho 2 — Recorrência custom via API

Se você precisa de regras específicas (multi-tenant, integração com seu produto, lógica de upgrade/downgrade, gestão complexa de churn), constrói via API. A estrutura básica:

Calendário com 4 meses mostrando cobrança recorrente automática conectada por uma engrenagem
O ciclo: cron job mensal → cria QR → cliente paga ativamente → webhook → renova.

Modelo de dados mínimo

Você precisa de 3 tabelas no seu banco:

subscriptions
  - id
  - customer_id (referência a quem assina)
  - plan_id (referência ao plano)
  - status: active | past_due | suspended | canceled
  - next_billing_date
  - created_at, canceled_at

plans
  - id
  - name
  - amount (em reais)
  - interval: monthly | weekly | annual
  - grace_days: dias de tolerância antes de suspender

invoices
  - id
  - subscription_id
  - payment_id (UUID retornado pela PixGo)
  - external_id (seu ID)
  - amount, due_date
  - status: pending | paid | overdue | canceled
  - paid_at

Lógica de cron (roda 1×/dia, recomendado às 8h)

// Pseudocódigo do cron diário
function runDailyBilling() {
    $hoje = date('Y-m-d');
    $vencendoHoje = db.query("SELECT * FROM subscriptions
        WHERE status='active' AND next_billing_date <= ?", [$hoje]);

    foreach ($vencendoHoje as $sub) {
        // 1. Cria invoice no seu banco
        $invoice = createInvoice($sub);

        // 2. Chama API PixGo
        $resp = callPixgoApi('POST', '/payment/create', [
            'amount' => $sub->plan->amount,
            'description' => "Mensalidade {$sub->plan->name}",
            'external_id' => $invoice->id,
            'customer' => [
                'name' => $sub->customer->name,
                'email' => $sub->customer->email,
                'cpf' => $sub->customer->cpf,
            ],
            'webhook_url' => 'https://meusite.com/webhooks/pixgo'
        ]);

        // 3. Guarda payment_id
        $invoice->payment_id = $resp['id'];
        $invoice->save();

        // 4. Notifica cliente (WhatsApp/email) com link de pagamento
        notifyCustomer($sub->customer, $resp['payment_url'], $resp['qr_code']);

        // 5. Atualiza próximo vencimento da subscription
        $sub->next_billing_date = addInterval($sub->next_billing_date, $sub->plan->interval);
        $sub->save();
    }

    // Trata invoices vencidos não pagos (grace period)
    handleOverdue();
}

Webhook handler (atualiza invoice quando paga)

function handleWebhook($event, $payload) {
    if ($event !== 'payment.completed') return;

    $external_id = $payload['external_id'];
    $invoice = db.findOne('invoices', ['id' => $external_id]);
    if (!$invoice) return;  // não é nosso

    $invoice->status = 'paid';
    $invoice->paid_at = now();
    $invoice->save();

    // Se sub estava past_due, reativa
    if ($invoice->subscription->status === 'past_due') {
        $invoice->subscription->status = 'active';
        $invoice->subscription->save();
    }
}

Grace period e suspensão

Cliente que não paga não é caso de "erro" — é normal acontecer. Você decide a política:

function handleOverdue() {
    $hoje = date('Y-m-d');
    $overdueInvoices = db.query("SELECT * FROM invoices
        WHERE status='pending' AND due_date < ?", [$hoje]);

    foreach ($overdueInvoices as $inv) {
        $diasAtraso = daysBetween($inv->due_date, $hoje);

        if ($diasAtraso == 3) {
            // Lembrete suave por email
            sendReminder($inv, 'gentle');
        } elseif ($diasAtraso == 7) {
            // Aviso de que suspende em breve
            sendReminder($inv, 'urgent');
            $inv->subscription->status = 'past_due';
            $inv->subscription->save();
        } elseif ($diasAtraso == 14) {
            // Suspende acesso
            $inv->subscription->status = 'suspended';
            $inv->subscription->save();
            sendNotification($inv->customer, 'suspended');
        } elseif ($diasAtraso >= 30) {
            // Cancela definitivamente
            $inv->subscription->status = 'canceled';
            $inv->status = 'overdue';
            $inv->save();
        }
    }
}

Notificação ao cliente — a chave do sucesso

A maior diferença entre "recorrência funciona" e "recorrência com churn alto" é a notificação. Cliente esquece de pagar PIX, simples assim. Boas práticas:

Cronograma sugerido

Quando Mensagem Objetivo
3 dias antes"Sua mensalidade vence em 3 dias. Pague aqui: [link]"Antecipação — cliente paga adiantado
Dia do vencimento"Hoje vence! Pague em 1 clique: [link]"Lembrete principal
1 dia atraso"Notamos que ainda não pagou. Algo errado? [link]"Resgate suave (zero pressão)
7 dias atraso"Sua conta vai ser suspensa em X dias. Pague pra continuar: [link]"Urgência real
Pós-suspensão"Conta suspensa. Pague pra reativar: [link]"Win-back

Canais

  • WhatsApp: tem a maior taxa de abertura (90%+). Use API oficial WhatsApp Business ou serviços como Z-API, Evolution API
  • Email: baixa abertura (20-30%), mas barato e necessário pra paper trail
  • SMS: alto custo, alta abertura — pra casos urgentes (7 dias atraso)
  • Push notification (se você tem app): grátis e eficaz
Dica de ouro: mande o QR Code direto na mensagem (imagem) ou o link de pagamento (payment_url retornado pela API). Cliente clica no link e o app dele abre direto na tela de PIX — taxa de pagamento sobe muito.

Tratamento de casos especiais

Cliente paga atrasado mas dentro do grace period

Quando o webhook payment.completed chega de uma invoice overdue, reative a subscription. Cobre normalmente no próximo ciclo (não tente "recuperar" pagamentos perdidos do passado).

Cliente paga 2× por engano

Pode acontecer (cliente confuso, link duplicado). Detecte: 2 webhooks payment.completed referentes ao mesmo cliente em janela curta. Solução: estorne o segundo pelo módulo de chamados (PixGo não tem endpoint de refund self-service ainda).

Cliente quer trocar de plano (upgrade/downgrade)

Sua subscription mantém o histórico. Cria nova invoice com o valor proporcional (diferença), ou cobra novo valor cheio no próximo ciclo. Decisão de produto.

Cliente cancela no meio do ciclo

Não tem como dar refund proporcional automático via API. Manda mensagem explicando que o serviço continua até o fim do período já pago. No vencimento seguinte, não gera nova invoice.

Webhook chega 2× pelo retry

Use idempotency: a invoice no seu banco só vira paid uma vez. Se webhook duplicado chega, o segundo é no-op.

Frequências comuns e considerações

Frequência Considerações
SemanalAtrito alto pra cliente. Recomendado só pra valor baixo (R$10-30). Maior churn rate.
MensalPadrão da indústria. Cliente já espera. Funciona em qualquer valor.
TrimestralBom pra cobrança maior (R$200+). Cliente paga menos vezes, churn cai.
AnualMaior LTV. Geralmente com desconto. Recomendado oferecer junto com mensal.

Integração com plataformas EAD / SaaS

Se seu produto vive em outra plataforma (Eduzz, Hotmart, Kiwify, Memberkit), você ainda pode usar PixGo pra cobrança e a plataforma só pra entrega do conteúdo. Fluxo:

  1. Cliente assina na sua landing → você cria subscription no seu banco
  2. Cron mensal gera QR PixGo
  3. Webhook payment.completed chega → seu sistema marca invoice paid
  4. Seu sistema chama API da plataforma EAD pra habilitar acesso do aluno
  5. No próximo vencimento, se não pagar, seu sistema chama API EAD pra suspender acesso

Custo total da pilha: você paga 2,5% PixGo + custo da plataforma EAD. Bem competitivo vs Hotmart "vendendo nativo" (4,99-9,99% + taxa boleto/cartão).

Métricas pra acompanhar

  • MRR (Monthly Recurring Revenue): soma de todas as subscriptions ativas no mês
  • Churn rate: % de subscriptions canceladas/suspensas por mês
  • Payment success rate: % de invoices que viram paid antes do grace period
  • Time to payment: tempo médio entre criação da invoice e payment.completed
  • Recovery rate: % de invoices overdue que viram paid depois

Implemente um dashboard simples mostrando esses 5 números diariamente. Vai te ajudar muito mais que qualquer analytics genérico.

FAQ recorrência

Cliente pode "salvar o método" pra pagar mais rápido?

O PIX em si não — toda vez precisa scan/cola. Mas o payment_url que você manda já leva ele direto pra tela de pagamento. Em 2 cliques está pago.

E se eu quiser cobrar cartão de crédito também?

A PixGo não processa cartão — só PIX. Pra cartão, você precisa de outro adquirente (Pagar.me, Stripe, etc) e roda os dois métodos em paralelo. Cliente escolhe na hora da assinatura.

Posso cobrar valor variável (consumo)?

Sim. Sua subscription pode calcular valor dinâmico (ex: minutos consumidos, GB usados) e mandar como amount no POST /payment/create.

Cliente cancela e volta — como reativar?

Subscription canceled → nova subscription (mesmo customer_id). Histórico fica preservado. Você pode oferecer desconto pra win-back na primeira invoice.

Como evitar duplicidade quando o cron falha e roda de novo?

No seu cron, marque a subscription com last_billing_date ANTES de chamar a API PixGo. Se a chamada falhar, o cron retry verifica se já cobrou hoje e pula.

Qual horário rodar o cron?

Manhã (8h-10h) costuma ter melhor conversão — cliente acabou de acordar, abre o WhatsApp/email, paga. Evite madrugada (cliente vê só na manhã, mas a notificação já está "velha").

Vale usar o módulo /recurrence em vez de fazer custom?

Se você é solo/early-stage, sim. Você foca no produto, a recorrência roda pronta. Custom só compensa quando tem regras únicas (multi-tenant, fluxo complexo, integração profunda com outro sistema).


Resumo prático

  • Não é débito automático: a PixGo gera a cobrança de cada ciclo e o cliente paga o PIX
  • Use o módulo de cobrança recorrente se não quer codar; API custom se precisa de regras específicas
  • Cron diário cria invoice + chama POST /payment/create + notifica cliente
  • Webhook payment.completed marca invoice como paga
  • Grace period + suspensão automática + win-back: implementa todos
  • Notificação WhatsApp/email é o que define sucesso da recorrência
  • Acompanhe MRR + churn + payment success rate diariamente

Leituras relacionadas: Guia completo da API · Códigos de erro e debug · ChatGPT como copiloto