Referência da API
Criar cupom
Cria um cupom de desconto. V2: o cupom só funciona nas Offers da whitelist (passe offerIds para já criar com a whitelist preenchida). Códigos são normalizados pra UPPERCASE — verao2026 é salvo como VERAO2026.
Cupom só tem efeito em Offers recorrentes (que geram Invoice). QuickLink e Checkout one-time não aceitam cupom.
A chave de API precisa da permissão isInvoiceAvailable.
/v2/couponsdiscountValue Quando discountType: PERCENTAGE, discountValue está em basis points (1.000 = 10%, 10.000 = 100%). Quando discountType: FIXED, está em centavos (100 = R$ 1,00). minPurchaseAmount também é em centavos. Veja a seção 'Cupons (visão geral)' para a tabela completa.Autenticação
HTTP Basic Auth. Envie sua secret key no header:
Authorization: Basic {base64(secret:SUA_SECRET_KEY)}Parâmetros
codestringobrigatórioCódigo do cupom. 3-30 caracteres. Aceita apenas A-Z, 0-9, - e _. É normalizado pra UPPERCASE no servidor (você pode mandar minúsculo). Único por conta.
Exemplo: VERAO2026
descriptionstringopcionalDescrição interna do cupom (não é mostrada ao cliente).
Exemplo: Promoção de verão — 15% off
discountType'PERCENTAGE' | 'FIXED'obrigatórioTipo do desconto. PERCENTAGE desconta uma porcentagem; FIXED desconta um valor absoluto. Esse campo fica imutável depois do primeiro uso do cupom.
Exemplo: PERCENTAGE
discountValuenumber (integer)obrigatórioValor do desconto. Para PERCENTAGE: basis points entre 1 (0,01%) e 10.000 (100%). Para FIXED: centavos entre 100 (R$ 1,00) e 5.000.000 (R$ 50.000,00). Imutável após primeiro uso.
Exemplo: 1500
maxUsesnumber | nullopcionalLimite global de usos do cupom. null ou ausente = ilimitado. O limite é respeitado mesmo em corrida de checkouts simultâneos. Máximo: 1.000.000.
Exemplo: 500
validFromstring (ISO 8601)opcionalData a partir da qual o cupom é válido. Pode estar no passado (não é validado). Se omitido, é válido desde sempre.
Exemplo: 2026-06-01T00:00:00.000Z
validUntilstring (ISO 8601)opcionalData de expiração. Não pode estar no passado — o servidor rejeita com 400. Se omitido, o cupom nunca expira.
Exemplo: 2026-12-31T23:59:59.000Z
minPurchaseAmountnumber | nullopcionalValor mínimo da fatura (em centavos) para o cupom ser aplicável. null = sem mínimo. Ex: 5000 = R$ 50,00.
Exemplo: 5000
offerIdsstring[]opcionalIDs das Offers onde o cupom funciona. Sem isso, o cupom existe mas não funciona em lugar nenhum até você adicionar via POST /v2/coupons/:id/offers. Todos os IDs precisam pertencer à sua conta.
Exemplo: ["off_plano_mensal", "off_plano_anual"]
metadataobjectopcionalObjeto JSON arbitrário para anexar informação do seu sistema.
Exemplo: { "campaign": "summer-launch" }
Body da requisição
Content-Type: application/json
// Cupom de 15% off, válido até 31/dez, mínimo R$ 50:
{
"code": "VERAO2026",
"description": "Promoção de verão — 15% off",
"discountType": "PERCENTAGE",
"discountValue": 1500,
"maxUses": 500,
"validFrom": "2026-06-01T00:00:00.000Z",
"validUntil": "2026-12-31T23:59:59.000Z",
"minPurchaseAmount": 5000,
"offerIds": ["off_plano_mensal", "off_plano_anual"],
"metadata": { "campaign": "summer-launch" }
}
// Cupom de R$ 10 fixo, ilimitado, sem mínimo:
{
"code": "BEM_VINDO",
"discountType": "FIXED",
"discountValue": 1000,
"maxUses": null,
"offerIds": ["off_plano_mensal"]
}Respostas
Cupom criado. Note que o response não inclui a whitelist — para ver as Offers vinculadas, faça GET /v2/coupons/:id.
{
"id": "cpn_a8f3d2e1-9b4c-4e5f-8a7d-2e5f6c1d4b9a",
"createdByUserId": "u-1234",
"code": "VERAO2026",
"description": "Promoção de verão — 15% off",
"discountType": "PERCENTAGE",
"discountValue": 1500,
"status": "ACTIVE",
"maxUses": 500,
"currentUses": 0,
"validFrom": "2026-06-01T00:00:00.000Z",
"validUntil": "2026-12-31T23:59:59.000Z",
"minPurchaseAmount": 5000,
"metadata": { "campaign": "summer-launch" },
"deletedAt": null,
"createdAt": "2026-05-26T14:32:01.923Z",
"updatedAt": "2026-05-26T14:32:01.923Z"
}Erro de validação. Causas comuns: código já existe, formato inválido, discountValue fora do range, validUntil no passado, ou alguma offerId não pertence à sua conta.
{
"status": 400,
"error": "Ja existe um cupom com codigo \"VERAO2026\""
}Exemplos
curl -X POST "https://api.ihubplay.com/v2/coupons" \
-H "Authorization: Basic $(echo -n 'secret:SUA_SECRET_KEY' | base64)" \
-H "Content-Type: application/json" \
-d '{
"code": "VERAO2026",
"discountType": "PERCENTAGE",
"discountValue": 1500,
"maxUses": 500,
"validUntil": "2026-12-31T23:59:59.000Z",
"offerIds": ["off_plano_mensal"]
}'const token = Buffer.from("secret:" + process.env.IHUBGAMES_SECRET_KEY).toString("base64");
// 15% off, máximo 500 usos, expira 31/dez
const res = await fetch("https://api.ihubplay.com/v2/coupons", {
method: "POST",
headers: {
Authorization: `Basic ${token}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
code: "verao2026", // será normalizado pra VERAO2026
discountType: "PERCENTAGE",
discountValue: 1500, // 15% (basis points!)
maxUses: 500,
validUntil: "2026-12-31T23:59:59.000Z",
offerIds: ["off_plano_mensal"],
}),
});
if (!res.ok) {
const err = await res.json();
console.error(err.error);
return;
}
const coupon = await res.json();
console.log("criado:", coupon.code, "id:", coupon.id);