iHubGamesiHubGamesdocs

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.

POST/v2/coupons
Unidades dependem do tipo
discountValue 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ório

Có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

descriptionstringopcional

Descrição interna do cupom (não é mostrada ao cliente).

Exemplo: Promoção de verão — 15% off

discountType'PERCENTAGE' | 'FIXED'obrigatório

Tipo 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ório

Valor 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 | nullopcional

Limite 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)opcional

Data 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)opcional

Data 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 | nullopcional

Valor mínimo da fatura (em centavos) para o cupom ser aplicável. null = sem mínimo. Ex: 5000 = R$ 50,00.

Exemplo: 5000

offerIdsstring[]opcional

IDs 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"]

metadataobjectopcional

Objeto JSON arbitrário para anexar informação do seu sistema.

Exemplo: { "campaign": "summer-launch" }

Body da requisição

Content-Type: application/json

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

201

Cupom criado. Note que o response não inclui a whitelist — para ver as Offers vinculadas, faça GET /v2/coupons/:id.

JSON
{
  "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"
}
400

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.

JSON
{
  "status": 400,
  "error": "Ja existe um cupom com codigo \"VERAO2026\""
}

Exemplos

cURL
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"]
  }'
JavaScript
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);