Cupons
Cupons (visão geral)
Cupons são códigos de desconto que seu cliente digita no checkout de uma Offer recorrente. Eles funcionam diferente de cupons de e-commerce tradicional: na Pagnovo, cada cupom só funciona nas Offers que você adicionou explicitamente à whitelist do cupom. Isso evita o problema clássico de cupom criado pra uma campanha vazar e ser usado em outros produtos.
V2: a whitelist é feita por Offer (não mais por Payment Link). Cupom não aplica em QuickLink nem em Checkout one-time — só faz sentido em fluxo que gera Invoice (Offer com
billingCyclepreenchido).
O modelo é deliberadamente simples (para o MVP):
- 1 uso por cliente. O mesmo
customernão consegue usar o mesmo cupom duas vezes — garantido pelo sistema. - Limite global opcional. Se você setar
maxUses: 100, o cupom para de funcionar após 100 redemptions totais. O limite é respeitado mesmo em corrida de checkouts simultâneos. - Aplica apenas na primeira fatura. Em Offer recurring, o desconto é aplicado só na primeira invoice. Faturas recorrentes seguintes vão sem desconto.
- Tipo e valor do desconto são imutáveis após o primeiro uso. Depois que alguém resgatou o cupom, você não pode mais mudar
discountTypenemdiscountValue— duplique e crie um novo.
Unidades — centavos e basis points
Cupons usam duas unidades diferentes, dependendo do tipo de desconto. Vale prestar atenção na primeira vez:
Basis points (para discountValue quando discountType: "PERCENTAGE"):
| Percentual | Basis points |
|---|---|
| 0,01% | 1 |
| 1% | 100 |
| 10% | 1000 |
| 50% | 5000 |
| 100% | 10000 |
Range válido: 1 a 10.000.
Centavos (para discountValue quando discountType: "FIXED", e também para minPurchaseAmount):
| Valor real | Centavos |
|---|---|
| R$ 1,00 | 100 |
| R$ 10,00 | 1000 |
| R$ 99,90 | 9990 |
| R$ 1.000,00 | 100000 |
Range válido para discountValue em FIXED: 100 (R$ 1,00) a 5.000.000 (R$ 50.000,00).
⚠️ Atenção: quando
discountType: "PERCENTAGE",discountValue: 1500é 15%. QuandodiscountType: "FIXED",discountValue: 1500é R$ 15,00. Não confunda os dois — confira o tipo antes de mandar.
Ciclo de vida do cupom
Um cupom passa por estes estados:
POST /coupons POST /:id/pause DELETE /:id
┌─────────────────────┐ ┌────────────────────┐ ┌────────────────────┐
│ (não existe) │ → │ ACTIVE │ → │ ARCHIVED │
└─────────────────────┘ └────────────────────┘ │ (arquivado) │
↑ ↓ └────────────────────┘
│ │
POST /:id/resume POST /:id/pause
│ │
│ ↓
┌────────────────────┐
│ PAUSED │
│ (não funciona em │
│ novo uso) │
└────────────────────┘
- ACTIVE — cupom funciona normalmente.
- PAUSED — não funciona em novos checkouts, mas histórico fica preservado. Pode ser reativado se
validUntilainda estiver no futuro. - ARCHIVED — arquivado. Não aparece em listagens (a menos que
?includeDeleted=true), não aceita edição, não aceita alteração de whitelist. Redemptions históricas continuam acessíveis para auditoria.
Whitelist de Ofertas
V2: o cupom é amarrado a Offers (não mais a Payment Links). Faz sentido porque cupom só tem efeito quando há Invoice (Offer recorrente) — e Offer é a entidade que define o produto que está sendo vendido.
Você gerencia a whitelist de três formas:
1. Na criação: passe offerIds: ["off_abc", "off_def"] no POST /coupons.
2. Adicionando depois: POST /coupons/:id/offers com { offerIds: [...] }. Máximo 100 por requisição.
3. Removendo: DELETE /coupons/:id/offers/:offerId.
A API valida ownership: todas as Offers precisam pertencer à sua conta — se alguma não for sua (ou não existir), a requisição inteira é rejeitada com 400 listando os IDs problemáticos.
ℹ️ Cupom em QuickLink? Não. QuickLink não passa por Invoice (gera Transaction direta), e cupom só tem efeito em Invoice. Pra dar desconto em campanha avulsa, basta criar QuickLinks com
amountjá reduzido.
💡 Boa prática: crie o cupom já com a whitelist correta em vez de criar vazio e adicionar depois. Reduz o risco de janela onde o cupom existe mas não funciona em lugar nenhum.