PagnovoPagnovodocs

Referência da API

Criar oferta

Cria uma Offer vinculada a um Product. O tipo (one-time vs recurring) é decidido pelo campo `billingCycle`: ausente ou `null` = pagamento único; preenchido com enum = cobrança recorrente. Valor em **centavos** (100 = R$ 1,00). Veja a seção 'Produtos e Ofertas' para a tabela completa de billing cycles. **PDF de entrega:** este endpoint **não aceita** `deliveryPdfUrl` no corpo. Crie a oferta primeiro e depois envie o PDF em [POST /v2/offers/:id/delivery-pdf](/docs/api/upload-offer-pdf).

POST/v2/offers
PDF é endpoint separado
deliveryPdfUrl Enviar `deliveryPdfUrl` aqui retorna 400. O PDF é hospedado no nosso S3 e enviado via multipart em `POST /v2/offers/:id/delivery-pdf`. Quando consultado depois, vem como signed URL temporária (1h).

Autenticação

HTTP Basic Auth. Envie sua secret key no header:

Authorization: Basic {base64(secret:SUA_SECRET_KEY)}

Parâmetros

productIdstring (UUID)obrigatório

UUID do Product ao qual essa Offer pertence. Precisa pertencer à sua conta.

Exemplo: prd_111aaa-bbb-ccc

namestringobrigatório

Nome da oferta, exibido no checkout (ex: 'Plano anual com desconto').

Exemplo: Mensal 12x

descriptionstringopcional

Descrição da oferta.

Exemplo: Acesso por 12 meses

amountnumber (integer, centavos)obrigatório

Valor cobrado **por ciclo** em centavos. 100 = R$ 1,00. R$ 49 = 4900. Range: 100 a 5.000.000.

Exemplo: 4900

externalIdstringopcional

Sua referência interna. Único por conta.

Exemplo: curso-mkt-mensal

billingCycleenum | nullopcional

`null` ou omitido = one-time. Valores recurring: `DAILY`, `WEEKLY`, `MONTHLY`, `QUARTERLY`, `SEMIANNUAL`, `YEARLY`.

Exemplo: MONTHLY

billingCycleCountnumberopcional

Quantas unidades do `billingCycle` entre cobranças. Default 1. Ex: `MONTHLY` + count=3 = cobra a cada 3 meses. Ignorado em one-time.

Exemplo: 1

maxCyclesnumber | nullopcional

Total máximo de cobranças antes da Subscription expirar. `null` = infinito. Ignorado em one-time. Ex: MONTHLY × max=12 = anual parcelado em 12.

Exemplo: 12

trialDaysnumberopcional

Dias grátis antes da primeira cobrança. Default 0. Ignorado em one-time. Range: 0 ao máximo configurado no servidor.

Exemplo: 7

metadataobjectopcional

Objeto JSON arbitrário.

Exemplo: { "tier": "premium" }

Body da requisição

Content-Type: application/json

JSON
// Exemplo one-time:
{
  "productId": "prd_111aaa-bbb-ccc",
  "name": "Pagamento único",
  "amount": 49700,
  "externalId": "curso-mkt-onetime"
}

// Exemplo recurring com trial:
{
  "productId": "prd_111aaa-bbb-ccc",
  "name": "Mensal com trial de 7 dias",
  "amount": 490,
  "billingCycle": "MONTHLY",
  "billingCycleCount": 1,
  "maxCycles": null,
  "trialDays": 7
}

// Exemplo recurring com fim definido:
{
  "productId": "prd_111aaa-bbb-ccc",
  "name": "Anual em 12x mensais",
  "amount": 990,
  "billingCycle": "MONTHLY",
  "maxCycles": 12,
  "trialDays": 0
}

Respostas

201

Oferta criada (sem PDF — deliveryPdfUrl: null). Em one-time, campos como maxCycles/trialDays voltam aos defaults (null/0). Pra anexar PDF, use POST /v2/offers/:id/delivery-pdf em seguida.

JSON
{
  "id": "off_xyz789",
  "createdByUserId": "u-1234",
  "productId": "prd_111aaa-bbb-ccc",
  "externalId": "curso-mkt-mensal",
  "name": "Mensal 12x",
  "description": "Acesso por 12 meses",
  "amount": 4900,
  "billingCycle": "MONTHLY",
  "billingCycleCount": 1,
  "maxCycles": 12,
  "trialDays": 7,
  "deliveryPdfUrl": null,
  "active": true,
  "metadata": null,
  "deletedAt": null,
  "createdAt": "2026-05-26T14:38:00.000Z",
  "updatedAt": "2026-05-26T14:38:00.000Z"
}
400

Validação falhou, externalId já existe ou deliveryPdfUrl enviado (use endpoint separado).

JSON
{ "status": 400, "error": "billingCycle invalido" }
404

Product não encontrado.

JSON
{ "status": 404, "error": "Produto nao encontrado" }

Exemplos

JavaScript
const token = Buffer.from("secret:" + process.env.PAGNOVO_SECRET_KEY).toString("base64");

// Mensal R$ 49 com 7 dias de trial, sem limite de ciclos
const offer = await fetch("https://api.pagnovo.com/v2/offers", {
  method: "POST",
  headers: { Authorization: `Basic ${token}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    productId: "prd_111aaa-bbb-ccc",
    name: "Plano Mensal",
    amount: 4900,                   // R$ 49 em centavos
    billingCycle: "MONTHLY",
    billingCycleCount: 1,
    trialDays: 7,
  }),
}).then(r => r.json());

console.log("offer criada:", offer.id);