Portal para desenvolvedores ValidaPay
Seja bem-vindo(a)! Aqui você encontra guias de integração, referência completa da API e tudo que precisa para conectar sua aplicação à ValidaPay.
Por onde começar
Introdução
Comece aqui! Aprenda o básico sobre a API ValidaPay e dê os primeiros passos na integração.
Referência da API
Explore todos os endpoints com exemplos de código, parâmetros e respostas detalhadas.
Collections
Baixe a collection Postman pronta para importar e testar os endpoints no seu ambiente.
Webhooks
Configure notificações em tempo real para pagamentos, assinaturas e eventos de onboarding.
Canais de Suporte
Fale com o time ValidaPay quando precisar de ajuda na integração ou em produção.
Tokenização
Entenda como tokenizar cartões com segurança sem trafegar dados sensíveis na sua API.
Endpoints por módulo
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._