Referência da API
Criar fatura
Cria uma Invoice (cobrança individual). Pode ser: - **Avulsa** sem `customerId` — Invoice "pública", qualquer pessoa com a `hostedUrl` paga. - **Vinculada a Customer** — passe `customerId`. Notificações automáticas são enviadas. - **Vinculada a Subscription** — passe `subscriptionId` (uso interno: o cron de billing usa isso; raramente você cria assim via API). Valores em **centavos**. A `hostedUrl` é gerada automaticamente.
/v2/invoicesitems Se você enviar `items[]`, a soma dos `totalPrice` (em centavos) deve bater exatamente com `amount`. E `totalPrice` de cada item deve ser `quantity * unitPrice`. Se não bater, a API rejeita com 400.Autenticação
HTTP Basic Auth. Envie sua secret key no header:
Authorization: Basic {base64(secret:SUA_SECRET_KEY)}Parâmetros
customerIdstring (UUID) | nullopcionalUUID do Customer dono da Invoice. `null` ou ausente = Invoice pública. Quando presente, ativa envio automático de notificações.
Exemplo: c8a5f4d2-...
subscriptionIdstring (UUID)opcionalUUID da Subscription que gerou essa Invoice. Uso interno (o cron de billing seta isso). Se enviado, o `customerId` precisa bater com o da Subscription.
Exemplo: sub_abc123-...
descriptionstringobrigatórioDescrição da cobrança. Exibida no `hostedUrl` ao cliente final e em notificações.
Exemplo: Setup inicial + 3 meses de consultoria
amountnumber (integer, centavos)obrigatórioValor total da cobrança, em centavos. Se `items` for enviado, deve bater com a soma de `totalPrice`.
Exemplo: 49700
itemsInvoiceItem[]opcionalLinhas detalhadas. Cada item: `description`, `quantity` (int >= 1), `unitPrice` (centavos), `totalPrice` (centavos, deve ser `quantity * unitPrice`). A soma dos `totalPrice` precisa bater com `amount`.
Exemplo: [{ "description": "Setup", "quantity": 1, "unitPrice": 19700, "totalPrice": 19700 }]
dueDatestring (ISO 8601)obrigatórioData de vencimento. Depois disso a Invoice vira `OVERDUE`.
Exemplo: 2026-06-15T00:00:00.000Z
expiresAtstring (ISO 8601)opcionalData em que a `hostedUrl` para de aceitar pagamento (Invoice vira `EXPIRED`). Default: `dueDate + 30 dias`. Não pode ser antes de `dueDate`.
Exemplo: 2026-07-15T00:00:00.000Z
lateFeeType'NONE' | 'FIXED' | 'PERCENTAGE'opcionalTipo de multa aplicada em atraso. Default: `NONE`.
Exemplo: FIXED
lateFeeValuenumber (integer)opcionalValor da multa. **FIXED**: em centavos (500 = R$ 5,00). **PERCENTAGE**: em basis points (200 = 2%). Obrigatório se `lateFeeType != NONE`.
Exemplo: 500
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 aceitos no checkout. Default: `['PIX']`.
Exemplo: ["PIX"]
successUrlstring (URL)opcionalURL para redirecionar o cliente após pagamento bem-sucedido na `hostedUrl`.
Exemplo: https://app.exemplo.com/sucesso
failureUrlstring (URL)opcionalURL para redirecionar o cliente em caso de falha no pagamento.
Exemplo: https://app.exemplo.com/erro
notificationConfigobjectopcionalConfiguração de notificações automáticas. Se ausente, default: envia e-mail de criação se houver `customerId` com email. Use `{ onCreate: false }` pra desabilitar e-mail de criação.
Exemplo: { "onCreate": true }
metadataobjectopcionalJSON arbitrário pra anexar dados do seu sistema.
Exemplo: { "orderId": "pedido-9876" }
Body da requisição
Content-Type: application/json
// Invoice avulsa com customer e items:
{
"customerId": "c8a5f4d2-...",
"description": "Setup inicial + 3 meses de consultoria",
"amount": 49700,
"dueDate": "2026-06-15T00:00:00.000Z",
"items": [
{ "description": "Taxa de setup", "quantity": 1, "unitPrice": 19700, "totalPrice": 19700 },
{ "description": "Consultoria mensal", "quantity": 3, "unitPrice": 10000, "totalPrice": 30000 }
],
"lateFeeType": "FIXED",
"lateFeeValue": 500,
"interestRatePerMonth": 100,
"paymentMethods": ["PIX"]
}
// Invoice pública (sem customer):
{
"description": "Mensalidade do plano Pro",
"amount": 4900,
"dueDate": "2026-06-15T00:00:00.000Z"
}Respostas
Invoice criada com status PENDING. hostedUrl gerada automaticamente. Se houver customerId com email e a notificação onCreate estiver habilitada, um e-mail de criação foi enfileirado.
{
"id": "inv_111aaa",
"createdByUserId": "u-1234",
"customerId": "c8a5f4d2-...",
"subscriptionId": null,
"status": "PENDING",
"description": "Setup inicial + 3 meses de consultoria",
"items": [
{ "description": "Taxa de setup", "quantity": 1, "unitPrice": 19700, "totalPrice": 19700 },
{ "description": "Consultoria mensal", "quantity": 3, "unitPrice": 10000, "totalPrice": 30000 }
],
"amount": 49700,
"amountPaid": 0,
"refundedAmount": null,
"dueDate": "2026-06-15T00:00:00.000Z",
"expiresAt": "2026-07-15T00:00:00.000Z",
"paidAt": null,
"canceledAt": null,
"refundedAt": null,
"lateFeeType": "FIXED",
"lateFeeValue": 500,
"interestRatePerMonth": 100,
"paymentMethods": ["PIX"],
"hostedUrl": "https://checkout.pagnovo.com/i/inv_111aaa",
"successUrl": null,
"failureUrl": null,
"metadata": null,
"createdAt": "2026-05-26T14:32:01.923Z",
"updatedAt": "2026-05-26T14:32:01.923Z"
}Validação falhou. Causas comuns: soma dos items != amount, dueDate inválida, expiresAt antes de dueDate, lateFeeValue ausente com lateFeeType != NONE.
{
"status": 400,
"error": "Soma dos items (50000) nao bate com amount (49700)"
}Customer ou Subscription não encontrados.
{ "status": 404, "error": "Customer nao encontrado" }Exemplos
curl -X POST "https://api.pagnovo.com/v2/invoices" \
-H "Authorization: Basic $(echo -n 'secret:SUA_SECRET_KEY' | base64)" \
-H "Content-Type: application/json" \
-d '{
"customerId": "c8a5f4d2-...",
"description": "Mensalidade Setembro",
"amount": 4900,
"dueDate": "2026-09-15T00:00:00.000Z"
}'const token = Buffer.from("secret:" + process.env.PAGNOVO_SECRET_KEY).toString("base64");
const res = await fetch("https://api.pagnovo.com/v2/invoices", {
method: "POST",
headers: { Authorization: `Basic ${token}`, "Content-Type": "application/json" },
body: JSON.stringify({
customerId: "c8a5f4d2-...",
description: "Setup inicial",
amount: 49700, // R$ 497 em centavos
dueDate: "2026-06-15T00:00:00.000Z",
lateFeeType: "FIXED",
lateFeeValue: 500, // R$ 5,00 em centavos
interestRatePerMonth: 100, // 1% ao mês
}),
});
const inv = await res.json();
console.log("URL pública:", inv.hostedUrl);