Sistema de créditos por indicação para SaaS: rastreie indicações, bloqueie abuso e aplique créditos em assinaturas com regras claras e um ledger auditável.

Um programa de créditos por indicação é um recurso de faturamento, não de pagamentos. A recompensa é crédito na conta que reduz cobranças futuras (ou estende tempo). Não é dinheiro enviado a um banco, não são gift cards e não é a promessa de que alguém "será pago" depois.
Um bom sistema responde a uma pergunta toda vez: "Por que a próxima fatura desta conta caiu?" Se você não consegue explicar isso em uma ou duas frases, surgem tickets de suporte e disputas.
Um sistema de créditos por indicação tem três partes: alguém convida um novo cliente, regras claras decidem quando esse convite conta (a conversão), e créditos são ganhos e aplicados às faturas de assinatura futuras.
O que não é: pagamentos em dinheiro, um desconto vago que altera números sem registro, ou um sistema de pontos que nunca se conecta às faturas.
Várias equipes dependem desses detalhes. Quem indica quer ver o que ganhou e quando isso vai valer. Usuários indicados querem saber o que recebem e se isso afeta o plano. Suporte precisa resolver "meu crédito desapareceu" rapidamente. Finance precisa de totais que batam com as faturas e possam ser auditados.
Exemplo: Sam indica Priya. Priya inicia um plano pago. Sam ganha $20 em créditos que reduzem a próxima fatura de Sam em até $20. Se a próxima fatura de Sam for $12, os $8 restantes ficam como crédito para depois, com um registro claro de origem.
Sucesso não é só "mais indicações". É faturamento previsível e menos discussões. Você sabe que está funcionando quando saldos de crédito são fáceis de explicar, faturas batem com o ledger, e suporte responde sem adivinhação ou correções manuais.
Um programa de indicação parece simples até os primeiros tickets: "Por que não recebi meus créditos?" A maior parte do trabalho é política, não código.
Comece pelo gatilho. "Convite enviado" é cedo demais. "Cadastro" é fácil de fraudar com contas descartáveis. Um ponto comum é a "conversão qualificada": e-mail verificado mais primeira fatura paga, ou o primeiro pagamento bem-sucedido após um trial. Escolha um gatilho e mantenha consistente para que o ledger fique limpo.
Depois, defina o valor e os limites. Créditos devem parecer reais, mas não se tornar uma máquina de desconto ilimitada. Decida se dá um valor fixo (por exemplo $20 em créditos) ou uma porcentagem de uma fatura, e limite de forma que você consiga explicar em uma frase.
As decisões que evitam a maioria das confusões depois são:
Regras de elegibilidade importam mais do que se espera. Se apenas planos pagos contam, diga isso. Se algumas regiões são excluídas (imposto, compliance, promoções), diga. Se planos anuais qualificam mas mensais não, diga. Para uma plataforma como Koder.ai com vários níveis, decida antecipadamente se upgrades de free para pro contam e se contratos enterprise são tratados manualmente.
Escreva o texto voltado ao usuário antes de lançar. Se você não consegue explicar cada regra em duas frases curtas, os usuários vão interpretar errado. Mantenha firme, mas calmo: "Podemos reter créditos por atividade suspeita" é mais claro (e menos hostil) que uma longa lista de ameaças.
Escolha um identificador primário e trate todo o resto como evidência de apoio. As opções mais limpas são um token de link de indicação (fácil de compartilhar), um código curto (fácil de digitar) e um convite enviado para um e-mail específico (melhor para convites diretos). Escolha um como fonte de verdade para que a atribuição seja previsível.
Capture esse identificador o quanto antes e carregue-o por toda a jornada. Um token de link geralmente é capturado na landing page, armazenado em storage de primeira parte e reenviado no signup. Para mobile, passe-o pelo fluxo de instalação do app quando possível, mas presuma que às vezes você vai perdê-lo.
Rastreie um conjunto pequeno de eventos que batam com suas regras de negócio. Se seu objetivo é "isso virou um cliente pagante" (não apenas "clicou"), um conjunto mínimo é suficiente:
referral_click (token visto)account_signup (novo usuário criado)account_verified (e-mail/telefone verificado)first_paid_invoice (primeiro pagamento bem-sucedido)qualification_locked (conversão aceita e não muda mais)Trocas de dispositivo e cookies bloqueados são normais. Para lidar com isso sem rastreamento invasivo, adicione um passo de reivindicação durante o cadastro: se o usuário chega com um token, anexe à nova conta; se não, permita inserir um código curto uma vez durante o onboarding. Se ambos estiverem presentes, mantenha o valor capturado mais cedo como primário e armazene o outro como evidência secundária.
Por fim, mantenha uma linha do tempo simples por indicação que o suporte leia em um minuto: quem indicou, conta indicada (quando conhecida), status atual e o último evento significativo com timestamps. Quando alguém pergunta "por que não recebi créditos?" você pode responder com fatos como "o cadastro aconteceu, mas a primeira fatura paga nunca ocorreu" em vez de adivinhar.
Programas de indicação geralmente quebram quando o modelo de dados é vago. Suporte pergunta "quem indicou quem?" Billing pergunta "o crédito já foi emitido?" Se você não consegue responder sem vasculhar logs, o modelo precisa ser mais rígido.
Armazene a relação de indicação como um registro de primeira classe, não como um palpite derivado de cliques.
Uma configuração simples e debuggable fica assim:
id, referrer_user_id, referred_user_id, created_at, source (invite link, coupon, manual), status, status_updated_atreferral_id, invite_code_id or campaign_id, first_seen_ip_hash, first_seen_user_agent_hashworkspace_id, owner_user_id, created_atworkspace_id, user_id, role, joined_atMantenha a tabela referrals pequena. Qualquer coisa que você possa se arrepender de coletar depois (IP bruto, user agent completo, nomes) deve ser evitada ou armazenada apenas como hashes de curta duração com política de retenção clara.
Deixe os statuses explícitos e mutuamente exclusivos: pending (cadastrado, ainda não elegível), qualified (atendeu às suas regras), credited (crédito emitido), rejected (falhou nas checagens), reversed (crédito anexado após reembolso/chargeback).
Decida precedência uma vez e então aplique no banco para que o app não credite acidentalmente duas vezes. No mínimo:
referred_user_id)credited por conta indicadareferral_id escolhidoSe você suporta times, decida se a indicação se liga ao cadastro pessoal ou à criação do workspace. Não tente fazer os dois. Uma abordagem viável é ligar a indicação à conta de usuário, enquanto as checagens de elegibilidade olham se esse usuário (ou seu workspace) se tornou assinante pagante.
Se você quer menos bugs de faturamento e menos tickets de suporte, use um ledger, não um único campo de "saldo de créditos". Um número de saldo pode ser sobrescrito, arredondado ou atualizado duas vezes. Um ledger é um histórico de entradas que você sempre pode somar.
Mantenha tipos de entrada limitados e sem ambiguidade: earn (conceder), spend (aplicar à fatura), expire, reversal (clawback) e ajuste manual (com nota e aprovador).
Toda entrada deve ser legível por engenheiros e suporte. Armazene campos consistentes: amount, credit type (não "USD" se créditos não são dinheiro), texto do motivo, evento fonte (como referral_signup_qualified), IDs fonte (usuário, usuário indicado, subscription ou invoice), timestamps e created_by (sistema ou admin).
Idempotência importa mais do que se espera. O mesmo webhook ou job em background pode rodar duas vezes. Exija uma chave de idempotência única por evento-fonte para poder reexecutar com segurança sem conceder créditos duplamente.
Torne explicável ao usuário. Quando alguém pergunta "por que recebi 20 créditos?" você deve mostrar qual indicação disparou, quando foi postado, se expira e se houve uma reversão depois. Se um amigo fizer um upgrade, você adiciona uma entrada de earn ligada a esse evento de upgrade. Se o pagamento for reembolsado, publique uma entrada de reversal ligada ao evento de reembolso.
Presuma que a maioria das pessoas é honesta e que alguns tentarão truques óbvios. O objetivo é parar abuso fácil, manter regras claras e evitar bloquear clientes reais que compartilham Wi‑Fi ou cartão da família.
Comece com bloqueios rígidos que você consiga justificar. Não conceda créditos quando o remetente e o indicado forem claramente a mesma pessoa, como mesmo user ID, mesmo e-mail verificado ou mesma impressão do método de pagamento. Regras por domínio de e-mail podem ajudar, mas mantenha-as estreitas. Bloquear todos os cadastros de um domínio de empresa pode atrapalhar times legítimos.
Depois adicione detecção leve para loops e cadastros em massa. Você não precisa de scoring de fraude perfeito no dia um. Alguns sinais fortes pegam a maior parte do abuso: muitos cadastros do mesmo dispositivo em curto período, uso repetido da mesma faixa de IP em minutos, mesmo cartão usado em várias contas "novas", muitas contas que nunca verificam e-mail, ou padrões rápidos de cancelar-e-assinar de novo depois que créditos são aplicados.
Requerer uma ação qualificadora antes dos créditos ficarem utilizáveis (por exemplo: e-mail verificado mais fatura paga, opcionalmente após curto período de carência) impede bots e churn de tier gratuito de gerar ruído.
Adicione rate limits e cooldowns ao redor de links de indicação e resgates, mas mantenha-os silenciosos até serem necessários. Se um link for usado 20 vezes em uma hora da mesma rede, pause recompensas e marque para análise.
Quando intervir, mantenha a experiência calma. Marque créditos como pendentes até o pagamento ser confirmado, mostre um motivo simples quando recompensas estiverem atrasadas (evite culpar), ofereça um caminho direto para contato com suporte e encaminhe casos extremos para revisão manual em vez de banir automaticamente.
Exemplo: uma equipe startup compartilha um IP de escritório. Três colegas se cadastram pelo mesmo referral no mesmo dia. Com verificação e pagamento qualificante mais um cooldown básico, eles ainda ganham créditos após as faturas pagas, enquanto rajadas tipo bot ficam retidas para revisão.
Programas de indicação parecem simples até o dinheiro mover do jeito "errado": um reembolso, chargeback, uma fatura anulada ou uma conta que muda de dono. Se você projetar esses casos desde o início, evita usuários irritados e longas threads de suporte.
Trate créditos como algo que se ganha com base em um resultado pago, não só por um cadastro. Então defina uma política de reversão ligada a eventos de cobrança.
Um conjunto de regras que o suporte consiga explicar:
Reembolsos parciais são onde times costumam travar. Escolha uma abordagem e mantenha: reversão proporcional (reverte 30% do crédito para um reembolso de 30%) ou reversão total (qualquer reembolso reverte todo o crédito). Proporcional é mais justo, mas mais difícil de explicar e testar. Reversão total é mais simples, mas pode parecer dura.
Transições de trial para pago também devem ser explícitas. Uma prática comum é manter créditos pendentes durante o trial e travá‑los somente após a primeira fatura paga bem-sucedida (e opcionalmente após curto período de carência).
Pessoas mudam e-mails, fundem contas ou passam de uso pessoal para workspace de time. Decida o que segue a pessoa e o que segue a conta pagante. Se um workspace é o assinante, créditos frequentemente pertencem ao workspace, não ao membro que pode sair.
Se você suporta merges de conta ou transferência de propriedade de time, registre um evento de ajuste em vez de reescrever a história. Toda reversão ou correção manual deve incluir uma nota amigável ao suporte tipo "Chargeback na invoice 10482" ou "Transferência de dono do workspace aprovada pelo suporte." Em plataformas como Koder.ai onde créditos se aplicam a assinaturas, essas notas permitem responder "por que meus créditos mudaram?" em uma única consulta.
A parte mais difícil não é rastrear indicações. É fazer com que créditos se comportem igual em renovações, upgrades, downgrades e impostos.
Primeiro, decida onde créditos podem ser usados. Alguns times aplicam créditos apenas à próxima fatura nova. Outros permitem que créditos cubram qualquer fatura em aberto. Escolha uma regra e mostre na UI para que ninguém se surpreenda.
Em seguida, trave a ordem de operações. Uma abordagem previsível é: calcular cobranças da assinatura (incluindo proration), aplicar descontos, calcular imposto, e então aplicar créditos por último. Aplicar créditos por último mantém a lógica de impostos consistente e evita discussões sobre se créditos reduzem montantes tributáveis em todas as jurisdições. Se suas regras legais/fiscais exigirem outra ordem, documente e escreva testes.
Proration é onde bugs de billing normalmente aparecem. Se alguém faz upgrade no meio do ciclo, crie um item de proration (cobrança ou crédito) e trate-o como qualquer outro line item. Depois aplique créditos ao total da fatura, não a itens individuais.
Mantenha regras de fatura rígidas:
Exemplo: um usuário faz upgrade no meio do mês e recebe uma cobrança de proration de $12. O subtotal da fatura vira $32 após descontos e impostos. Se ele tem $50 em créditos por indicação, você aplica $32, define a fatura como $0 e mantém $18 para a próxima renovação.
Trate o programa de indicação como um pequeno recurso de faturamento, não um widget de marketing. O objetivo é consistência chata: cada crédito tem uma razão, um timestamp e um caminho claro para a próxima fatura.
Escolha um evento de conversão e uma regra de crédito. Por exemplo: uma indicação se qualifica somente quando o usuário convidado se torna assinante pagante e o primeiro pagamento é liquidado.
Construa o MVP ao redor de um fluxo ponta a ponta: capture token ou código de indicação no signup, execute qualificação quando o pagamento succeed (não quando o usuário inserir o cartão), escreva uma entrada no ledger com chave de idempotência única e aplique créditos à próxima fatura em ordem previsível.
Decida a fonte da verdade cedo. Ou seu provedor de billing é a fonte da verdade e seu app espelha, ou seu ledger interno é a fonte da verdade e o billing apenas recebe "aplique X créditos nesta fatura". Misturar ambos geralmente cria tickets "meus créditos sumiram".
Adicione ferramentas administrativas antes de adicionar mais regras de indicação. Suporte precisa buscar por usuário, código de indicação e fatura, então ver uma timeline de: invite, signup, qualificação, créditos concedidos, créditos gastos e reversões. Inclua ajustes manuais e sempre exija uma nota curta.
Depois adicione UX para usuário: uma página de indicação, linha de status para cada invite (pending, qualified, credited) e um histórico de créditos que bata com as faturas.
Finalmente, adicione monitoramento: alerte sobre picos súbitos de indicações, altas taxas de reversão (reembolsos ou chargebacks) e padrões incomuns como muitas contas compartilhando mesmo dispositivo ou método de pagamento. Isso mantém controles de abuso firmes sem punir usuários normais.
Exemplo: se alguém compartilha uma indicação da Koder.ai com o time, eles devem ver créditos aparecerem apenas após a primeira assinatura paga com sucesso, e esses créditos devem reduzir a próxima renovação automaticamente, não como um cupom manual.
A maioria dos programas de indicação falha em faturamento, não em marketing. A forma mais rápida de criar tickets é tornar créditos imprevisíveis: usuários não entendem por que os receberam, quando vão aplicar ou por que uma fatura está diferente.
Uma armadilha comum é construir antes das regras estarem claras. Se "indicação qualificada" é vago (trial iniciado, primeiro pagamento, plano mantido por 30 dias), você acabará negociando créditos caso a caso e emitindo reembolsos para acertar as contas.
Outro problema frequente é usar um único campo mutável de "saldo de créditos". Parece simples até você ter retries, reembolsos, mudanças de plano ou ajustes manuais. Então o número deriva e você não consegue explicar de onde veio.
Idempotência também é negligenciada. Provedores de pagamento reenviam webhooks, workers reexecutam jobs e usuários clicam duas vezes. Se a ação "conceder crédito" não for idempotente, você vai mintar créditos duplicados e só notar quando a receita estiver errada.
A matemática dos créditos também pode estar errada mesmo quando os totais batem. Aplicar créditos antes de impostos, ou ignorar regras de proration, pode produzir faturas que não coincidem com o que o sistema de pagamento espera. Isso leva a recibos inconsistentes, pagamentos falhados e reconciliações dolorosas.
Checagens antifraude podem ser severas demais. Bloquear por IP, dispositivo ou domínio sem caminho de revisão impede indicações reais (colegas, roommates, times na mesma rede) e prejudica o crescimento silenciosamente.
Cinco sinais de alerta:
invite_id, conversion_id) para prevenir duplicatas.Exemplo: um usuário Koder.ai no plano Pro faz upgrade no meio do mês, ganha um crédito por indicação, depois faz downgrade. Se seu sistema usa um único campo de saldo e aplica créditos antes da proration, a próxima fatura pode ficar errada mesmo que o total esteja próximo. Um ledger mais ordem fixa de aplicação evita que isso vire um longo ticket de suporte.
Antes de lançar, execute algumas verificações que pegam a maioria dos problemas de cobrança e suporte cedo.
Exemplo: Maya convida Noah. Noah se cadastra pelo invite de Maya, faz trial, depois faz upgrade para Pro e paga $30. Seu sistema marca essa fatura como qualificada e cria uma entrada de crédito para Maya (por exemplo: $10 de crédito de assinatura).
Na próxima renovação de Maya, o subtotal da fatura é $30. Sua etapa de faturamento aplica até $10 dos créditos disponíveis, então a fatura mostra $30 subtotal, -$10 crédito e $20 devido. O ledger de Maya tem uma entrada por ganho (+$10) e uma por gasto (-$10 aplicado à invoice #1234).
Se Noah depois pedir reembolso daquele primeiro pagamento, o sistema adiciona uma entrada de reversal que remove o crédito ganho por Maya (ou publica um débito correspondente). Se algum crédito já tiver sido usado, a próxima fatura cobra a diferença em vez de reescrever o histórico.
Dois próximos passos que mantêm o impulso sem quebrar a confiança:
Prototipe o fluxo completo em um documento de planejamento curto: atribuição, qualificação, entradas no ledger, aplicação em faturas e reversões.
Teste cenários fixos em sandbox: trial para pago, reembolso depois de crédito usado, upgrade e downgrade no meio do ciclo e ajuste administrativo.
Se quiser avançar rápido sem perder controle da lógica de cobrança, Koder.ai inclui Planning Mode mais snapshots e rollback, que ajudam a iterar no fluxo de indicação até que a matemática das faturas fique consistente. Você pode fazer todo o ciclo dentro da plataforma na koder.ai, depois exportar o código quando estiver pronto.
Referral credits reduzem o que você deve nas faturas futuras (ou estendem o tempo da assinatura).
Eles não são dinheiro em conta bancária, não são gift cards e não são uma promessa de pagamento posterior. Pense neles como crédito na loja que aparece na cobrança.
Um padrão comum é: a indicação se qualifica depois que o usuário indicado completa a primeira fatura paga com sucesso (frequentemente após verificação de e-mail, e às vezes após um curto período de carência).
Evite qualificar apenas em “convite enviado” ou “cadastro”, porque isso é fácil de fraudar e difícil de defender em disputas.
Use uma única fonte primária de verdade, tipicamente um token de link de indicação ou código curto.
Boas práticas:
Use statuses explícitos e mutuamente exclusivos para que o suporte responda rapidamente:
pending: existe cadastro, ainda não elegívelqualified: atendeu às regras (ex.: primeira fatura paga)credited: crédito foi emitidoUm único campo “saldo” é sobrescrito, reexecutado ou atualizado em duplicidade e torna-se impossível auditar.
Um ledger é uma lista de entradas que você sempre pode somar:
Isso torna a cobrança explicável e debuggable.
Torne a ação “conceder crédito” idempotente usando uma chave única por evento-fonte (por exemplo, o ID da primeira fatura paga).
Se o mesmo webhook ou job rodar duas vezes, a segunda execução não deve fazer nada e nem emitir créditos duplicados.
Comece com bloqueios simples e justificáveis:
Depois adicione controles leves sem penalizar usuários reais:
Defina uma política de reversão clara ligada a eventos de cobrança:
Para reembolsos parciais, escolha uma regra e mantenha-a: reversão proporcional (mais justo, mais complexo) ou reversão total (mais simples, pode parecer severo).
Uma ordem previsível padrão é:
Regras que reduzem confusão:
Um MVP mínimo, mas suportável:
Depois disso, adicione UI e ferramentas administrativas antes de complicar com tiers de recompensa.
rejected: falhou nas checagens ou é inelegívelreversed: crédito recuperado após reembolso/chargebackGuarde também um timestamp da última alteração de status.