Criar um cupom
Cria um novo cupom de desconto, definindo o código que o cliente digita no checkout, o tipo e o valor do desconto, e as regras que controlam quando ele pode ser usado (validade, valor mínimo de carrin
Cria um novo cupom de desconto, definindo o código que o cliente digita no checkout, o tipo e o valor do desconto, e as regras que controlam quando ele pode ser usado (validade, valor mínimo de carrinho, limites de uso e restrições por cliente ou produto). Use esta operação para montar campanhas promocionais que serão aplicadas em transações e assinaturas.
POST /v1/coupons
Como funciona
Um cupom é uma regra de desconto reutilizável. Você o cria uma vez e o cliente o aplica no checkout digitando o code. No momento da compra, a API valida o cupom contra o carrinho (valor, quantidade de itens, cliente, produtos permitidos e janela de validade) e, se tudo bater, abate o desconto do valor a cobrar.
Ao chamar POST /v1/coupons, o servidor:
- Valida o corpo (campos obrigatórios, tipos, faixas e formato das datas).
- Confere os IDs em
allowedItemIdseallowedCustomerIds, se enviados — IDs inexistentes fazem a criação falhar. - Persiste o cupom e gera um
idopaco com prefixodis_(ex.:dis_01hqzvabc). - Inicializa o contador de uso
usageQuantityem0. - Responde
201 Createdcom o objeto completo do cupom.
O cupom já nasce "ligado" se você enviar enabled: true, mas só passa a ser aceito no checkout dentro da janela initDate … endDate. Ou seja, enabled e a janela de datas são dois controles independentes: um cupom habilitado fora da janela de validade não é aplicado.
Importante
A criação não é idempotente por natureza: cada chamada cria um novo cupom, mesmo que o code se repita. Envie um cabeçalho X-Idempotency-Key para que retentativas de rede não gerem cupons duplicados — veja Idempotência.
Quando usar
- Lançar uma campanha promocional (Black Friday, primeira compra, frete grátis simulado por desconto fixo).
- Oferecer um desconto fechado para um conjunto específico de clientes (
allowedCustomerIds) ou produtos (allowedItemIds). - Criar incentivos com teto de uso (
usageLimit) ou uma utilização por cliente (limitOneUsePerCustomer).
Quando não usar:
- Para alterar um cupom existente (estender validade, mudar o valor, desligar), use Atualizar — não crie um novo.
- Para um desconto pontual e não reutilizável aplicado a uma única cobrança, considere ajustar o valor na própria transação em vez de criar um cupom.
Requisição
Headers
| Cabeçalho | Obrigatório | Valor |
|---|---|---|
SelectKey | Sim | Sua chave de API. Produção: sl_live_...; sandbox: sl_test_.... Veja Autenticação. |
Content-Type | Sim | application/json |
X-Idempotency-Key | Recomendado | Chave única da operação, para evitar criação duplicada em retentativas. Veja Idempotência. |
A autenticação é sempre pelo cabeçalho
SelectKey— nuncaAuthorization: BearerouBasic.
Corpo
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
name | string | Sim | Nome descritivo do cupom (uso interno/exibição). |
enabled | boolean | Sim | Se o cupom está ativo. |
code | string | Sim | Código que o cliente digita no checkout (ex.: BLACKFRIDAY25). |
type | string | Sim | Tipo do desconto. Enum: flat (valor fixo) ou percentage (percentual). |
value | number | Sim | Para flat: valor do desconto em centavos (500 = R$ 5,00). Para percentage: o percentual (ex.: 25 = 25%). Mínimo 0. |
minCartAmount | integer | Não | Valor mínimo do carrinho em centavos para o cupom valer. Mínimo 0. |
maxCartAmount | integer | Não | Teto opcional do carrinho em centavos. Mínimo 0. |
usageLimit | integer | Não | Número máximo de resgates no total. Mínimo 0. |
limitOneUsePerCustomer | boolean | Não | Restringe a um uso por cliente. |
initDate | string (date-time) | Não | Início da validade, ISO 8601 UTC (ex.: 2026-04-01T00:00:00Z). |
endDate | string (date-time) | Não | Fim da validade, ISO 8601 UTC. |
allowedItemIds | array | Não | Restringe o cupom a IDs de produtos/itens específicos. |
allowedCustomerIds | array | Não | Restringe o cupom a IDs de clientes específicos. |
usageQuantity | integer | Não | Regras de quantidade de uso por cliente, quando aplicável. Mínimo 0. |
minCartItems | integer | Não | Quantidade mínima de itens no carrinho. Mínimo 0. |
maxCartItems | integer | Não | Quantidade máxima de itens elegíveis. Mínimo 0. |
isCumulative | boolean | Não | Se o cupom acumula (empilha) com outros descontos. |
Atenção: centavos vs. percentual
O campo value muda de significado conforme o type. Em type: "flat", value é dinheiro em centavos (500 = R$ 5,00). Em type: "percentage", value é o número do percentual (25 = 25%, não 2500). Errar isso é a causa mais comum de descontos absurdos. Todos os campos monetários da API seguem a convenção de centavos — veja Convenções.
Exemplo — cupom percentual
curl -X POST https://api.selectwin.io/v1/coupons \
-H "SelectKey: sl_live_aBcDeFgHiJkLmNoPqRsTuVwXyZ" \
-H "Content-Type: application/json" \
-H "X-Idempotency-Key: 7f3c1e8a-bf2d-4a9c-9b21-1d0e5f6a7c8b" \
-d '{
"name": "Black Friday 25%",
"enabled": true,
"code": "BLACKFRIDAY25",
"type": "percentage",
"value": 25,
"minCartAmount": 10000,
"usageLimit": 100,
"limitOneUsePerCustomer": true,
"initDate": "2026-04-01T00:00:00Z",
"endDate": "2026-04-30T23:59:59Z"
}'Exemplo — cupom de valor fixo, restrito a produtos
{
"name": "Summer Sale R$ 5,00",
"enabled": true,
"code": "SUMMER2026",
"type": "flat",
"value": 500,
"minCartAmount": 10000,
"usageLimit": 1000,
"limitOneUsePerCustomer": true,
"initDate": "2026-04-01T00:00:00Z",
"endDate": "2026-12-31T23:59:59Z",
"allowedItemIds": ["prd_a1b2c3", "prd_d4e5f6"],
"isCumulative": true
}Aqui
value: 500significa um abatimento fixo de R$ 5,00, e o cupom só vale para os produtos listados emallowedItemIds.
Resposta
201 Created — retorna o objeto completo do cupom, sem envelope. Coupons não trazem os blocos merchant nem _links (HATEOAS) que outros recursos expõem.
{
"id": "dis_01hqzvabc",
"name": "Black Friday 25%",
"enabled": true,
"code": "BLACKFRIDAY25",
"type": "percentage",
"value": 25,
"minCartAmount": 10000,
"maxCartAmount": null,
"usageLimit": 100,
"limitOneUsePerCustomer": true,
"initDate": "2026-04-01T00:00:00.000Z",
"endDate": "2026-04-30T23:59:59.000Z",
"allowedItemIds": null,
"allowedCustomerIds": null,
"usageQuantity": 0,
"minCartItems": 0,
"maxCartItems": 0,
"isCumulative": false,
"updatedAt": "2026-04-12T17:56:33.000Z",
"createdAt": "2026-04-12T17:56:33.000Z"
}| Campo | Tipo | Descrição |
|---|---|---|
id | string | ID opaco do cupom, prefixo dis_. Armazene a string inteira — não faça parsing. |
name | string | Nome descritivo. |
enabled | boolean | Se o cupom está ativo. |
code | string | Código aplicado no checkout. |
type | string | flat ou percentage. |
value | integer | Desconto: centavos (flat) ou percentual (percentage). |
minCartAmount / maxCartAmount | integer | null | Faixa de valor do carrinho (centavos); null quando sem limite. |
usageLimit | integer | Limite total de resgates. |
limitOneUsePerCustomer | boolean | Um uso por cliente. |
initDate / endDate | string (date-time) | Janela de validade, ISO 8601 UTC. |
allowedItemIds / allowedCustomerIds | array | null | Restrições por produto/cliente; null quando sem restrição. |
usageQuantity | integer | Resgates já realizados. Nasce em 0. |
minCartItems / maxCartItems | integer | Faixa de quantidade de itens no carrinho. |
isCumulative | boolean | Se acumula com outros descontos. |
createdAt / updatedAt | string (date-time) | Timestamps de criação e última atualização, ISO 8601 UTC. |
Note a normalização: datas enviadas como
2026-04-01T00:00:00Zvoltam com milissegundos (...000Z). Trate as datas como o servidor as devolveu.
Erros
A API responde com um envelope padrão e um error.code estável — trate sempre pelo code, nunca pela message. Veja Tratamento de Erros e o Catálogo de Códigos de Erro.
error.code | HTTP | Quando ocorre |
|---|---|---|
invalidParameters | 400 | Validação genérica do corpo (campo faltando, tipo errado, fora da faixa). Detalhes em error.params. |
couponCreateItemIdIsInvalid | 400 | Algum ID em allowedItemIds não existe ou é inválido. |
couponCreateCustomerIdIsInvalid | 400 | Algum ID em allowedCustomerIds não existe ou é inválido. |
couponCreateFailed | 400 | Falha geral ao criar o cupom. |
unauthorized | 401 | SelectKey ausente, inválida ou revogada. |
forbidden | 403 | Autenticado, mas sem permissão para criar cupons. |
unprocessableEntity | 422 | Entidade não processável (regra de negócio). |
tooManyRequests | 429 | Limite de requisições excedido — respeite error.retryAfterMinutes e repita com backoff. |
serverError | 500 | Erro interno — repita com backoff; se persistir, contate o suporte. |
Boas práticas
- Confira o
typeantes de definirvalue. Use centavos paraflate o número do percentual parapercentage. Um teste rápido em sandbox (sl_test_...) evita lançar um cupom com desconto errado. - Envie
X-Idempotency-Keyem toda criação. Sem ela, uma retentativa por timeout pode gerar dois cupons com o mesmocode. - Defina sempre
initDateeendDate. Sem janela, o cupom fica ativo indefinidamente enquantoenabledfortrue— fácil de esquecer e abusar. - Limite o uso com
usageLimit(teto global) elimitOneUsePerCustomerpara conter abuso de campanhas públicas. - Valide os IDs de restrição antes de enviar. IDs inexistentes em
allowedItemIds/allowedCustomerIdscausamcouponCreateItemIdIsInvalid/couponCreateCustomerIdIsInvalide abortam a criação. - Trate
codecomo sensível a maiúsculas/duplicidade. A API não impede dois cupons com o mesmocode; padronize a geração (ex.: maiúsculas) e verifique colisões no seu sistema antes de criar. - Guarde o
idretornado, não ocode, como referência interna estável — ocodepode ser reaproveitado em campanhas distintas.
Veja também
- Visão geral de Cupons — modelo do objeto e ciclo de vida.
- Ler um cupom · Atualizar · Listar · Excluir
- Convenções da API — centavos, datas ISO 8601, IDs opacos.
- Idempotência · Autenticação · Catálogo de Códigos de Erro
How is this guide?