PagnovoPagnovodocs

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.

POST/v2/invoices
Soma dos items precisa bater com amount
items 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) | nullopcional

UUID do Customer dono da Invoice. `null` ou ausente = Invoice pública. Quando presente, ativa envio automático de notificações.

Exemplo: c8a5f4d2-...

subscriptionIdstring (UUID)opcional

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

Descriçã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ório

Valor total da cobrança, em centavos. Se `items` for enviado, deve bater com a soma de `totalPrice`.

Exemplo: 49700

itemsInvoiceItem[]opcional

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

Data de vencimento. Depois disso a Invoice vira `OVERDUE`.

Exemplo: 2026-06-15T00:00:00.000Z

expiresAtstring (ISO 8601)opcional

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

Tipo de multa aplicada em atraso. Default: `NONE`.

Exemplo: FIXED

lateFeeValuenumber (integer)opcional

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

Juros mensais aplicados proporcionalmente por dia de atraso. Em basis points (100 = 1% ao mês). Default: 0.

Exemplo: 100

paymentMethodsInvoicePaymentMethod[]opcional

Métodos aceitos no checkout. Default: `['PIX']`.

Exemplo: ["PIX"]

successUrlstring (URL)opcional

URL para redirecionar o cliente após pagamento bem-sucedido na `hostedUrl`.

Exemplo: https://app.exemplo.com/sucesso

failureUrlstring (URL)opcional

URL para redirecionar o cliente em caso de falha no pagamento.

Exemplo: https://app.exemplo.com/erro

notificationConfigobjectopcional

Configuraçã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 }

metadataobjectopcional

JSON arbitrário pra anexar dados do seu sistema.

Exemplo: { "orderId": "pedido-9876" }

Body da requisição

Content-Type: application/json

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

201

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.

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

Validação falhou. Causas comuns: soma dos items != amount, dueDate inválida, expiresAt antes de dueDate, lateFeeValue ausente com lateFeeType != NONE.

JSON
{
  "status": 400,
  "error": "Soma dos items (50000) nao bate com amount (49700)"
}
404

Customer ou Subscription não encontrados.

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

Exemplos

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