Referência da API
Todos os endpoints
Pix
Status de cobrança
/v1/charges/:chargeIdCobrança imediata
/v1/charges/pixCom esta funcionalidade você pode criar um QR Code de cobrança imediata. **Case de uso:** _Como SaaS, quero gerar cobranças preenchendo apenas o valor do produto e nada mais_ **Regras condicionais (COBV):** `name` e `cep` do `customer` só são aceitos junto com `expiration`. Havendo `expiration` e `customer`, o trio `documentNumber`, `name` e `cep` passa a ser obrigatório em bloco. **Resposta:** os campos vêm na raiz — `emv` e `qrCode`, não aninhados sob `pix`. O `qrCode` já é uma data URL PNG pronta para exibir; não é preciso gerar a imagem no seu lado. **Correlação com o pedido:** envie `metadata` na criação e ele volta na resposta e no payload do webhook `payment.success`. É a forma recomendada de amarrar o pagamento ao seu pedido. > ⚠️ **Esta rota não tem idempotência.** `externalId` é aceito e descartado; duas chamadas iguais criam **duas cobranças**. Controle duplicidade no seu lado (índice `pedido → cobrança`) ou use `POST /v1/charges`, que responde `409 DUPLICATE_CHARGE`. O campo `externalTxid` documentado aqui identifica loja, caixa ou vendedor — não serve como chave de idempotência.
Split de pagamentos
Cobrança imediata com split
/v1/charges/pixCom esta funcionalidade você pode criar um QR Code de cobrança na sua conta e fazer split para outras contas ValidaPay. **Case de uso:** _Como SaaS, tenho parceiros/afiliados PF ou PJ. Quero gerar cobranças na minha conta preenchendo apenas o valor do produto e fazer split para as contas dos meus parceiros._ Use `externalTxid` para identificar a **loja**, o **caixa** ou o **vendedor** responsável pela cobrança.
Split para Conta Master
/v1/charges/pixCom esta funcionalidade você pode criar um QR Code de cobrança na conta de um _Seller_ e fazer split para a sua conta. **Case de uso:** _Como SaaS tenho vários Sellers, cada um deles possui uma subconta ValidaPay. Quero gerar cobranças para qualquer subconta preenchendo apenas o valor do produto e fazer split para a minha conta Master_ > ⚠️ **Atenção:** O número da subconta é retornado via webhook quando a subconta é aprovada. Use `externalTxid` para identificar a **loja**, o **caixa** ou o **vendedor** responsável pela cobrança.
Status de cobrança com split
/v1/charges/:chargeIdSubcontas ValidaPay
Criar subconta PF
/v1/proposalsCom esta funcionalidade você pode criar subcontas Pessoa Física na ValidaPay. Ao criar a subconta ela ficará associada à sua conta (chamaremos de conta Master). Case de uso: _Como SaaS tenho vários Sellers, preciso gerar cobranças para esses Sellers e receber split em cada venda._ > ⚠️ **Atenção:** Não é possivel criar uma subconta com mesmo email e telefone da _master account._ > ⚠️ **Atenção:** Dados de renda/faturamento no campo financialDetails são obrigatórios. Os respectivos códigos estão descritos no apêndice Campos Financeiros ao final da sessão Subcontas ValidaPay
Criar subconta PJ
/v1/proposalsCom esta funcionalidade você pode criar subcontas Pessoa Jurídica na ValidaPay. Ao criar a subconta ela ficará associada à sua conta (chamaremos de conta Master). Case de uso: _Como SaaS tenho vários Sellers, preciso gerar cobranças para esses Sellers e receber split em cada venda._ > ⚠️ **Atenção:** Não é possivel criar uma subconta com mesmo email e telefone da _master account_ > ⚠️ **Atenção:** Dados de renda/faturamento no campo financialDetails são obrigatórios. Os respectivos códigos estão descritos no apêndice Campos Financeiros ao final da sessão Subcontas ValidaPay
Status de subconta
/v1/proposals/:formId@botton Quando a conta for aprovada, será enviado um evento na URL de webhook cadastrada nas rotas de criação de conta PF e PJ. O evento segue o seguinte layout: ``` json { "event": "account_approved", "status": "CONFIRMED", "account": { "account": "123456", "branch": "0001", "documentNumber": "123456789", "ispb": "13935893", "name": "Werner Heisenberg" }, "onboardingId": "fc0e6dab-8210-4f2d-8fce-2e94990b63ef", "documentNumber": "1234567889", "formId": "7b83fcb4-fe9c-4ad3-8d3a-621fe9c9ffc1", "createdAt": "2025-06-02T17:46:10.1120909" } ```
Listar subcontas
/v1/accounts/subaccountsCom esta rota você poderá listar todas as subcontas associadas à sua _master account_
Listar cobranças
/v1/chargesCom esta rota você poderá listar todas as cobranças que a sua _master account_ gerou em uma subcontas
Saldo subcontas
/v1/wallet/balanceCom esta funcionalidade você pode verificar o saldo de uma ou várias subcontas > ⚠️ **Atenção:** Para consultar o saldo de várias subcontas envie o header acoountId com o número das subcontas separado por vírgula, por exemplo: 9489623,9489624,9489625
Produtos
Criar Produto
/v1/productsCria um novo produto ou serviço com nome, descrição, preço e configurações de recorrência. Os produtos criados ficam disponíveis no painel administrativo e podem ser utilizados tanto no checkout transparente (via API) quanto no checkout pro (link de pagamento). Tipos de recorrência em prices[].recurrenceType: - ONE_TIME → Avulsa - WEEKLY → Semanal - MONTHLY → Mensal - QUARTERLY → Trimestral - SEMIANNUAL → Semestral - YEARLY → Anual Case de uso: _Como SaaS, quero cadastrar meus planos como produtos com preços recorrentes, para que meus clientes possam assinar diretamente pelo checkout pro ou pela minha própria interface._
Listar Produtos
/v1/productsLista todos os produtos cadastrados com suporte a filtros por status e paginação.
Buscar Produto
/v1/products/:idRetorna todos os detalhes de um produto específico, incluindo preço e configurações.
Atualizar Produto
/v1/products/:idAtualiza as informações de um produto, como nome, descrição ou preço. Mesmos campos de POST (todos opcionais). Para atualizar preço existente, inclua `priceId` no item de `prices[]`.
Remover Produto
/v1/products/:idRemove um produto que não esteja vinculado a assinaturas ativas.
Arquivar Produto
/v1/products/:id/archiveGuarda o produto sem excluí-lo, mantendo o histórico de cobranças vinculadas.
Links de pagamento
Criar link de pagamento
/v1/checkoutsCria uma página de pagamento (payment link) configurável, com produtos, formas de pagamento aceitas, cupons e aparência personalizada. O link é reutilizável e não fica vinculado a um cliente específico. É obrigatório informar `priceId` (preço já cadastrado) ou `product` (produto com preços inline). Formas de pagamento suportadas: pix, creditcard, boleto e pix_automatico. **Pix Automático** está disponível apenas para **contas PJ** (conta ValidaPay cadastrada com CNPJ) e só é aceito em preços recorrentes (`recurrenceType` WEEKLY, MONTHLY, QUARTERLY, SEMIANNUAL ou YEARLY). O cliente autoriza a recorrência uma única vez no aplicativo do banco e as cobranças seguintes são debitadas automaticamente, sem novo QR Code a cada ciclo. Até o banco do pagador confirmar a autorização, a assinatura fica com status `PENDING`. O valor mínimo por cobrança é de **R$ 4,99**. Erros: `400 PIX_AUTOMATICO_PJ_ONLY` (conta PF) e `400 PIX_AUTOMATICO_MIN_AMOUNT` (valor abaixo do mínimo). Ao informar `termsOfServiceUrl` e/ou `privacyPolicyUrl`, o checkout exibe um aceite obrigatório com os links: o cliente só consegue finalizar a compra depois de marcar que leu e concorda. O texto do aceite se adapta a um ou aos dois links. Sem esses campos, nenhum aceite é exibido. Case de uso: _Como SaaS, quero criar um link de pagamento reutilizável para uma oferta — definindo cores, parcelamento e order bumps — e compartilhá-lo com vários clientes._
Listar links de pagamento
/v1/checkoutsLista todas as páginas de pagamento (checkouts) criadas, com seus status e configurações. Suporta paginação e filtros por status e busca textual.
Buscar link de pagamento
/v1/checkouts/:idRetorna os detalhes completos de uma página de pagamento, incluindo produtos e formas de pagamento aceitas. O identificador aceita diferentes prefixos: `cha_` (cobrança), `cs_` (sessão), `price_` (preço) e `pl_` (payment link). A autenticação é opcional — o checkout pode ser consultado publicamente.
Atualizar link de pagamento
/v1/checkouts/:idAtualiza as configurações de uma página de pagamento, como preço vinculado, parcelamento ou aparência. Todos os campos são opcionais — envie apenas o que deseja alterar.
Criar sessão de pagamento
/v1/checkout-sessionsCria um acesso temporário e seguro a uma página de pagamento, com cliente e configurações pré-preenchidos. É de uso único: expira após o pagamento. Informe o `priceId` de um preço já cadastrado. Opcionalmente, envie os dados do cliente, restrinja as formas de pagamento e personalize a aparência. A resposta inclui o `id` da sessão e a `url` de pagamento hospedada pela ValidaPay. Formas de pagamento aceitas em `allowedPaymentMethods`: pix, creditcard, boleto e pix_automatico. O **Pix Automático** está disponível apenas para **contas PJ** (conta ValidaPay cadastrada com CNPJ) e exige um preço recorrente (`recurrenceType` WEEKLY, MONTHLY, QUARTERLY, SEMIANNUAL ou YEARLY): o cliente autoriza a recorrência uma única vez no aplicativo do banco e os ciclos seguintes são debitados automaticamente. Enquanto a autorização não é confirmada pelo banco do pagador, a assinatura fica com status `PENDING`. O valor mínimo por cobrança é de **R$ 4,99**. Erros: `400 PIX_AUTOMATICO_PJ_ONLY` (conta PF) e `400 PIX_AUTOMATICO_MIN_AMOUNT` (valor abaixo do mínimo). Ao informar `termsOfServiceUrl` e/ou `privacyPolicyUrl`, o checkout exibe um aceite obrigatório com os links: o cliente só consegue finalizar a compra depois de marcar que leu e concorda. O texto do aceite se adapta a um ou aos dois links. Sem esses campos, nenhum aceite é exibido. Case de uso: _Como SaaS, quero gerar um link de pagamento nominal para cada cliente no momento da contratação, com uso único para evitar cobranças duplicadas._
Buscar sessão de pagamento
/v1/checkout-sessions/:idRetorna os dados de uma sessão de checkout ativa, como produtos disponíveis e formas de pagamento.
Checkout Transparente
Gerar cobrança PIX
/v1/chargesGera uma cobrança **PIX** pelo checkout transparente. O cliente informa os dados diretamente na sua própria interface e você os envia para a API. Envie os dados do comprador e os itens da compra. A resposta traz o código `emv` (copia e cola) e o QR Code para pagamento. Produto ou valor: envie `items` com os produtos OU `amount` para uma cobrança avulsa. Notificações por e-mail: use `notifications` para escolher quais e-mails saem nesta cobrança. Eventos aceitos aqui: `oneoff.pix.generated` (envia o QR Code ao comprador assim que a cobrança é criada), `oneoff.payment.success` (confirmação ao comprador quando o Pix compensa) e `new.sale` (avisa você, vendedor, da venda paga). Os eventos destinados ao comprador exigem `customer.email`. Sem o campo, uma cobrança avulsa (enviada com `amount`) não dispara e-mail nenhum; com `items` de um produto, vale a configuração de notificações do produto, e `notifications` no payload tem precedência sobre ela. > ⚠️ **Atenção:** envie o campo `externalId` como chave de idempotência (idempotencyKey). Se duas cobranças forem enviadas com o mesmo `externalId`, a segunda é recusada com `409 DUPLICATE_CHARGE`, retornando o `chargeId` da cobrança original. Erros comuns: `409 DUPLICATE_CHARGE` (externalId já utilizado), `404 PRICE_NOT_FOUND` (preço inexistente) e `400 INVALID_DATA` (campo inválido). Use `externalTxid` para identificar a **loja**, o **caixa** ou o **vendedor** responsável pela cobrança. **Correlação com o pedido:** use `externalId` — ele é persistido e devolvido. O campo `metadata` é aceito nesta rota mas **não é gravado na cobrança** nem volta no webhook; ele só é persistido em `POST /v1/charges/pix`. ### Emitindo nota fiscal na cobrança Envie `nfConfigId` com o identificador de uma configuração fiscal criada em `POST /v1/invoices/notas/config`. Com ele presente: - `customer.address` passa a ser **obrigatório** — a nota precisa do endereço do tomador. Sem ele: `400 INVALID_DATA`. - O momento da emissão vem da configuração, não da cobrança: `invoiceTiming` aceita `IMMEDIATE` (padrão), `AFTER_CONFIRMATION` e `DAYS_AFTER_CONFIRMATION`; neste último, `daysAfterConfirmation` define em quantos dias (padrão 1). - O `cityCode` (IBGE) do endereço é resolvido a partir do CEP e é necessário para a NFS-e. O mesmo campo existe em produtos (`POST /v1/products`) e nas configurações de assinatura, para emitir nota a cada ciclo sem repetir o `nfConfigId` em cada cobrança.
Gerar cobrança Pix Automático
/v1/chargesInicia uma assinatura com **Pix Automático** pelo checkout transparente. O cliente informa os dados na sua própria interface e você os envia para a API. A resposta traz `pix.emv` (copia e cola) e `pix.recurrencyId`. Enquanto o banco do pagador não confirma a autorização, a assinatura fica com status `PENDING`. Requisitos: - conta ValidaPay cadastrada como **PJ** (CNPJ) - `items` com preço **recorrente** (`recurrenceType` WEEKLY, MONTHLY, QUARTERLY, SEMIANNUAL ou YEARLY); não use `amount` avulso - valor mínimo de **R$ 4,99** por cobrança Notificações por e-mail: use `notifications` para escolher quais e-mails saem nesta cobrança. Eventos aceitos aqui: `oneoff.payment.success` (confirmação ao comprador quando o Pix compensa) e `new.sale` (avisa você, vendedor, da venda paga). Os eventos destinados ao comprador exigem `customer.email`. Sem o campo, uma cobrança avulsa (enviada com `amount`) não dispara e-mail nenhum; com `items` de um produto, vale a configuração de notificações do produto, e `notifications` no payload tem precedência sobre ela. > ⚠️ **Atenção:** envie o campo `externalId` como chave de idempotência (idempotencyKey). Se duas cobranças forem enviadas com o mesmo `externalId`, a segunda é recusada com `409 DUPLICATE_CHARGE`, retornando o `chargeId` da cobrança original. Erros comuns: `400 PIX_AUTOMATICO_PJ_ONLY` (conta PF), `400 PIX_AUTOMATICO_MIN_AMOUNT` (valor abaixo do mínimo), `409 DUPLICATE_CHARGE` (externalId já utilizado) e `404 PRICE_NOT_FOUND` (preço inexistente). Use `externalTxid` para identificar a **loja**, o **caixa** ou o **vendedor** responsável pela cobrança. **Correlação com o pedido:** use `externalId` — ele é persistido e devolvido. O campo `metadata` é aceito nesta rota mas **não é gravado na cobrança** nem volta no webhook; ele só é persistido em `POST /v1/charges/pix`.
Gerar cobrança Boleto
/v1/chargesGera uma cobrança via **boleto** pelo checkout transparente. O cliente informa os dados na sua própria interface e você os envia para a API. Para boleto, o **endereço completo do comprador é obrigatório**. Você pode personalizar vencimento, multa, juros e desconto por meio de `boletoInstructions`. Produto ou valor: envie `items` com os produtos OU `amount` para uma cobrança avulsa. Notificações por e-mail: use `notifications` para escolher quais e-mails saem nesta cobrança. Eventos aceitos aqui: `oneoff.boleto.generated` (envia o boleto ao comprador assim que a cobrança é criada), `oneoff.payment.success` (confirmação ao comprador quando o boleto compensa) e `new.sale` (avisa você, vendedor, da venda paga). Os eventos destinados ao comprador exigem `customer.email`. Sem o campo, uma cobrança avulsa (enviada com `amount`) não dispara e-mail nenhum; com `items` de um produto, vale a configuração de notificações do produto, e `notifications` no payload tem precedência sobre ela. > ⚠️ **Atenção:** envie o campo `externalId` como chave de idempotência (idempotencyKey). Se duas cobranças forem enviadas com o mesmo `externalId`, a segunda é recusada com `409 DUPLICATE_CHARGE`, retornando o `chargeId` da cobrança original. Erros comuns: `409 DUPLICATE_CHARGE` (externalId já utilizado), `404 PRICE_NOT_FOUND` (preço inexistente) e `400 INVALID_DATA` (campo inválido — inclui endereço ausente). Use `externalTxid` para identificar a **loja**, o **caixa** ou o **vendedor** responsável pela cobrança. **Correlação com o pedido:** use `externalId` — ele é persistido e devolvido. O campo `metadata` é aceito nesta rota mas **não é gravado na cobrança** nem volta no webhook; ele só é persistido em `POST /v1/charges/pix`.
Gerar cobrança Cartão
/v1/chargesGera uma cobrança via **cartão de crédito** pelo checkout transparente. O cliente informa os dados na sua própria interface e você os envia para a API. Envie os dados do cartão no objeto `card` (dados brutos) ou use `paymentMethodId`/`tokenId` de um cartão tokenizado. É possível parcelar (`installments`) e repassar as taxas ao comprador. Produto ou valor: envie `items` com os produtos OU `amount` para uma cobrança avulsa. Notificações por e-mail: use `notifications` para escolher quais e-mails saem nesta cobrança. Eventos aceitos aqui: `oneoff.payment.success` (confirmação ao comprador quando o cartão é aprovado), `oneoff.payment.failed` (aviso ao comprador quando o cartão é recusado) e `new.sale` (avisa você, vendedor, da venda paga). Os eventos destinados ao comprador exigem `customer.email`. Sem o campo, uma cobrança avulsa (enviada com `amount`) não dispara e-mail nenhum; com `items` de um produto, vale a configuração de notificações do produto, e `notifications` no payload tem precedência sobre ela. > ⚠️ **Atenção:** envie o campo `externalId` como chave de idempotência (idempotencyKey). Se duas cobranças forem enviadas com o mesmo `externalId`, a segunda é recusada com `409 DUPLICATE_CHARGE`, retornando o `chargeId` da cobrança original. Erros comuns: `409 DUPLICATE_CHARGE` (externalId já utilizado), `402` (pagamento recusado pelo banco), `400 MISSING_CARD_DATA` (faltam dados do cartão) e `404 PRICE_NOT_FOUND` (preço inexistente). **Cartões de teste (sandbox):** em conta de sandbox nenhuma cobrança chega ao adquirente — o número do cartão é que define o resultado: - `4111111111111111` — pagamento aprovado - `4000000000000002` — recusado pela operadora (`card_declined`) - `4000000000000004` — saldo insuficiente (`insufficient_funds`) - `4000000000000006` — cartão expirado (`expired_card`) - `4000000000000008` — CVV inválido (`invalid_cvv`) - `4000000000000010` — suspeita de fraude (`fraud_suspected`) Qualquer outro número de 16 dígitos é aprovado. CVV, validade e nome do titular podem ser quaisquer valores válidos. Em produção o número não muda nada: quem decide é o emissor do cartão. Use `externalTxid` para identificar a **loja**, o **caixa** ou o **vendedor** responsável pela cobrança. **Correlação com o pedido:** use `externalId` — ele é persistido e devolvido. O campo `metadata` é aceito nesta rota mas **não é gravado na cobrança** nem volta no webhook; ele só é persistido em `POST /v1/charges/pix`.
Saques
Saque subconta
/v1/wallet/withdrawCom esta funcionalidade você pode criar um saque em uma subconta associada à sua _master account._ > ⚠️ **Atenção:** Só é possível fazer saques para contas de mesma titularidade
Saque master account
/v1/wallet/withdrawCom esta funcionalidade você pode criar um saque da sua _conta ValidaPay._ > ⚠️ **Atenção:** Só é possível fazer saques para contas de mesma titularidade
Extratos
Devoluções
Clientes
Criar Cliente
/v1/customersCadastra um cliente na sua conta a partir do CPF/CNPJ, com endereço opcional. O documento é a chave do cliente dentro da conta e não pode ser alterado depois. Por padrão, se já existir um cliente com o mesmo documento, a API devolve 200 com o cadastro existente em vez de duplicar. Envie upsert: true para que a tentativa de recadastrar retorne erro 400 (CUSTOMER_ALREADY_EXISTS). Quando o endereço é informado, o código IBGE do município (cityCode) é resolvido automaticamente a partir do CEP — necessário para emissão de NFS-e. Case de uso: _Como plataforma, quero cadastrar meus clientes junto com o endereço de cobrança, para depois gerar assinaturas e cobranças sem redigitar os dados a cada venda._
Listar Clientes
/v1/customersLista os clientes cadastrados na sua conta, com busca por texto e paginação por cursor. O parâmetro search faz busca parcial simultânea em nome, e-mail e documento — é o filtro indicado para uma tela de seleção de cliente, onde o usuário pode digitar qualquer um dos três. Já document faz correspondência exata e deve ser usado quando o CPF/CNPJ completo já é conhecido. A paginação é por cursor: quando houver mais páginas, pagination.lastKey vem preenchido; repita a chamada enviando esse valor em lastKey, mantendo os mesmos filtros. Quando lastKey vier null, não há mais páginas. Case de uso: _Como integrador, quero buscar um cliente já cadastrado por nome, e-mail ou CPF/CNPJ, para preencher automaticamente os dados na hora de criar uma nova cobrança._
Buscar Cliente por Documento
/v1/customersBusca direta de um único cliente pelo CPF/CNPJ exato, retornando junto o endereço padrão dele. Diferente de Listar Clientes, esta chamada não devolve lista nem paginação: retorna o objeto do cliente e o endereço em uma única resposta, pronto para preencher um formulário. Quando o documento não está cadastrado, a resposta é 200 com customer e address em null — não é erro. Case de uso: _Como checkout próprio, quero consultar o CPF digitado pelo comprador e, se ele já for cliente, preencher nome, e-mail, telefone e endereço automaticamente._
Detalhar Cliente
/v1/customers/:customerIdRetorna os dados completos de um cliente, incluindo todos os endereços cadastrados e o histórico de assinaturas. Cada assinatura vem acompanhada dos itens, dos ciclos de cobrança e das faturas e cobranças de cada ciclo. É a visão consolidada usada na tela de detalhe do cliente. Case de uso: _Como atendente, quero ver tudo que um cliente possui — assinaturas, ciclos e faturas — em uma única consulta, para responder a um contato de suporte._
Atualizar Cliente
/v1/customers/:customerIdAtualiza os dados de um cliente. Envie apenas os campos que deseja alterar. O documento não pode ser alterado: enviar um CPF/CNPJ diferente do atual retorna erro 400 (DOCUMENT_UPDATE_NOT_ALLOWED). Quando o endereço é enviado, ele substitui o endereço padrão do cliente. Case de uso: _Como plataforma, quero atualizar o e-mail e o telefone de um cliente que mudou de contato, sem recriar o cadastro._
Remover Cliente
/v1/customers/:customerIdRemove um cliente da sua conta. A exclusão é bloqueada quando o cliente possui assinaturas recorrentes vinculadas, retornando erro 400 (CUSTOMER_HAS_ACTIVE_SUBSCRIPTIONS). Cancele as assinaturas antes de excluir. Case de uso: _Como plataforma, quero remover um cadastro criado por engano, garantindo que clientes com assinaturas ativas não sejam apagados por acidente._
Assinaturas
Listar Assinaturas
/v1/subscriptionsLista todas as assinaturas da conta com suporte a filtros por status, cliente, método de pagamento, produto e período. Utilize o campo `lastKey` retornado na resposta para navegar entre as páginas. Status possíveis: `PENDING`, `AWAITING_PAYMENT`, `ACTIVE`, `TRIALING`, `PAST_DUE`, `PAUSED`, `CANCELED`, `INCOMPLETE`. > Assinaturas com `interval: ONE_TIME` são excluídas automaticamente do resultado. Case de uso: _Como SaaS, quero listar todas as assinaturas ativas dos meus clientes para exibir no meu painel administrativo._
Buscar Assinatura
/v1/subscriptions/:subscriptionIdRetorna os detalhes completos de uma assinatura específica. A resposta inclui: `customer` (dados do cliente), `items` (itens da assinatura), `upgrades` (mudanças de plano pendentes), `billingCycles` (histórico de ciclos) e `coupon` (cupom aplicado, se houver). Case de uso: _Como SaaS, quero consultar o status e os itens de uma assinatura específica para exibir na área do cliente._
Atualizar Assinatura (Item)
/v1/subscriptions/:subscriptionIdRealiza **upgrade ou downgrade** de um item da assinatura. Envie `old.itemId` do item atual e `new.priceId` (e opcionalmente `new.quantity`) do novo plano. > Rota **canônica** para upgrade/downgrade: **Atualizar Item** (PUT). Este PATCH delega para a mesma lógica. - **Upgrade:** gera cobrança de pro rata imediatamente (cartão) ou de forma assíncrona via webhook (PIX/boleto). O item antigo só é substituído após confirmação do pagamento. - **Downgrade:** a mudança é agendada para o próximo ciclo de cobrança, sem cobrança imediata. Pré-condições: assinatura `ACTIVE`, `PAST_DUE` ou `AWAITING_PAYMENT`; item com status `ACTIVE`. Case de uso: _Como SaaS, quero permitir que meu cliente faça upgrade do plano Básico para o Pro no meio do ciclo, cobrando apenas a diferença proporcional._
Cancelar Item
/v1/subscriptions/:subscriptionIdRemove um **item** da assinatura sem cancelar a assinatura inteira. Envie apenas `old.itemId` — **não informe** o campo `new`. A ausência de `new` indica cancelamento de item. Case de uso: _Como SaaS, quero remover um add-on da assinatura do cliente mantendo o plano principal ativo._
Cancelar Assinatura
/v1/subscriptions/:subscriptionIdCancela uma assinatura ativa, interrompendo todas as cobranças futuras. **Rota recomendada** para cancelamento (preferir em relação ao PATCH com `action: "cancel"`). A assinatura é marcada como `CANCELED` imediatamente. Ciclos futuros pendentes (`PENDING`, `AWAITING_PAYMENT`) são cancelados. O campo `reason` é opcional e pode ser usado para registrar o motivo do cancelamento. Case de uso: _Como SaaS, quero cancelar a assinatura de um cliente que solicitou encerramento do serviço._
Adicionar Item
/v1/subscriptions/:subscriptionId/itemsAdiciona um novo produto ou serviço a uma assinatura já existente. Informe o `priceId` de um preço previamente cadastrado. Para assinaturas com cartão de crédito, a cobrança é processada imediatamente. Para PIX ou boleto, a resposta inclui `payment.transactionId` — a confirmação chega via **webhook**. Pré-condições: assinatura `ACTIVE` ou `PAST_DUE`. Antes do 1º pagamento confirmado (`currentCycleNumber === 1`), add item retorna `400`. > `billOnNextCycle` adia a cobrança para o próximo ciclo (apenas boleto/PIX; incompatível com cartão ou `ONE_TIME`). Case de uso: _Como SaaS, quero adicionar um módulo extra (add-on) à assinatura de um cliente que já possui um plano base._
Atualizar Item
/v1/subscriptions/:subscriptionId/items/:itemId**Rota canônica** para upgrade ou downgrade de plano. Altera o `priceId` ou `quantity` de um item específico. O `subscriptionId` e `itemId` vão na URL. Informe pelo menos `priceId` ou `quantity`. - **Upgrade** (`newTotal > currentTotal`): cobra pro-rata imediatamente (cartão) ou gera boleto/PIX assíncrono. - **Downgrade** (`newTotal <= currentTotal`): efetivado no próximo ciclo, sem cobrança imediata. Pré-condições: assinatura `ACTIVE`, `PAST_DUE` ou `AWAITING_PAYMENT`; item `ACTIVE`. > Falha de pagamento retorna **400** com `PAYMENT_DECLINED` ou `PAYMENT_FAILED` (não 402).
Calcular Pro Rata
/v1/subscriptions/:subscriptionId/prorataCalcula o valor de pro rata para uma troca de plano **sem efetuar cobrança**. Útil para exibir ao cliente o valor exato da mudança antes de confirmar o upgrade. O cálculo considera os dias restantes do ciclo atual. Envie `old` com o preço/quantidade atuais e `new` com o preço/quantidade desejados. Case de uso: _Como SaaS, quero mostrar na interface "Você pagará R$ 45,48 hoje pela diferença proporcional" antes do cliente confirmar o upgrade._
Notas Fiscais
Listar Notas Fiscais
/v1/invoices/notasLista as notas fiscais da conta, da mais recente para a mais antiga. Inclui todas as origens: notas geradas por cobranças e assinaturas e também as avulsas, emitidas por POST nesta mesma rota. ### O identificador da nota O campo `invoiceId` é o identificador usado nas demais rotas — consultar, cancelar, reemitir, reenviar e emitir. Na nota avulsa ele é o `ref` que você informou na emissão; nas notas geradas por cobrança, é o identificador da própria cobrança. Não o confunda com o `ref` da resposta, que traz o identificador interno da nota e serve apenas para suporte. ### Status - `PROCESSING` — enviada, a prefeitura ainda não respondeu - `ISSUED` ou `AUTHORIZED` — autorizada. Os dois valores são equivalentes: o primeiro vem da emissão síncrona, o segundo da confirmação assíncrona da prefeitura - `FAILED` ou `ERROR` — recusada. `nf.errors` traz as mensagens da prefeitura - `CANCELED` — cancelada - `REPLACED` — substituída por uma reemissão No filtro `status` os pares são intercambiáveis: `AUTHORIZED` traz também as `ISSUED`, e `ERROR` traz também as `FAILED`. ### Paginação Por cursor: envie em `lastKey` o valor devolvido em `pagination.lastKey`. Enquanto `pagination.hasMore` for `true`, ainda há páginas. `emissor` identifica de qual empresa a nota saiu, útil quando a conta tem mais de uma configuração fiscal. `feeAmount` e `feeStatus` descrevem a taxa de emissão cobrada pela ValidaPay, não um tributo da nota. Case de uso: _Como plataforma, quero conciliar as notas do mês e conferir quais foram autorizadas antes de fechar o faturamento._
Resumo de Notas Fiscais
/v1/invoices/notas/summaryTotais de notas da conta por status, em quantidade e em valor. Sem `startDate` e `endDate`, o resumo cobre todas as notas da conta. Os pares de status são somados juntos: `authorized` inclui as notas `ISSUED` e `AUTHORIZED`, e `error` inclui as `FAILED` e `ERROR`. Case de uso: _Como plataforma, quero mostrar no painel quantas notas foram autorizadas e quantas falharam no mês, sem paginar a listagem inteira._
Consultar Nota Fiscal
/v1/invoices/notas/:notaidRetorna uma nota pelo `invoiceId` devolvido na listagem — que na nota avulsa é o `ref` informado na emissão, e na nota de cobrança é o identificador da cobrança. Traz os links do PDF e do XML e o código de verificação quando a nota já está autorizada. Quando a prefeitura recusou, `nf.errors` traz as mensagens do que precisa ser corrigido. Nota inexistente, excluída ou de outra conta responde 404 com `NOTA_NOT_FOUND`. Case de uso: _Como plataforma, quero buscar o PDF de uma nota para anexar ao e-mail que envio ao meu cliente._
Emitir Nota Fiscal
/v1/invoices/notasEmite uma nota fiscal de serviço avulsa, sem vínculo com cobrança ou assinatura. A emissão é imediata: o `invoiceTiming` da configuração fiscal vale apenas para as notas geradas a partir de cobranças, não para a avulsa. Informe em `configId` qual configuração fiscal usar — uma conta pode ter configurações de mais de uma empresa, e a nota sai no CNPJ da configuração escolhida. Liste as disponíveis em `GET /v1/invoices/notas/config`. O `ref` que você enviar passa a ser o identificador da nota nas demais rotas: consultar, cancelar, reemitir e reenviar. Omitido, a API gera um identificador próprio e o devolve na resposta. O campo `type` indica o modelo do documento fiscal. O único valor aceito hoje é `NFSE` (nota fiscal de serviço), que também é o assumido quando o campo é omitido — qualquer outro valor retorna 400 com o código `NOTA_TYPE_NOT_SUPPORTED`. Outros tipos de nota estarão disponíveis em breve. Envie `type` explicitamente desde já: quando cada modelo for liberado, nenhuma alteração no payload será necessária. O tomador não precisa estar cadastrado. Se o endereço não trouxer `cityCode`, o código IBGE do município é resolvido a partir do CEP — assim como logradouro e bairro, quando faltarem. A resposta volta com status `PROCESSING`: a prefeitura responde de forma assíncrona. Não há evento de webhook para nota fiscal — acompanhe o desfecho em `GET /v1/invoices/notas/{notaId}`, que passa a `AUTHORIZED` ou a `ERROR` com as mensagens da prefeitura. Case de uso: _Como prestador, quero emitir uma nota para um serviço cobrado fora da plataforma, informando apenas o tomador, o valor e a descrição._
Emitir Nota de uma Cobrança
/v1/invoices/notas/:notaid/emitirEmite a nota de uma cobrança que já existe — a que nunca emitiu e também a que falhou. O identificador na URL é o da cobrança: `invoiceId` de uma fatura de assinatura ou `chargeId` de uma cobrança avulsa. Diferente da emissão avulsa, a nota nasce ligada à cobrança: herda cliente, valor e, quando existe, assinatura e ciclo. ### De onde vem a configuração fiscal Na ordem: o `configId` do corpo, depois o da nota anterior, o `nfConfigId` da cobrança e o da assinatura. Não achando nenhum, a resposta é `NF_CONFIG_REQUIRED` e nada é emitido. ### Quando a emissão é recusada - `INVOICE_NOT_FOUND` (404) — cobrança inexistente ou de outra conta - `INVOICE_STATUS_NOT_EMITTABLE` — só emite cobrança pendente, aguardando pagamento ou paga - `NOTA_ALREADY_ISSUED` — já existe nota autorizada, vinculada ou agendada para essa cobrança - `NOTA_PROCESSING` — há uma emissão em andamento aguardando o retorno da prefeitura - `NF_INCOMPLETE_DATA` — faltam dados do tomador; `details` lista exatamente o que falta - `NF_CONFIG_NOT_FOUND` — a configuração informada não existe ou está desabilitada Para conferir os dados antes sem emitir nada, use `POST /v1/invoices/notas/{notaId}/verificar-emissao`. Case de uso: _Como prestador, quero emitir a nota de uma cobrança que ficou sem nota, sem precisar refazer a cobrança._
Verificar Dados para Emissão
/v1/invoices/notas/:notaid/verificar-emissaoConfere se uma cobrança tem tudo o que a nota fiscal exige, sem emitir nada. O identificador na URL é o da cobrança, como em `POST /v1/invoices/notas/{notaId}/emitir`. `ready` diz se a emissão passaria agora; `pendencias` lista em português o que falta — CPF ou CNPJ, nome, valor, endereço, CEP, município (código IBGE), logradouro ou bairro do cliente. `configId` traz a configuração fiscal que seria usada, ou `null` quando nenhuma foi encontrada. Diferente da emissão, aqui a ausência de configuração não é erro. A conferência é uma rota própria em vez de um parâmetro na rota de emissão: um flag ignorado por engano emitiria a nota de verdade. Case de uso: _Como plataforma, quero avisar o usuário sobre o cadastro incompleto do cliente antes de tentar emitir a nota e receber a recusa._
Cancelar Nota Fiscal
/v1/invoices/notas/:notaidCancela na prefeitura uma nota fiscal já autorizada. O identificador é o `invoiceId` da listagem. O motivo vai na query string, e não no corpo: parte dos clientes HTTP descarta body em requisições DELETE. Só é possível cancelar notas da própria conta e que estejam autorizadas. O status é reconferido antes do cancelamento: nota em processamento ou já cancelada é recusada com `NF_NOT_AUTHORIZED`. O prazo de cancelamento é definido pela prefeitura do município emissor. Passada essa janela, o cancelamento é recusado com `NF_CANCEL_FAILED` e a correção passa a exigir substituição da nota. Case de uso: _Como prestador, quero cancelar uma nota emitida com valor errado, dentro do prazo permitido pelo município._
Reemitir Nota Fiscal
/v1/invoices/notas/:notaid/reemitirGera uma nova nota para uma emissão que falhou na prefeitura. O identificador é o `invoiceId` da listagem. Só vale para notas que não foram autorizadas: uma nota já autorizada é recusada com `NOTA_ALREADY_ISSUED` — nesse caso o caminho é cancelar e emitir de novo. A nota anterior fica com status `REPLACED` e a nova assume o lugar dela. A configuração fiscal usada é a mesma da nota anterior. Corrija a causa da recusa antes de reemitir: a mensagem da prefeitura está em `nf.errors`, na consulta da nota. Case de uso: _Como prestador, quero reprocessar uma nota recusada por erro de cadastro, depois de corrigir a configuração fiscal._
Reenviar Nota por E-mail
/v1/invoices/notas/:notaid/reenviarReenvia por e-mail uma nota já autorizada. O identificador é o `invoiceId` da listagem. Aceita até 10 destinatários por chamada — acima disso a resposta é `TOO_MANY_EMAILS`. Notas que ainda não foram autorizadas são recusadas com `NOTA_NOT_ISSUED`. A nota segue anexada em PDF e XML. Case de uso: _Como prestador, quero reenviar a nota para um segundo e-mail do cliente, sem precisar baixar e anexar o PDF manualmente._
Listar Configurações Fiscais
/v1/invoices/notas/configLista as configurações fiscais da conta. Use o `id` de cada uma como `configId` ao emitir uma nota avulsa, e como `nfConfigId` em cobranças, produtos e assinaturas. A resposta traz também `defaults`: os valores que a API preencheria sozinha a partir do cadastro da conta — CNPJ, endereço, contato e código IBGE do município — úteis para montar a tela de cadastro já preenchida. Segredos nunca são devolvidos. De `prefeitura` vêm o `login`, `has_senha` e a numeração do RPS; do certificado, se existe e a validade. Case de uso: _Como plataforma, quero listar as empresas emissoras da conta para escolher por qual emitir cada nota._
Consultar Configuração Fiscal
/v1/invoices/notas/config/:configidRetorna uma configuração fiscal pelo `id`. Segredos nunca são devolvidos: a senha do certificado e a senha da prefeitura ficam de fora. `certificate.expiry_date` traz o vencimento do certificado, e `prefeitura.has_senha` diz se há credencial gravada. Configuração inexistente ou de outra conta responde `{}`, e não 404. Case de uso: _Como plataforma, quero conferir a validade do certificado de uma empresa antes que ela pare de emitir._
Criar Configuração Fiscal
/v1/invoices/notas/configCadastra a empresa emissora: CNPJ, regime tributário, certificado digital e os tributos que entram na nota. O `id` devolvido aqui é o `configId` da emissão avulsa e o `nfConfigId` de cobranças, produtos e assinaturas. Uma conta pode ter mais de uma configuração — o CNPJ do prestador define de qual empresa a nota sai. O que não for enviado é preenchido a partir do cadastro da conta: CNPJ, endereço, contato e código IBGE do município. Enviar explicitamente evita depender desses dados. A criação valida e registra a empresa emissora, incluindo o certificado. Se essa etapa falhar, nada é gravado e o certificado enviado é descartado — não sobra configuração pela metade. Não envie `id` no corpo: com ele a chamada vira atualização da configuração existente. ### Municipal ou nacional: quem decide é o município O código IBGE em `prestador.codigo_municipio` determina por qual padrão a nota sai, e isso muda quais campos tributários são lidos: - **NFS-en nacional** — padrão nacional da NFS-e, adotado pela maior parte dos municípios. Usa `codigo_tributacao_nacional_iss`, `tributacao_iss`, `tipo_retencao_iss`, `serie_dps` e os campos de PIS/COFINS ou do Simples, conforme o regime. - **NFS-e municipal** — municípios com sistema próprio. Usa `item_lista_servico`, `aliquota_iss`, `iss_retido`, `natureza_operacao` e, quando o município exige, `codigo_cnae` e `codigo_tributario_municipio`. Você não precisa escolher: a rota é resolvida na emissão, a partir do município do prestador. `tipo_nf` força um dos dois padrões e só faz sentido quando o município aceita ambos. Na dúvida sobre em qual padrão o seu município está, preencha os dois conjuntos — o que não se aplica é ignorado. ### Credencial da prefeitura e numeração do RPS O certificado digital A1 basta na maior parte dos municípios. Os que têm sistema próprio podem exigir também uma credencial do portal, enviada em `prefeitura` — nem todos pedem `login`, e há municípios em que só a senha é necessária. Confira o portal do seu município antes de preencher. Em parte deles o que vai em `senha` é uma chave digital gerada no perfil do usuário, e não a senha de acesso ao portal — usar a senha errada só aparece como falha de autenticação na primeira emissão. ### Numeração Cada padrão tem a sua, e as duas continuam a sequência que a prefeitura já registrou para a empresa — em branco, a numeração começa do início. - **NFS-e municipal** — `prefeitura.serie_rps` e `prefeitura.proximo_numero_rps`. - **NFS-en nacional** — `serie_dps`, no primeiro nível do corpo. A série declarada no cadastro é a mesma que vai em cada emissão e precisa bater com a registrada na prefeitura; a sequência dos números é mantida pela ValidaPay. ### Quando a nota é emitida `invoiceTiming` define o momento da emissão das notas geradas por cobrança: - `IMMEDIATE` — junto com a cobrança. É o padrão. - `AFTER_CONFIRMATION` — somente após a confirmação do pagamento. - `DAYS_AFTER_CONFIRMATION` — `daysAfterConfirmation` dias depois da confirmação (padrão 1). A emissão avulsa por `POST /v1/invoices/notas` sai sempre na hora, qualquer que seja o valor configurado. > ⚠️ **Atenção:** configurações criadas pelo painel trazem também `quando_emitir`, com os mesmos três valores. Ele é apenas o espelho gravado pela tela — quem define o agendamento é `invoiceTiming`. ### Campos exigidos pelo regime O regime vem de `prestador.codigo_opcao_simples_nacional`: - **1, não optante** — exige `situacao_tributaria_pis_cofins`, `aliquota_pis` e `aliquota_cofins`. - **2 (MEI) e 3 (ME/EPP)** — exigem `percentual_total_tributos_simples_nacional`. Faltando um deles, a configuração não é gravada e a resposta traz a mensagem da validação com o código `INTERNAL_ERROR`. Case de uso: _Como plataforma, quero cadastrar a empresa emissora e o certificado digital por API, para habilitar a emissão de notas sem passar pelo painel._
Atualizar Configuração Fiscal
/v1/invoices/notas/config/:configidAtualiza uma configuração fiscal. Envie apenas os campos que mudam — os demais são preservados. > ⚠️ **Atenção:** o merge é por campo do primeiro nível, não por campo aninhado. Enviar `prestador` com dois campos substitui o objeto `prestador` inteiro, apagando o que não veio. O mesmo vale para `endereco` e `certificate`: monte o objeto completo antes de enviar. `prefeitura` é a exceção: os campos enviados são mesclados com os já gravados, então dá para alterar só a série do RPS sem reenviar a senha. Enviar `null` em um campo o remove da configuração. `certificate` com `pfx_base64` e `password` substitui o certificado e revalida a empresa emissora; o certificado anterior é apagado, a menos que outra configuração da conta use o mesmo arquivo. Qualquer alteração revalida a empresa emissora. Se essa etapa falhar, nada é gravado. Case de uso: _Como plataforma, quero trocar o certificado digital antes do vencimento, sem recriar a configuração._
Excluir Configuração Fiscal
/v1/invoices/notas/config/:configidRemove uma configuração fiscal da conta. A exclusão vale para a plataforma. As notas já emitidas por ela não são afetadas. Case de uso: _Como plataforma, quero remover a configuração de uma empresa que deixou de operar._