Guia visual · SMA-306 + SMA-310

Programa de Indicações

Cliente fiel indica um amigo. Quando o amigo aparece e corta, os dois ganham — corte grátis ou desconto, configurável pela barbearia. Esta é a documentação visual de tudo que foi implementado.

👥 Double-sided: os dois ganham 🎁 Corte grátis ou desconto %/R$ 🔁 Referidor recorrente ou uma vez só 🔒 Resgate calculado no servidor 📊 Ativo só pro ProBarbers (feature flag)
X Referidor — quem indica Y Indicado — o amigo novo

01As 4 peças

A feature combina configuração por barbearia, um histórico imutável de prêmios, regras no banco e telas no app.

⚙️ Config por barbearia

Tabela referral_program_configs. O dono define, por lado, o tipo de recompensa, valores, o modo do referidor e a validade.

🧾 Ledger de prêmios

Tabela referral_rewards. Uma linha por prêmio ganho, com snapshot do valor no momento — mudar a config depois não mexe no que já foi ganho.

🧠 Regras no banco (RPCs)

credit_referral_reward emite os prêmios, close_appointment resgata o desconto de forma atômica, get_referral_program_stats calcula o custo realizado.

🖥️ Telas no app

Configuração em /configuracoes/indicacoes, badge de resgate no fechamento da comanda, banner no agendamento e link enviado pelo bot do WhatsApp.

02O fluxo, do convite ao prêmio

O gatilho é sempre a presença física: o crédito só acontece quando a comanda do indicado fecha como concluída.

1
📲

X recebe o link

Após cortar, Carlos recebe no WhatsApp seu link único ?ref=….

2
📤

X compartilha

Manda pro amigo André.

3
📅

Y agenda

André abre o link, vê o banner e marca o primeiro horário.

4
💈

Y comparece

Corte concluído → o gatilho dispara.

5
🎁

Os dois ganham

André ganha boas-vindas; Carlos ganha conforme o modo.

03Dentro do app — tela de configuração

Réplica de /configuracoes/indicacoes. Tudo independente por lado.

ProBarbers · Configurações › Indicações
Clientes via indicação
12
total acumulado
Conversões (30d)
8
67%
Custo de recompensas
R$ 260
realizado
Ganho líquido (30d)
R$ 980
receita − custo
Quando ativo, clientes recebem um link único.
Serviço
Usos
Recompensa recorrente Recorrente: ganha a cada visita do indicado (1 por vez). Uma vez só: ganha apenas na primeira.
Serviço
Usos
Por quantos dias a recompensa de desconto fica disponível. Corte grátis não expira.
Validade (dias)

04Dentro do app — resgate no checkout interativo

Quando o cliente da comanda tem um desconto de indicação pendente, aparece o badge. Mexa nos controles e clique em Aplicar — repare que o desconto manual fica intacto (não soma duas vezes) e o valor é "calculado no servidor".

Configuração do prêmio do X (simulação)

Percentual (%)
Teto (R$, opcional)
Corte R$ 50 + Barba R$ 35 = subtotal R$ 85 (fixo nesta simulação)
Fechar comanda · Carlos · Edward Mãos de Tesoura
Corte
30 min
R$ 50,00
Barba
20 min
R$ 35,00
Desconto de indicação disponível: 20%
Estimado: − R$ 17,00
ServiçosR$ 85,00
TotalR$ 85,00
Pagamento (auto)R$ 85,00

05Recorrente vs uma vez só interativo

A regra mais importante da fase 2. Clique em "André comparece" várias vezes e veja como o referidor é (ou não) premiado. No modo recorrente vale a regra "1 pendente por vez".

Modo do referidor:
0
visitas do André (Y)
0
pendentes do Carlos (X)
0
resgatados pelo Carlos
não
boas-vindas do André

06No WhatsApp — o bot

Depois que o corte é concluído, o worker do bot dispara (fire-and-forget) a mensagem com o link de indicação. O indicado abre o link e cai no agendamento com o banner.

ProBarbers
conta comercial
Valeu pela visita, Carlos! 💈 Corte registrado.
14:31
🎁 Indique amigos e ganhe desconto no seu próximo corte. Compartilhe seu link:
14:32
Boa! Vou mandar pro André 🙌
14:40 ✓✓

Como o link funciona

O ?ref=ABC123 carrega o código de indicação do Carlos. Ele é opaco (sem PII) e validado dentro do tenant.

  • André abre → a página de agendamento mostra um banner de boas-vindas.
  • O vínculo (referred_by) só é gravado se o André for cliente novo.
  • Auto-indicação (usar o próprio link) é ignorada.
probarbers.com.br/probarbers/agendar?ref=ABC123
🎉 Você foi indicado por um amigo!
Agende e ganhe 1 Corte grátis de boas-vindas.
Escolha o barbeiro
Escolha o serviço
Data e horário
Anti-fraude: o prêmio só é creditado quando o André comparece (comanda concluída) — agendar e não aparecer não gera nada. Tudo passa por after() pra não travar a resposta.

07Todos os casos implementados

Cada combinação possível, com um exemplo concreto.

1 · Corte grátis dos dois lados, uma vez só

O padrão (igual fase 1). Os dois ganham um corte grátis no primeiro corte do indicado.

Carlos indica André → André comparece 1x André ganha 1 corte grátis (boas-vindas) e Carlos ganha 1 corte grátis. André volta de novo → Carlos não ganha mais.

2 · Referidor desconto recorrente + indicado corte grátis

O carro-chefe da fase 2. X ganha desconto toda vez que Y volta, com a regra 1-pendente.

André comparece → Carlos ganha 20% pendente. Carlos usa. André volta → Carlos ganha de novo. André volta antes de Carlos usar não acumula (1 por vez).

3 · Desconto em valor fixo

Em vez de %, um valor cravado em reais.

X = R$ 15 fixo. Comanda do Carlos de R$ 50 total vai pra R$ 35.

4 · Desconto % com teto

O % incide no total da comanda, mas limitado a um teto em R$.

20% com teto R$ 30. Comanda de R$ 85 → 20% = R$ 17 (ok). Comanda de R$ 200 → 20% = R$ 40, mas o teto trava em R$ 30.

5 · Resgate no checkout

Badge de um toque; valor calculado no servidor; resgate atômico com o fechamento.

Carlos tem 20% pendente → badge "Aplicar" → total R$ 85 vira R$ 68 prêmio marcado como usado (não dá pra usar 2x).

6 · Validade / expiração

Configurável; NULL = sem validade. Vale só pro desconto.

Carlos some por 3 meses (validade 60d) o desconto expira e some do badge. Corte grátis não expira.

7 · Snapshot ao ganhar

Mudar a config não altera prêmios já ganhos.

Carlos tem 20% pendente. Dono muda pra 10% ou desliga o de Carlos continua 20% até usar/expirar. Só o futuro muda.

8 · Permissão da secretária

Resgatar indicação é aplicar desconto — exige a permissão apply_discount.

Secretária sem a permissão tenta resgatar bloqueado no servidor (mesmo gate do desconto manual).

9 · Comissão do barbeiro

O desconto de indicação é bancado pela barbearia.

Comanda R$ 85 com R$ 17 de desconto de indicação a comissão do barbeiro é calculada sobre R$ 85 (a casa absorve o desconto).

Anti-fraude (transversal)

Várias guardas combinadas.

Só cliente novo vira indicado · auto-indicação ignorada · cross-tenant impossível · boas-vindas só 1x · sem double-credit (lock no fechamento) · presença física obrigatória.

08O modelo de dados

Onde cada coisa vive.

Config — referral_program_configs (1 por barbearia)

ColunaO que é
enabledliga/desliga o programa
referrer_reward_type / referred_reward_typefree_service ou discount (por lado)
*_service_id / *_usesserviço grátis + qtd de usos (quando corte grátis)
*_discount_mode / *_discount_value / *_discount_cap_centspct|fixed, valor e teto (quando desconto)
referrer_modeone_time ou recurring
validity_daysdias de validade · NULL = sem validade

Ledger — referral_rewards (1 por prêmio ganho)

ColunaO que é
beneficiary_customer_id + rolequem recebe (referrer = X / referred = Y)
sourcewelcome (boas-vindas) ou recurring
reward_type + snapshot (discount_mode/value/cap, free_service_id/uses)o prêmio congelado no momento que foi ganho
earned_at / expires_at / redeemed_at / redeemed_amount_centsciclo de vida: ganho → expira ou é resgatado
Pendente = redeemed_at IS NULL AND (expires_at IS NULL OR expires_at > agora). A regra 1-pendente do modo recorrente só emite um novo prêmio de referidor se não houver nenhum pendente.

Gating — quem vê

🎚️ Flag PostHog referral_program

Mira só o tenant do ProBarbers (pelo group key). Outras barbearias recebem false → não veem a tela nem o badge.

🛡️ Fallback no app

Só um false explícito desabilita. Se o PostHog estiver inerte, mostra (comportamento seguro).

09Tracking de eventos — PostHog

8 eventos cobrem o ciclo inteiro, do convite ao prêmio. Zero PII: só ids de tenant, contagens, valores agregados e enums.

Funil principal (aquisição)

📤 Cliente compartilha o linkreferral_link_shared
👀 Indicado abre o ?ref=referral_landing_viewed
📅 Indicado agenda e comparecebooking_completed
🎁 Crédito concedido aos doisreferral_reward_credited
💸 Referidor resgata o descontoreferral_discount_redeemed
Funil de engajamento do dono: referral_program_configuredreferral_stats_viewed (recorrência de abertura dos relatórios).

Todos os eventos

EventoQuando disparaPropriedadesLado
referral_program_enabledDono ativa o toggle do programaclient
referral_program_configuredDono salva a configuraçãoreferrer_uses, referred_usesclient
referral_stats_viewedDono abre Indicações ou Relatóriossource: config | relatoriosclient
referral_link_viewedCliente abre a própria áreahas_existing_codeclient
referral_link_sharedCliente compartilha o linkshare_method: native | clipboardclient
referral_landing_viewedNovo cliente abre um ?ref= válidoclient
referral_reward_creditedCrédito concedido (1º corte do indicado)tenant_id, referrer_uses, referred_usesserver
referral_discount_redeemedDesconto de indicação resgatado no checkouttenant_id, amount_centsserver
client posthog-js — agrupado pelo grupo tenant server captureServerEvent — disparado em server actions
Os eventos server-side (reward_credited, discount_redeemed) saem de dentro do after() no fechamento da comanda — nunca travam a ação principal e nunca carregam nome/telefone/email.