Referência da API
Criar assinatura
Cria uma Subscription recorrente. Pode ser criada de duas formas: 1. **A partir de uma Offer** (modo snapshot): passe `offerId` e os valores são copiados da Offer (amount, billingCycle, billingCycleCount, maxCycles, trialDays). 2. **Standalone** (sem Offer): passe `amount` e `billingCycle` manualmente. Valores monetários em **centavos**. A chave de API precisa da permissão `isInvoiceAvailable`.
/v2/subscriptionsofferId Quando você cria via `offerId`, os campos `amount`/`billingCycle`/etc são copiados da Offer no momento da criação. Mudanças posteriores na Offer **não afetam** essa Subscription. Pra mudar valores depois, edite a Subscription diretamente via PATCH.Autenticação
HTTP Basic Auth. Envie sua secret key no header:
Authorization: Basic {base64(secret:SUA_SECRET_KEY)}Parâmetros
customerIdstring (UUID)obrigatórioUUID do Customer dono da assinatura. Precisa pertencer à sua conta e não estar arquivado.
Exemplo: c8a5f4d2-...
offerIdstring (UUID)opcionalUUID da Offer pra puxar snapshot. Se omitido, você precisa informar `amount` e `billingCycle` manualmente. A Offer precisa ser **recurring** — Offers one-time são rejeitadas com 400.
Exemplo: off_xyz789
amountnumber (integer, centavos)opcionalValor cobrado por ciclo, em centavos. Obrigatório (>=100) se `offerId` não for informado. Se for, sobrescreve o valor da Offer.
Exemplo: 9900
descriptionstringopcionalDescrição da assinatura. Aparece em cada invoice recorrente gerada por ela. Se omitida, a invoice usa um texto padrão ("Cobrança recorrente — ciclo N").
Exemplo: Assinatura de consultoria — plano mensal
billingCycle'DAILY' | 'WEEKLY' | 'MONTHLY' | 'QUARTERLY' | 'SEMIANNUAL' | 'YEARLY'opcionalCiclo de cobrança. Obrigatório se `offerId` não for informado.
Exemplo: MONTHLY
billingCycleCountnumberopcionalMultiplicador do ciclo. `MONTHLY` + count=3 = a cada 3 meses. Default: 1.
Exemplo: 1
maxCyclesnumber | nullopcionalTotal máximo de cobranças antes da Subscription expirar automaticamente. `null` ou ausente = infinito.
Exemplo: 12
startedAtstring (ISO 8601)opcionalData de início da assinatura. Default: agora. Se a Offer tem `trialDays > 0`, a Subscription nasce em `TRIAL` com `nextBillingAt = startedAt + trialDays`.
Exemplo: 2026-06-01T00:00:00.000Z
nextBillingAtstring (ISO 8601)opcionalData da próxima cobrança. Sobrescreve o cálculo automático (`startedAt + trialDays` ou `startedAt` direto).
Exemplo: 2026-06-08T00:00:00.000Z
expiresAtstring (ISO 8601) | nullopcionalData fixa de fim da Subscription. Tem que ser depois de `startedAt`. Pode usar junto com `maxCycles` — o que acontecer primeiro encerra.
Exemplo: 2027-06-01T00:00:00.000Z
daysBeforeDueToBillnumberopcionalQuantos dias antes do vencimento o sistema **gera a Invoice**. Default: 5. Range: 0 a 60.
Exemplo: 5
daysBeforeDueToNotifynumberopcionalQuantos dias antes do vencimento o sistema **envia lembrete** ao cliente. Default: 3. Range: 0 a 30.
Exemplo: 3
lateFeeType'NONE' | 'FIXED' | 'PERCENTAGE'opcionalTipo da multa aplicada em invoices vencidas. Default: `NONE`.
Exemplo: PERCENTAGE
lateFeeValuenumber (integer)opcionalValor da multa. Obrigatório se `lateFeeType != NONE`. Quando `FIXED`: **centavos** (ex: 500 = R$ 5,00). Quando `PERCENTAGE`: **basis points** (ex: 200 = 2%).
Exemplo: 200
interestRatePerMonthnumber (integer, basis points)opcionalJuros mensais aplicados proporcionalmente por dia de atraso. Em basis points (100 = 1% ao mês). Default: 0.
Exemplo: 100
paymentMethodsInvoicePaymentMethod[]opcionalMétodos de pagamento aceitos nas invoices geradas. Default: `['PIX']`.
Exemplo: ["PIX"]
notificationConfigobjectopcionalConfiguração de quais notificações enviar e por qual canal. Estrutura livre.
Exemplo: { "onCreate": true, "channels": ["EMAIL"] }
metadataobjectopcionalJSON arbitrário pra anexar dados do seu sistema.
Exemplo: { "source": "import" }
Body da requisição
Content-Type: application/json
// Modo 1 — A partir de uma Offer (snapshot):
{
"customerId": "c8a5f4d2-...",
"offerId": "off_xyz789",
"lateFeeType": "PERCENTAGE",
"lateFeeValue": 200,
"interestRatePerMonth": 100,
"daysBeforeDueToBill": 5,
"daysBeforeDueToNotify": 3
}
// Modo 2 — Standalone (sem Offer):
{
"customerId": "c8a5f4d2-...",
"amount": 9900,
"billingCycle": "MONTHLY",
"billingCycleCount": 1,
"maxCycles": 12,
"description": "Assinatura de consultoria — plano mensal",
"startedAt": "2026-06-01T00:00:00.000Z",
"lateFeeType": "FIXED",
"lateFeeValue": 500
}Respostas
Subscription criada. status inicial é TRIAL se há trialDays > 0 da Offer, senão ACTIVE. Valores em centavos.
{
"id": "sub_abc123-...",
"createdByUserId": "u-1234",
"customerId": "c8a5f4d2-...",
"offerId": "off_xyz789",
"status": "ACTIVE",
"amount": 4900,
"billingCycle": "MONTHLY",
"billingCycleCount": 1,
"maxCycles": 12,
"currentCycle": 0,
"nextBillingAt": "2026-06-01T00:00:00.000Z",
"daysBeforeDueToBill": 5,
"daysBeforeDueToNotify": 3,
"paymentMethods": ["PIX"],
"lateFeeType": "PERCENTAGE",
"lateFeeValue": 200,
"interestRatePerMonth": 100,
"startedAt": "2026-06-01T00:00:00.000Z",
"expiresAt": null,
"canceledAt": null,
"metadata": null,
"createdAt": "2026-05-26T14:32:01.923Z",
"updatedAt": "2026-05-26T14:32:01.923Z"
}Validação falhou. Causas comuns: Offer one-time, amount/billingCycle ausente em modo standalone, lateFeeValue ausente com lateFeeType != NONE, daysBeforeDueToBill fora de range.
{
"status": 400,
"error": "Oferta de pagamento unico nao pode virar assinatura"
}Customer ou Offer não encontrados.
{ "status": 404, "error": "Customer nao encontrado" }Exemplos
curl -X POST "https://api.pagnovo.com/v2/subscriptions" \
-H "Authorization: Basic $(echo -n 'secret:SUA_SECRET_KEY' | base64)" \
-H "Content-Type: application/json" \
-d '{
"customerId": "c8a5f4d2-...",
"offerId": "off_xyz789",
"lateFeeType": "PERCENTAGE",
"lateFeeValue": 200,
"interestRatePerMonth": 100
}'const token = Buffer.from("secret:" + process.env.PAGNOVO_SECRET_KEY).toString("base64");
// Cria sub padrão R$49/mês sem trial, com multa 2% + 1% ao mês
const res = await fetch("https://api.pagnovo.com/v2/subscriptions", {
method: "POST",
headers: { Authorization: `Basic ${token}`, "Content-Type": "application/json" },
body: JSON.stringify({
customerId: "c8a5f4d2-...",
offerId: "off_xyz789",
lateFeeType: "PERCENTAGE",
lateFeeValue: 200, // 2% em basis points
interestRatePerMonth: 100, // 1% ao mês em basis points
}),
});
const sub = await res.json();
console.log("status inicial:", sub.status, "próxima cobrança:", sub.nextBillingAt);