# Obter Dados da Conta Source: https://docs.pague.dev/api-reference/account/get openapi.json GET /account Retorna os dados da conta, informações da empresa e saldo disponível. **Permissão requerida:** `ACCOUNT:READ` ou `FULL_ACCESS` # Gerar Access Token Source: https://docs.pague.dev/api-reference/auth/token openapi.json POST /auth Troca o `client_id` e o `client_secret` da sua credencial por um access token de curta duração. Envie o token retornado no header `Authorization: Bearer ` das demais requisições. O token expira em **300 segundos (5 minutos)** — gere um novo quando expirar; não há refresh token. # Listar Bloqueios de Saldo Source: https://docs.pague.dev/api-reference/balance-blocks/list openapi.json GET /balance-blocks Retorna os bloqueios de saldo (MED, judiciais ou administrativos) da conta. Permite filtrar opcionalmente pelo status do bloqueio. **Permissão requerida:** `BALANCE_BLOCK:READ` ou `FULL_ACCESS` # Criar Cobrança PIX Source: https://docs.pague.dev/api-reference/pix/create openapi.json POST /pix Cria uma cobrança PIX instantânea. **Permissão requerida:** `PIX:WRITE` ou `FULL_ACCESS` **Split entre subcontas.** O campo opcional `split` reparte parte do valor com outras carteiras suas — subcontas ou a conta principal, pela palavra reservada `principal`. No máximo 10 itens, valores fixos em reais. Quem cria a cobrança é o **originador**: recebe o bruto, paga a taxa cheia e só então reparte, então o teto do rateio é o **líquido** (valor da cobrança menos a taxa), não o bruto. O rateio acontece na liquidação, não na criação. Estorno e MED debitam **só o originador** — quem recebeu rateio nunca é debitado. Veja [Split de Pagamento](/#split-de-pagamento) para as regras completas, os exemplos e a tabela de erros. **Escolha da instituição.** Se a sua conta tem essa opção habilitada, o campo opcional `pspCredentialId` fixa a instituição que emite esta cobrança, ignorando o roteamento configurado. Copie o ID em **Configurações → Roteamento** no painel. Fixar **não é preferir**: se a instituição estiver fora do ar ou sem capacidade, a cobrança falha em vez de sair por outra. A resposta ecoa `pspCredentialId` como recibo. Veja [Escolha da Instituição](/#escolha-da-instituição) para as regras completas e a tabela de erros. # Criar Projeto Source: https://docs.pague.dev/api-reference/projects/create openapi.json POST /projects Cria um novo projeto. **Permissão requerida:** `PROJECT:WRITE` ou `FULL_ACCESS` # Listar Projetos Source: https://docs.pague.dev/api-reference/projects/list openapi.json GET /projects Retorna uma lista paginada de projetos. **Permissão requerida:** `PROJECT:READ` ou `FULL_ACCESS` # Criar Subconta Source: https://docs.pague.dev/api-reference/sub-accounts/create openapi.json POST /sub-accounts Cria uma subconta com saldo próprio, totalmente independente do saldo da conta principal. **Permissão requerida:** `SUBACCOUNT:WRITE` ou `FULL_ACCESS` **O `reference` é imutável.** Ele é o identificador que você envia no header `X-Sub-Account` para operar na subconta e o valor que chega no campo `subAccount` dos webhooks — escolha com cuidado, porque não é possível alterá-lo depois da criação. Formato: `^[a-z0-9][a-z0-9_-]{1,31}$` — de 2 a 32 caracteres, apenas letras minúsculas, números, `-` e `_`, começando por letra minúscula ou número. O `reference` precisa ser único dentro da conta: repetir um já existente retorna `409 SUB_ACCOUNT_REFERENCE_TAKEN`. A subconta nasce com saldo próprio, zerado e totalmente independente do saldo da conta principal. Veja [Subcontas](/#subcontas) para o comportamento do header `X-Sub-Account` e a tabela completa de erros. # Listar Subcontas Source: https://docs.pague.dev/api-reference/sub-accounts/list openapi.json GET /sub-accounts Retorna as subcontas da conta. **Permissão requerida:** `SUBACCOUNT:READ` ou `FULL_ACCESS` Retorna as subcontas da conta principal, cada uma com o `reference` que você usa no header `X-Sub-Account` para operar nela. Veja [Subcontas](/#subcontas) para o comportamento do header e a tabela completa de erros. # Buscar Transação Source: https://docs.pague.dev/api-reference/transactions/get openapi.json GET /transactions/{id} Retorna os detalhes de uma transação específica pelo seu ID. **Permissão requerida:** `TRANSACTION:READ` ou `FULL_ACCESS` # Solicitar Reembolso Source: https://docs.pague.dev/api-reference/transactions/refund openapi.json POST /transactions/{id}/refund Solicita um reembolso total da transação de pagamento informada. O reembolso é assíncrono — a confirmação chega via webhook `refund_completed` quando o PSP processar. **Permissão requerida:** `REFUND:WRITE` ou `FULL_ACCESS` # Webhooks Source: https://docs.pague.dev/api-reference/webhooks Receba notificações em tempo real sobre eventos de pagamento ## Visão Geral Webhooks permitem que você receba notificações HTTP automáticas quando eventos importantes acontecem na sua conta, como pagamentos confirmados, reembolsos processados ou saques concluídos. ## Eventos Disponíveis | Evento | Descrição | | ------------------------ | ---------------------------------------------------------------------------------------------- | | `payment_completed` | Pagamento foi confirmado com sucesso | | `payment_expired` | Pagamento expirou sem confirmação | | `payment_failed` | Pagamento recebido mas recusado — depósito bloqueado por política da conta (ex.: pagador CNPJ) | | `refund_completed` | Reembolso foi processado | | `withdrawal_completed` | Saque foi processado com sucesso | | `withdrawal_failed` | Saque foi rejeitado ou falhou | | `withdrawal_reversed` | Saque foi estornado pelo PSP | | `balance_block_created` | Bloqueio de saldo criado (MED/judicial/administrativo) | | `balance_block_approved` | Bloqueio aprovado — valor devolvido ao pagador | | `balance_block_rejected` | Bloqueio rejeitado — valor retorna ao lojista | ## Estrutura do Payload Todos os webhooks seguem a mesma estrutura base: ```json theme={null} { "event": "payment_completed", "eventId": "a0b78f10-c7f4-4f5d-98dd-3e36eafeb812", "timestamp": "2026-01-11T19:03:28.280Z", "subAccount": null, "data": { // Dados específicos do evento } } ``` | Campo | Tipo | Descrição | | ------------ | -------------- | ------------------------------------------------------------------------------------------ | | `event` | string | Tipo do evento | | `eventId` | string | ID único do evento (geralmente o ID da transação) | | `timestamp` | string | Data/hora do evento em formato ISO 8601 | | `subAccount` | string ou null | `reference` da subconta que originou o evento; `null` quando o evento é da conta principal | | `data` | object | Dados específicos do evento | ## Subcontas Quando o evento pertence a uma [subconta](/#subcontas), o campo `subAccount` traz o `reference` dela: ```json theme={null} { "event": "payment_completed", "eventId": "a0b78f10-c7f4-4f5d-98dd-3e36eafeb812", "timestamp": "2026-01-11T19:03:28.280Z", "subAccount": "loja-centro", "data": { "transactionId": "a0b78f10-c7f4-4f5d-98dd-3e36eafeb812", "amount": 100.21, "status": "completed" } } ``` **Se a subconta não tiver um endpoint de webhook próprio cadastrado, os eventos dela são entregues nos endpoints da conta principal.** É por isso que o `subAccount` é essencial: é ele que diz de qual carteira é o evento. Sempre use esse campo para creditar o evento na carteira certa — nunca assuma que todo evento recebido no endpoint da conta principal pertence à conta principal. ## Headers Enviados Cada requisição de webhook inclui os seguintes headers: | Header | Descrição | | -------------------- | ---------------------------------------------------- | | `Content-Type` | `application/json` | | `User-Agent` | `Pague-Webhook/1.0` | | `X-Pague-Event` | Tipo do evento (ex.: `payment_completed`) | | `X-Pague-Webhook-ID` | ID único desta entrega (UUID) | | `X-Pague-Signature` | Assinatura do payload: `sha256=` | | `X-Pague-Timestamp` | Timestamp da entrega em milliseconds (Unix epoch) | ## Validando a Assinatura Cada webhook é assinado com HMAC-SHA256 usando o **secret do seu endpoint** (exibido uma única vez na criação). Siga estes passos para validar: 1. Calcule o **HMAC-SHA256** do body cru da requisição usando o seu secret como chave 2. Prefixe o resultado em hex com `sha256=` 3. Compare com o header `X-Pague-Signature` usando comparação em tempo constante ```typescript Node.js (crypto) theme={null} import { createHmac, timingSafeEqual } from 'node:crypto'; app.post('/webhook', (req, res) => { const signature = req.headers['x-pague-signature'] as string; // "sha256=" const rawBody = req.body; // raw string body // 1. HMAC-SHA256 do payload com o SEU secret (não hasheie o secret) // 2. Prefixar com "sha256=" const expected = `sha256=${createHmac('sha256', 'seu_webhook_secret') .update(rawBody) .digest('hex')}`; // 3. Comparar em tempo constante const isValid = typeof signature === 'string' && signature.length === expected.length && timingSafeEqual(Buffer.from(expected), Buffer.from(signature)); if (!isValid) { return res.status(401).send('Assinatura inválida'); } // Processar o evento... res.status(200).send('OK'); }); ``` Sempre use comparação em tempo constante (`timingSafeEqual`) para evitar ataques de timing. Nunca compare assinaturas com `===`. ## Exemplos de Payload ### payment\_completed Enviado quando um pagamento PIX é confirmado. ```json theme={null} { "event": "payment_completed", "eventId": "a0b78f10-c7f4-4f5d-98dd-3e36eafeb812", "timestamp": "2026-01-11T19:03:28.280Z", "data": { "transactionId": "a0b78f10-c7f4-4f5d-98dd-3e36eafeb812", "environment": "sandbox", "amount": 100.21, "feeAmount": 0.5, "netAmount": 99.71, "split": [ { "subAccount": "loja-sul", "amount": 20.00 } ], "currency": "BRL", "paymentMethod": "pix", "status": "completed", "completedAt": "2026-01-11T19:03:28.277Z", "externalReference": "pedido-12345", "e2eId": "E18189547202603160145ZYFfVx3jP8D", "counterpartName": "Maria Silva", "counterpartDocument": "12345678900", "metadata": { "orderId": "ORDER-12345", "customerId": "CUST-67890" } } } ``` **O `split` do webhook é o que foi efetivamente distribuído**, não o que você pediu na criação da cobrança. Os dois divergem quando a taxa da conta muda entre a cobrança e o pagamento: o líquido encolhe e as pernas são reduzidas na ordem em que foram enviadas, em vez de a liquidação falhar. Para conciliar com o extrato da carteira, use sempre o valor que vem no webhook — nunca o que você mandou no request. O campo só aparece quando houve rateio; cobrança sem split não ganha a chave. | Campo | Tipo | Descrição | | --------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `transactionId` | string | ID único da transação | | `environment` | string | Ambiente (`production` ou `sandbox`) | | `amount` | number | Valor total do pagamento | | `feeAmount` | number | Taxa cobrada | | `netAmount` | number | Valor líquido (amount - feeAmount) | | `split` | array | Rateio efetivado entre as carteiras, em reais; `subAccount` traz o `reference` de destino, ou `principal` para a conta principal (opcional — presente apenas quando houve [split](/#split-de-pagamento)) | | `currency` | string | Moeda (BRL) | | `paymentMethod` | string | Método de pagamento (pix) | | `status` | string | Status do pagamento (completed) | | `completedAt` | string | Data/hora da conclusão em ISO 8601 | | `externalReference` | string | Sua referência externa (opcional) | | `e2eId` | string | ID fim-a-fim da rede PIX (opcional, presente quando disponível) | | `counterpartName` | string | Nome do pagador conforme retornado pelo PSP (opcional) | | `counterpartDocument` | string | CPF/CNPJ do pagador conforme retornado pelo PSP (opcional, sem máscara) | | `metadata` | object | Metadados customizados enviados na criação do pagamento (opcional) | ### payment\_expired Enviado quando um pagamento PIX expira sem confirmação. ```json theme={null} { "event": "payment_expired", "eventId": "payment_expired_d5e6f7a8-1234-5678-9abc-def012345678", "timestamp": "2026-01-11T19:30:00.000Z", "data": { "transactionId": "d5e6f7a8-1234-5678-9abc-def012345678", "environment": "sandbox", "amount": 75.50, "feeAmount": 0, "netAmount": 0, "currency": "BRL", "paymentMethod": "pix", "status": "expired", "expiredAt": "2026-01-11T19:30:00.000Z", "externalReference": "pedido-12345", "metadata": { "orderId": "ORDER-12345", "customerId": "CUST-67890" } } } ``` | Campo | Tipo | Descrição | | ------------------- | ------ | ------------------------------------------------------------------ | | `transactionId` | string | ID único da transação | | `environment` | string | Ambiente (`production` ou `sandbox`) | | `amount` | number | Valor do pagamento | | `feeAmount` | number | Taxa cobrada (sempre 0 para pagamentos expirados) | | `netAmount` | number | Valor líquido (sempre 0 para pagamentos expirados) | | `currency` | string | Moeda (BRL) | | `paymentMethod` | string | Método de pagamento (pix) | | `status` | string | Status do pagamento (expired) | | `expiredAt` | string | Data/hora da expiração em ISO 8601 | | `externalReference` | string | Sua referência externa (opcional) | | `metadata` | object | Metadados customizados enviados na criação do pagamento (opcional) | ### payment\_failed Enviado quando um pagamento PIX foi **recebido mas não pôde ser creditado** — hoje, quando a conta bloqueia depósitos de pagadores pessoa jurídica (CNPJ). O valor não entra no seu saldo, não gera taxa e é devolvido ao pagador automaticamente. `blockedDeposit.refund` informa o andamento da devolução. ```json theme={null} { "event": "payment_failed", "eventId": "payment_failed_13e3ffd1-55d9-4863-9cc1-8955475cdf64", "timestamp": "2026-09-09T20:50:17.612Z", "data": { "transactionId": "13e3ffd1-55d9-4863-9cc1-8955475cdf64", "environment": "production", "amount": 5000.00, "feeAmount": 0, "netAmount": 5000.00, "currency": "BRL", "paymentMethod": "pix", "status": "failed", "failureReason": "Bloqueio de depósito: pagador CNPJ não permitido", "failedAt": "2026-09-09T20:50:17.610Z", "createdAt": "2026-09-09T20:49:41.506Z", "e2eId": "E71328769202609092049JcZwvkhgNGJ", "counterpartName": "EMPRESA PAGADORA LTDA", "counterpartDocument": "60937487000165", "blockedDeposit": { "reason": "cnpj_payer_not_allowed", "refund": { "status": "confirmed", "e2eId": null, "settledAt": "2026-09-09T20:50:14.900Z" } }, "externalReference": "pedido-12345", "metadata": { "orderId": "ORDER-12345" } } } ``` A devolução é feita pela instituição de pagamento logo após o bloqueio. O `refund.status` do webhook é o estado no momento do envio; o E2E da devolução (`refund.e2eId`) costuma chegar segundos depois — consulte `GET /transactions/{id}` para o dado final e para responder ao pagador. | Campo | Tipo | Descrição | | --------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------- | | `transactionId` | string | ID único da transação | | `environment` | string | Ambiente (`production` ou `sandbox`) | | `amount` | number | Valor pago pelo pagador | | `feeAmount` | number | Taxa cobrada (sempre 0 — nada foi creditado) | | `netAmount` | number | Igual a `amount` (referência; nada foi creditado) | | `currency` | string | Moeda (BRL) | | `paymentMethod` | string | Método de pagamento (pix) | | `status` | string | Status do pagamento (failed) | | `failureReason` | string | Motivo, em texto | | `failedAt` | string | Data/hora da recusa em ISO 8601 | | `createdAt` | string | Data/hora da criação da cobrança em ISO 8601 | | `e2eId` | string | ID fim-a-fim do PIX recebido (opcional) | | `counterpartName` | string | Nome do pagador conforme retornado pelo PSP (opcional) | | `counterpartDocument` | string | CNPJ do pagador, sem máscara | | `blockedDeposit.reason` | string | Motivo do bloqueio: `cnpj_payer_not_allowed` | | `blockedDeposit.refund.status` | string | Devolução ao pagador: `pending` (aceita, sem confirmação), `confirmed` (liquidada) ou `failed` (em tratamento manual) | | `blockedDeposit.refund.e2eId` | string | ID fim-a-fim da devolução (`D…`), quando já conhecido | | `blockedDeposit.refund.settledAt` | string | Data/hora da liquidação da devolução em ISO 8601, quando confirmada | | `externalReference` | string | Sua referência externa (opcional) | | `customer` | object | Dados do cliente informados na criação da cobrança (opcional) | | `metadata` | object | Metadados customizados enviados na criação do pagamento (opcional) | ### refund\_completed Enviado quando um reembolso é processado. ```json theme={null} { "event": "refund_completed", "eventId": "c92d45e6-8b33-4f12-a789-2e56f8901def", "timestamp": "2026-01-11T19:22:15.456Z", "data": { "refundTransactionId": "c92d45e6-8b33-4f12-a789-2e56f8901def", "originalTransactionId": "a0b78f10-c7f4-4f5d-98dd-3e36eafeb812", "environment": "sandbox", "amount": 50.00, "feeAmount": 0.25, "netAmount": 50.00, "currency": "BRL", "paymentMethod": "pix", "status": "completed", "refundedAt": "2026-01-11T19:22:15.400Z", "externalReference": "pedido-12345", "metadata": { "orderId": "ORDER-12345", "customerId": "CUST-67890" } } } ``` **Convenção do `netAmount` em refund**: representa o que o destinatário do evento (o cliente final) efetivamente recebe — ou seja, o valor cheio do reembolso. A taxa de reembolso é debitada separadamente do saldo do lojista. O custo total do refund para o lojista é `amount + feeAmount`. | Campo | Tipo | Descrição | | ----------------------- | ------ | ------------------------------------------------------------ | | `refundTransactionId` | string | ID único da transação de reembolso | | `originalTransactionId` | string | ID da transação original que foi reembolsada | | `environment` | string | Ambiente (`production` ou `sandbox`) | | `amount` | number | Valor do reembolso | | `feeAmount` | number | Taxa do reembolso cobrada do lojista | | `netAmount` | number | Valor líquido recebido pelo cliente final (igual a `amount`) | | `currency` | string | Moeda (BRL) | | `paymentMethod` | string | Método de pagamento da transação original | | `status` | string | Status do reembolso (completed) | | `refundedAt` | string | Data/hora do reembolso em ISO 8601 | | `externalReference` | string | Sua referência externa do pagamento original (opcional) | | `metadata` | object | Metadados customizados do pagamento original (opcional) | ### withdrawal\_completed Enviado quando um saque é processado com sucesso. ```json theme={null} { "event": "withdrawal_completed", "eventId": "e73775b5-70ee-4bad-be4c-4acff9890e27", "timestamp": "2026-01-11T19:08:21.953Z", "data": { "withdrawalId": "e73775b5-70ee-4bad-be4c-4acff9890e27", "projectId": "3c90c3cc-0d44-4b50-8888-8dd25736052a", "environment": "sandbox", "amount": 500.00, "feeAmount": 2.50, "netAmount": 497.50, "currency": "BRL", "status": "completed", "completedAt": "2026-01-11T19:08:21.939Z", "externalReference": "saque-empresa-001", "e2eId": "E18189547202603160145ZYFfVx3jP8D", "counterpartName": "João da Silva", "counterpartDocument": "12345678900", "metadata": { "batchId": "BATCH-001" } } } ``` | Campo | Tipo | Descrição | | --------------------- | ------ | --------------------------------------------------------------------------------------- | | `withdrawalId` | string | ID único do saque | | `projectId` | string | ID do projeto do saque (null quando não informado na criação e a conta tem 2+ projetos) | | `environment` | string | Ambiente (`production` ou `sandbox`) | | `amount` | number | Valor do saque | | `feeAmount` | number | Taxa do saque | | `netAmount` | number | Valor líquido transferido | | `currency` | string | Moeda (BRL) | | `status` | string | Status do saque (completed) | | `completedAt` | string | Data/hora da conclusão em ISO 8601 | | `externalReference` | string | Sua referência externa enviada na criação do saque (opcional) | | `e2eId` | string | ID fim-a-fim da rede PIX (opcional, presente após confirmação do PSP) | | `counterpartName` | string | Nome do destinatário no banco de destino (opcional) | | `counterpartDocument` | string | CPF/CNPJ do destinatário (opcional, sem máscara) | | `metadata` | object | Metadados customizados do saque (opcional) | ### withdrawal\_failed Enviado quando um saque é rejeitado ou falha. ```json theme={null} { "event": "withdrawal_failed", "eventId": "b84f12c3-9a21-4e67-bc88-1d45f6789abc", "timestamp": "2026-01-11T19:15:42.123Z", "data": { "withdrawalId": "b84f12c3-9a21-4e67-bc88-1d45f6789abc", "projectId": "3c90c3cc-0d44-4b50-8888-8dd25736052a", "environment": "sandbox", "amount": 1000.00, "feeAmount": 5.00, "netAmount": 995.00, "currency": "BRL", "status": "failed", "failedAt": "2026-01-11T19:15:42.100Z", "failureReason": "insufficient_funds", "externalReference": "saque-empresa-001", "e2eId": "E18189547202603160145ZYFfVx3jP8D", "counterpartName": "João da Silva", "counterpartDocument": "12345678900", "metadata": { "batchId": "BATCH-001" } } } ``` | Campo | Tipo | Descrição | | --------------------- | ------ | ------------------------------------------------------------------------------------------------ | | `withdrawalId` | string | ID único do saque | | `projectId` | string | ID do projeto do saque (null quando não informado na criação e a conta tem 2+ projetos) | | `environment` | string | Ambiente (`production` ou `sandbox`) | | `amount` | number | Valor do saque | | `feeAmount` | number | Taxa do saque | | `netAmount` | number | Valor líquido que seria transferido | | `currency` | string | Moeda (BRL) | | `status` | string | Status do saque (failed) | | `failedAt` | string | Data/hora da falha em ISO 8601 | | `failureReason` | string | Motivo da falha (insufficient\_funds, invalid\_account, etc.) | | `externalReference` | string | Sua referência externa enviada na criação do saque (opcional) | | `e2eId` | string | ID fim-a-fim da rede PIX (opcional, presente apenas se o saque chegou a ser processado pelo PSP) | | `counterpartName` | string | Nome do destinatário no banco de destino (opcional) | | `counterpartDocument` | string | CPF/CNPJ do destinatário (opcional, sem máscara) | | `metadata` | object | Metadados customizados do saque (opcional) | ### withdrawal\_reversed Enviado quando um saque é estornado pelo PSP. ```json theme={null} { "event": "withdrawal_reversed", "eventId": "f12a34b5-6c78-9d01-ef23-456789abcdef", "timestamp": "2026-01-11T20:00:00.000Z", "data": { "reversalTransactionId": "f12a34b5-6c78-9d01-ef23-456789abcdef", "originalTransactionId": "e73775b5-70ee-4bad-be4c-4acff9890e27", "environment": "sandbox", "amount": 500.00, "feeAmount": 0, "netAmount": 500.00, "currency": "BRL", "paymentMethod": "pix", "status": "completed", "reversedAt": "2026-01-11T20:00:00.000Z", "metadata": { "batchId": "BATCH-001" } } } ``` | Campo | Tipo | Descrição | | ----------------------- | ------ | --------------------------------------------------- | | `reversalTransactionId` | string | ID único da transação de estorno | | `originalTransactionId` | string | ID do saque original que foi estornado | | `environment` | string | Ambiente (`production` ou `sandbox`) | | `amount` | number | Valor do estorno | | `feeAmount` | number | Taxa do estorno | | `netAmount` | number | Valor líquido do estorno | | `currency` | string | Moeda (BRL) | | `paymentMethod` | string | Método de pagamento (pix) | | `status` | string | Status do estorno (completed) | | `reversedAt` | string | Data/hora do estorno em ISO 8601 | | `externalReference` | string | Sua referência externa do saque original (opcional) | | `metadata` | object | Metadados customizados do saque original (opcional) | ### balance\_block\_created Enviado quando um bloqueio de saldo é criado (MED, judicial ou administrativo). ```json theme={null} { "event": "balance_block_created", "eventId": "d4e5f6a7-8b9c-0d1e-2f3a-456789abcdef", "timestamp": "2026-01-11T19:30:00.000Z", "data": { "blockId": "d4e5f6a7-8b9c-0d1e-2f3a-456789abcdef", "transactionId": "a0b78f10-c7f4-4f5d-98dd-3e36eafeb812", "environment": "production", "amount": 1500.00, "currency": "BRL", "blockType": "med", "referenceNumber": "MED-2026-001234", "reason": "Notificação de infração Pix recebida", "status": "awaiting_response", "createdAt": "2026-01-11T19:30:00.000Z", "externalReference": "pedido-12345", "e2eId": "E18189547202603160145ZYFfVx3jP8D" } } ``` | Campo | Tipo | Descrição | | ------------------- | ------ | --------------------------------------------------------- | | `blockId` | string | ID único do bloqueio | | `transactionId` | string | ID da transação original bloqueada | | `environment` | string | Ambiente (`production` ou `sandbox`) | | `amount` | number | Valor bloqueado em reais | | `currency` | string | Moeda (BRL) | | `blockType` | string | Tipo do bloqueio (`med`, `judicial` ou `administrative`) | | `referenceNumber` | string | Número de referência do bloqueio | | `reason` | string | Motivo do bloqueio | | `status` | string | Status inicial (`awaiting_response`) | | `createdAt` | string | Data/hora da criação em ISO 8601 | | `externalReference` | string | Referência externa da transação original (opcional) | | `e2eId` | string | ID fim-a-fim da rede PIX da transação original (opcional) | ### balance\_block\_approved Enviado quando um bloqueio de saldo é aprovado e o valor é devolvido ao pagador original. ```json theme={null} { "event": "balance_block_approved", "eventId": "d4e5f6a7-8b9c-0d1e-2f3a-456789abcdef", "timestamp": "2026-01-12T14:00:00.000Z", "data": { "blockId": "d4e5f6a7-8b9c-0d1e-2f3a-456789abcdef", "transactionId": "a0b78f10-c7f4-4f5d-98dd-3e36eafeb812", "environment": "production", "amount": 1500.00, "currency": "BRL", "blockType": "med", "referenceNumber": "MED-2026-001234", "reason": "Notificação de infração Pix recebida", "resolutionReason": "Devolução confirmada pelo BACEN", "status": "approved", "createdAt": "2026-01-11T19:30:00.000Z", "resolvedAt": "2026-01-12T14:00:00.000Z", "externalReference": "pedido-12345", "e2eId": "E18189547202603160145ZYFfVx3jP8D" } } ``` | Campo | Tipo | Descrição | | ------------------- | ------ | --------------------------------------------------------- | | `blockId` | string | ID único do bloqueio | | `transactionId` | string | ID da transação original bloqueada | | `environment` | string | Ambiente (`production` ou `sandbox`) | | `amount` | number | Valor bloqueado em reais | | `currency` | string | Moeda (BRL) | | `blockType` | string | Tipo do bloqueio (`med`, `judicial` ou `administrative`) | | `referenceNumber` | string | Número de referência do bloqueio | | `reason` | string | Motivo original do bloqueio | | `resolutionReason` | string | Motivo da resolução (opcional) | | `status` | string | Status do bloqueio (`approved`) | | `createdAt` | string | Data/hora da criação em ISO 8601 | | `resolvedAt` | string | Data/hora da resolução em ISO 8601 | | `externalReference` | string | Referência externa da transação original (opcional) | | `e2eId` | string | ID fim-a-fim da rede PIX da transação original (opcional) | ### balance\_block\_rejected Enviado quando um bloqueio de saldo é rejeitado e o valor retorna ao saldo disponível do lojista. ```json theme={null} { "event": "balance_block_rejected", "eventId": "e5f6a7b8-9c0d-1e2f-3a4b-567890abcdef", "timestamp": "2026-01-12T14:00:00.000Z", "data": { "blockId": "e5f6a7b8-9c0d-1e2f-3a4b-567890abcdef", "transactionId": "b1c89f20-d8e5-5f6a-99ee-4f47eafeb923", "environment": "production", "amount": 250.00, "currency": "BRL", "blockType": "med", "referenceNumber": "MED-2026-005678", "reason": "Notificação de infração Pix recebida", "resolutionReason": "Defesa aceita - transação legítima comprovada", "status": "rejected", "createdAt": "2026-01-11T19:30:00.000Z", "resolvedAt": "2026-01-12T14:00:00.000Z", "externalReference": "pedido-67890", "e2eId": "E4071059520260316020613919677838" } } ``` | Campo | Tipo | Descrição | | ------------------- | ------ | --------------------------------------------------------- | | `blockId` | string | ID único do bloqueio | | `transactionId` | string | ID da transação original bloqueada | | `environment` | string | Ambiente (`production` ou `sandbox`) | | `amount` | number | Valor bloqueado em reais | | `currency` | string | Moeda (BRL) | | `blockType` | string | Tipo do bloqueio (`med`, `judicial` ou `administrative`) | | `referenceNumber` | string | Número de referência do bloqueio | | `reason` | string | Motivo original do bloqueio | | `resolutionReason` | string | Motivo da resolução (opcional) | | `status` | string | Status do bloqueio (`rejected`) | | `createdAt` | string | Data/hora da criação em ISO 8601 | | `resolvedAt` | string | Data/hora da resolução em ISO 8601 | | `externalReference` | string | Referência externa da transação original (opcional) | | `e2eId` | string | ID fim-a-fim da rede PIX da transação original (opcional) | ## Boas Práticas Retorne um status `200 OK` o mais rápido possível. Processe o webhook de forma assíncrona se necessário. Use o `eventId` para evitar processar o mesmo evento duas vezes. Webhooks podem ser reenviados em caso de falha. Configure seu endpoint apenas com HTTPS para garantir a segurança dos dados. ## Retentativas Se o seu endpoint não responder com status `2xx`, tentaremos reenviar o webhook: * **5 tentativas** com backoff exponencial * Intervalo inicial: 2 segundos * Intervalo máximo: \~30 segundos entre tentativas Após 5 tentativas sem sucesso, o webhook é marcado como falho. # Criar Saque PIX Source: https://docs.pague.dev/api-reference/withdrawals/create openapi.json POST /withdrawals Cria um novo saque via PIX informando os dados da chave PIX e do titular da conta destino. **Permissão requerida:** `WITHDRAWAL:WRITE` ou `FULL_ACCESS` **Restrição de IP:** Se a credencial tiver uma lista de IPs permitidos configurada, requisições fora dela são rejeitadas com `403`. Recomendado para credenciais com esta permissão. **Processamento assíncrono.** A criação do saque retorna um status não-terminal (`pending` ou `processing`) — o desfecho definitivo é sempre entregue via webhook (`withdrawal.completed` ou `withdrawal.failed`). Trate o webhook como a fonte da verdade; não trate a resposta da criação como resultado final. Erros de validação (saldo insuficiente, limite excedido, dados inválidos) retornam erro na própria chamada. # Introdução Source: https://docs.pague.dev/index Documentação da API pague.dev ## Bem-vindo A API pague.dev permite integrar o processamento de pagamentos em suas aplicações. Esta documentação cobre todos os endpoints disponíveis para gerenciar clientes, projetos, cobranças, transações e pagamentos PIX. ## URL Base Todas as requisições devem ser feitas para: ``` https://api-gateway.pague.dev/v2 ``` ## Autenticação A autenticação é feita em duas etapas: você troca as credenciais da sua conta por um **access token** de curta duração e envia esse token no header `Authorization` de cada requisição. ### 1. Obtenha suas credenciais Crie uma credencial de API no Dashboard. Ela é composta por um `client_id` e um `client_secret`: * `mp_live_*` — credencial de **produção** * `mp_test_*` — credencial de **sandbox** O `client_secret` é exibido **uma única vez**, no momento da criação. Guarde-o em local seguro. ### 2. Gere um access token Troque suas credenciais por um token no endpoint de [autenticação](/api-reference/auth/token): ```bash theme={null} curl -X POST https://api-gateway.pague.dev/v2/auth \ -H 'Content-Type: application/json' \ -d '{ "client_id": "mp_live_abc123...", "client_secret": "seu_client_secret" }' ``` ```json Resposta theme={null} { "access_token": "eyJhbGciOiJSUzI1NiIs...", "token_type": "Bearer", "expires_in": 300 } ``` Credenciais inválidas ou revogadas retornam `401 {"error": "Unauthorized", "message": "Invalid credentials"}`. ### 3. Use o token nas requisições Envie o token no header `Authorization`: ```bash theme={null} curl https://api-gateway.pague.dev/v2/account \ -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIs...' ``` O token expira em **300 segundos (5 minutos)**. Gere um novo token no `/auth` quando ele expirar — não há refresh token. ## Permissões Cada credencial possui permissões granulares que determinam quais endpoints ela pode acessar. As permissões são atribuídas no momento da criação da credencial. ### Permissões disponíveis | Permissão | Descrição | | ------------------ | ------------------------------------------- | | `FULL_ACCESS` | Acesso completo a todos os endpoints da API | | `PIX:WRITE` | Criar cobranças PIX | | `PROJECT:WRITE` | Criar projetos | | `PROJECT:READ` | Listar e buscar projetos | | `TRANSACTION:READ` | Buscar transações | | `WITHDRAWAL:WRITE` | Criar saques via PIX | | `METRICS:READ` | Obter métricas de receita | | `ACCOUNT:READ` | Visualizar dados da conta e saldo | | `SUBACCOUNT:WRITE` | Criar subcontas | | `SUBACCOUNT:READ` | Listar subcontas | A permissão `FULL_ACCESS` concede acesso a todos os endpoints, equivalente a possuir todas as permissões listadas acima. **Exceção: o acesso a subcontas não é permissão.** `FULL_ACCESS` cobre os endpoints de `/sub-accounts` (criar e listar carteiras), mas **não** libera o header `X-Sub-Account` — esse é um campo separado da credencial. Veja [Subcontas](/#subcontas). ### Restrição por IP Opcionalmente, você pode restringir uma credencial a uma lista de IPs permitidos. Quando a lista está configurada, requisições originadas de IPs fora dela são rejeitadas com erro `403 Forbidden`. Recomendamos configurar a restrição de IP em credenciais com permissões sensíveis, como `FULL_ACCESS` e `WITHDRAWAL:WRITE`. ## Subcontas Uma conta pode ter subcontas: carteiras filhas com **saldo totalmente independente** do saldo da conta principal. Cada subconta é identificada por um `reference` escolhido por você. Subcontas e [split](/#split-de-pagamento) funcionam nos **dois ambientes**: uma credencial `mp_test_*` cria e opera carteiras no sandbox como uma `mp_live_*` faz em produção. Para operar em uma subconta, envie o header `X-Sub-Account` com o `reference` dela: ```bash theme={null} curl https://api-gateway.pague.dev/v2/account \ -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIs...' \ -H 'X-Sub-Account: loja-centro' ``` O header é **opcional** e é aceito em todos os endpoints, exceto `/auth` e os próprios endpoints de `/sub-accounts` — criar e listar subcontas acontece sempre na conta principal. Quando presente, a operação inteira acontece na subconta — criar cobrança, consultar transação, criar saque, consultar saldo. Quando ausente, a operação acontece na conta principal. `X-Sub-Account: principal` também resolve para a conta principal, e é equivalente a omitir o header. O `reference` é definido por você na criação da subconta e é **imutável**. Ele precisa casar com `^[a-z0-9][a-z0-9_-]{1,31}$`: de 2 a 32 caracteres, apenas letras minúsculas, números, `-` e `_`, começando por letra minúscula ou número. `principal` é **palavra reservada**: ela identifica a conta principal no `split` e no header `X-Sub-Account`, então nenhuma subconta pode ser criada com esse `reference`. ### Subcontas no sandbox O header `X-Sub-Account`, o `split`, a palavra `principal` e a transferência interna funcionam no sandbox exatamente como em produção. **O mesmo `reference` pode existir nos dois ambientes.** A conta sandbox e a de produção são contas distintas, então `loja-centro` no sandbox e `loja-centro` em produção convivem sem colidir. É isso que permite o **mesmo payload rodar nos dois**: você testa com `mp_test_*`, troca a chave por uma `mp_live_*` e vai para produção sem mudar uma linha. **As duas árvores são isoladas.** Uma credencial `mp_test_*` só enxerga as carteiras da árvore sandbox; uma `mp_live_*`, só as de produção. Isso vale para o `split`: ratear de uma carteira sandbox para uma carteira de produção é recusado, porque a de produção não existe naquele contexto. O erro é o mesmo `Subconta 'X' não existe nesta conta ou não está ativa`. **A carteira precisa ser criada em cada ambiente.** Criar `loja-centro` em produção não a faz aparecer no sandbox — são dois cadastros, de propósito. **A taxa é a mesma nos dois ambientes**, e isso é deliberado: a carteira sandbox herda a taxa da conta de produção justamente para que o teto do rateio, que é o líquido e não o bruto, se comporte igual. Um split que passa no sandbox passa em produção. Uma carteira sandbox originando R$ 20,00 e rateando R$ 1,00 fecha em **+R$ 18,80** na originadora e **+R$ 1,00** no destino, com taxa de R\$ 0,20 — os mesmos números de produção. ### Transferência interna Uma subconta nasce com **saldo zero**. A transferência interna é como você abastece uma carteira nova — e como devolve saldo para a conta principal depois. Ela move saldo entre contas da **mesma titularidade**: da conta principal para uma carteira, de uma carteira para a conta principal, ou entre carteiras irmãs. Não é PIX e não é saque — é troca de bolso. O dinheiro sai de uma conta e entra na outra, aparece nos **dois** extratos, e o saldo total da conta não muda. **Não existe endpoint de transferência interna na API pública.** A operação é feita no Dashboard, na tela de carteiras. Não adianta procurar uma rota: ela não faz parte deste contrato. O que vale saber antes de transferir: * **Só dentro da titularidade.** Transferir para conta de terceiro não existe aqui — isso é PIX, e o caminho é [Criar Saque PIX](/api-reference/withdrawals/create). * **O teto é o saldo gastável da origem**, não o disponível bruto: é o disponível menos a dívida de estorno em aberto, o mesmo critério que vale para o saque. * **Não tem desfazer.** Uma transferência errada se corrige transferindo no sentido inverso. No extrato, cada transferência gera **duas linhas** de tipo `internal_transfer` — uma saída (valor negativo) na origem e uma entrada (positiva) no destino. É o mesmo tipo das pernas de [split](/#split-de-pagamento): nos dois casos, `GET /transactions/{id}` devolve `type: internal_transfer`. ### Limites da subconta Por padrão, **a carteira compartilha o orçamento de limite da conta principal**. Esse é o comportamento de toda subconta criada pela API ou pelo painel: o consumo de todas as carteiras soma contra o mesmo teto do titular. **Criar carteiras não multiplica o seu limite.** Como o orçamento é um só, uma cobrança em uma carteira pode ser recusada por limite **por causa do movimento de outra carteira** da mesma conta — inclusive de uma carteira que o seu código nem tocou naquela requisição. Isso é o comportamento esperado, não uma falha de isolamento. A plataforma pode, caso a caso, dar orçamento **próprio** a uma carteira, separando o consumo dela do resto da conta. É decisão da plataforma: não é configurável pelo lojista, não tem endpoint e não é autoatendimento — se a sua operação precisa disso, fale com o suporte. No **sandbox não há limite**: o teto compartilhado descrito aqui só se manifesta em produção. Isso não é específico de carteiras — vale para qualquer operação sandbox —, então não conclua dos seus testes que o compartilhamento sumiu. Não confunda com o `SUB_ACCOUNT_QUOTA_EXCEEDED` da tabela abaixo: aquele é o teto de **quantas** carteiras a conta pode ter, e não tem relação com valor transacionado. ### Erros de subconta | HTTP | Código | Quando acontece | | ---- | ------------------------------- | ----------------------------------------------------------------------------------- | | 404 | `SUB_ACCOUNT_NOT_FOUND` | O `reference` informado não existe nesta conta | | 403 | `SUB_ACCOUNT_FORBIDDEN` | A credencial não está autorizada a operar essa subconta | | 403 | `SUB_ACCOUNT_SUSPENDED` | A subconta está suspensa | | 409 | `SUB_ACCOUNT_QUOTA_EXCEEDED` | O limite de subcontas da conta foi atingido | | 409 | `SUB_ACCOUNT_REFERENCE_TAKEN` | O `reference` já está em uso nesta conta | | 400 | `SUB_ACCOUNT_INVALID_REFERENCE` | O `reference` pedido na criação é `principal`, palavra reservada da conta principal | Duas coisas diferentes controlam o acesso a carteiras, e elas falham de formas diferentes: * **A permissão da credencial** vale para os endpoints de `/sub-accounts`: listar exige `SUBACCOUNT:READ`, criar exige `SUBACCOUNT:WRITE`. Sem ela, a resposta é `403 Insufficient permissions. Required: SUBACCOUNT:READ`. * **O escopo da credencial** vale para operar *dentro* de uma carteira: é ele que decide quais carteiras aquela credencial alcança pelo header `X-Sub-Account` e pelo `split`, e é ele que devolve `SUB_ACCOUNT_FORBIDDEN`. Por isso criar uma cobrança com `X-Sub-Account` e `split` exige só `PIX:WRITE`: as permissões `SUBACCOUNT:*` governam o cadastro de carteiras, não o uso delas. **O escopo nasce desligado, e nenhuma permissão o substitui.** Uma credencial recém-criada — inclusive uma com acesso total — recebe `403 SUB_ACCOUNT_FORBIDDEN` no primeiro request com `X-Sub-Account` enquanto o escopo estiver em "sem acesso". Ligue em **Configurações → Integração → Credenciais de API**, no campo **Acesso a subcontas** (vale na hora, inclusive para tokens já emitidos). É proposital: sem isso, toda credencial que já existia passaria a alcançar a árvore inteira no dia em que a primeira carteira fosse criada. Subcontas são criadas em [Criar Subconta](/api-reference/sub-accounts/create) e listadas em [Listar Subcontas](/api-reference/sub-accounts/list). Nos webhooks, o campo `subAccount` indica de qual carteira é o evento — veja [Webhooks](/api-reference/webhooks). ## Split de Pagamento Uma cobrança PIX pode repartir parte do valor recebido com outras carteiras da mesma conta — subcontas ou a própria conta principal. Envie o campo opcional `split` na [criação da cobrança](/api-reference/pix/create): ```json theme={null} { "amount": 100.00, "description": "Pedido 4821", "split": [ { "subAccount": "loja-centro", "amount": 30.00 }, { "subAccount": "loja-sul", "amount": 20.00 } ] } ``` | Campo | Tipo | Descrição | | -------------------- | ------ | ------------------------------------------------------------------------------------ | | `split` | array | Opcional. No máximo **10** itens | | `split[].subAccount` | string | `reference` da subconta que recebe o rateio, ou `principal` para a conta principal | | `split[].amount` | number | Valor em reais destinado a essa carteira — mínimo `0.01`, no máximo 2 casas decimais | Os valores são **fixos, em reais**: não existe rateio por percentual. A resposta da criação ecoa o `split` aceito, no mesmo formato e também em reais — se ele veio na resposta, as subcontas existiam e a soma cabia. A validação acontece **antes** de a cobrança ser gerada: um `split` inválido devolve `400` e nenhuma cobrança é criada. ### Quem cria a cobrança é o originador O originador é a conta — ou a subconta do header `X-Sub-Account` — que criou a cobrança. É ele que recebe o **valor bruto**, paga a **taxa cheia** e só então reparte o que sobrou. A taxa **não é rateada** entre os destinatários. Cada subconta do `split` recebe exatamente o `amount` que você pediu, sem desconto nenhum. ### O teto do rateio é o líquido, não o bruto O máximo que pode ser repartido é o valor da cobrança **menos a taxa**. Numa cobrança de **R$ 100,00** com taxa de **R$ 1,49**, o líquido é \*\*R$ 98,51** — e é esse o teto. Um `split` somando R$ 98,51 é aceito (o originador fica com zero). Um `split` somando \*\*R$ 99,00** é recusado, mesmo sendo menor que os R$ 100,00 da cobrança: ```json Resposta 400 theme={null} { "statusCode": 400, "error": "DomainError", "message": "A soma do split (R$ 99.00) excede o líquido da cobrança (R$ 98.51 — bruto R$ 100.00 menos taxa de R$ 1.49)", "timestamp": "2026-01-11T19:03:28.280Z" } ``` A taxa considerada é a da conta que origina a cobrança, para o método PIX. **Estorno e MED atingem só o originador.** Quem recebeu rateio **nunca** é debitado: não existe estorno em cadeia nem recolhimento do valor já repassado. Um reembolso, um chargeback ou um bloqueio MED sobre a cobrança debita exclusivamente a conta que a originou. A consequência é sua para administrar: se você repartir 100% do líquido e a transação for estornada, o originador arca com o prejuízo inteiro — e o débito pode deixar o saldo dele negativo. Guardar uma margem no originador é decisão do integrador, não do sistema. ### O rateio acontece na liquidação Criar a cobrança **não move dinheiro nenhum**. O `split` fica registrado na cobrança e só é executado quando o pagamento é confirmado — é nesse momento que os valores saem do saldo do originador e entram nas carteiras de destino. Cobrança expirada ou nunca paga não gera rateio. A taxa da conta pode mudar entre a criação da cobrança e o pagamento. Se, na liquidação, a soma do `split` não couber mais no líquido, as pernas são atendidas **na ordem em que você as enviou**, até o líquido acabar: a última pode ser reduzida, ou não acontecer. A liquidação nunca falha por causa disso — ordene o array por prioridade e concilie pelo `split` do webhook [`payment_completed`](/api-reference/webhooks), que traz o que foi efetivamente distribuído. ### Só carteiras da mesma conta `subAccount` aceita o `reference` de uma subconta **ativa da mesma conta**, ou a palavra reservada `principal`. Split para fora da titularidade não existe nesta API. ### Rateio de volta para a conta principal `principal` é a única palavra que não é `reference` de ninguém: ela endereça a **conta principal** como destino do rateio. Serve para o caminho inverso do resto desta seção — a cobrança nasce em uma subconta e parte do líquido volta para a conta principal: ```bash theme={null} curl -X POST https://api-gateway.pague.dev/v2/pix \ -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIs...' \ -H 'X-Sub-Account: loja-centro' \ -H 'Content-Type: application/json' \ -d '{ "amount": 20.00, "description": "Pedido 4821", "split": [ { "subAccount": "principal", "amount": 5.00 } ] }' ``` Com uma taxa de R$ 0,20, o resultado é: `loja-centro` fica com **R$ 14,80\*\* (R$ 20,00 menos R$ 0,20 de taxa menos R$ 5,00 de rateio) e a conta principal recebe **R$ 5,00\*\*. Quem origina continua sendo `loja-centro` — é ela que paga a taxa cheia, e a conta principal recebe o rateio limpo, como qualquer outro destinatário. O eco na resposta e o `split` do webhook trazem `"subAccount": "principal"`, igual às demais carteiras. Uma cobrança **originada pela conta principal** não pode ratear para `principal` — seria rateio para si mesma, e o que não é repartido já fica nela de qualquer forma. Esse caso devolve `400`. Para mover saldo entre carteiras fora de um pagamento, use a [transferência interna](/#transferência-interna) — operação explícita, que não fica pendurada na liquidação de uma cobrança. ### Split a partir de uma subconta O header `X-Sub-Account` e o campo `split` respondem a perguntas diferentes e funcionam **juntos**: o header diz **quem origina** a cobrança, o `split` diz **para quem vai parte do líquido**. Uma subconta pode originar uma cobrança e repartir com uma irmã. Nesse caso a conta principal não é tocada — não recebe nada e não paga taxa nenhuma: ```bash theme={null} curl -X POST https://api-gateway.pague.dev/v2/pix \ -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIs...' \ -H 'X-Sub-Account: loja-centro' \ -H 'Content-Type: application/json' \ -d '{ "amount": 100.00, "description": "Pedido 4821", "split": [ { "subAccount": "loja-sul", "amount": 20.00 } ] }' ``` `loja-centro` é a originadora: recebe os R$ 100,00, paga a taxa e repassa R$ 20,00 para `loja-sul`. Uma subconta não pode repartir consigo mesma. ### Erros do split Todos retornam `400`: | Mensagem | Quando acontece | | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `Subconta 'X' não existe nesta conta ou não está ativa` | O `reference` não é de uma subconta ativa desta conta. É também o erro de quem endereça uma subconta de outra titularidade ou uma carteira do outro ambiente — para endereçar a conta principal, use `principal` | | `Subconta 'X' aparece duas vezes no split` | O mesmo `reference` foi enviado em dois itens — junte os valores em um item só | | `A soma do split (R$ Y) excede o líquido da cobrança (R$ Z — bruto R$ A menos taxa de R$ B)` | O rateio não cabe no líquido da cobrança | | `A conta que origina a cobrança não pode receber rateio de si mesma` | A subconta do header `X-Sub-Account` também aparece no `split` | | `Esta cobrança já foi criada pela conta principal — o que não for rateado fica nela. Use 'principal' no split apenas quando a cobrança for originada por uma subconta (header X-Sub-Account)` | A cobrança foi criada pela conta principal e o `split` inclui `principal` | | `split must contain no more than 10 elements` | O array tem mais de 10 itens | | `split.0.amount must not be less than 0.01` | Algum item tem `amount` abaixo de `0.01` — o índice indica qual | ### No extrato Na liquidação, cada perna do split gera **duas linhas** de tipo `internal_transfer`, ambas amarradas à cobrança pelo `parentTransactionId`: * uma **saída** no originador — `Split enviado para loja-centro`, ou `Split enviado para a conta principal` quando o destino é `principal` * uma **entrada** na carteira que recebeu — `Split recebido do pagamento {id da cobrança}` As duas são transações de verdade: [Buscar Transação](/api-reference/transactions/get) devolve `type: internal_transfer` para cada uma. O `parentTransactionId` é vínculo de extrato e não faz parte da resposta pública. ## Escolha da Instituição Toda cobrança PIX é emitida por uma das instituições ligadas à sua conta. Por padrão, quem escolhe é o **roteamento** configurado no painel — ordem fixa, divisão por fatias ou automático. Se a sua conta tem a **escolha de instituição** habilitada, você pode decidir isso por cobrança, enviando `pspCredentialId` na [criação da cobrança](/api-reference/pix/create): ```bash theme={null} curl -X POST https://api-gateway.pague.dev/v2/pix \ -H 'Authorization: Bearer eyJhbGciOiJSUzI1NiIs...' \ -H 'Content-Type: application/json' \ -d '{ "amount": 100.00, "description": "Pedido 4821", "pspCredentialId": "6e307aa4-4772-4230-a648-d88cee308f54" }' ``` Sem o campo, nada muda: o roteamento configurado continua valendo, com failover. ### Onde encontrar o ID No painel, em **Configurações → Roteamento**. Cada instituição mostra o ID logo abaixo dos números, com um botão de copiar. É de propósito que ele fique ali e não numa lista à parte: na mesma linha você vê a conversão das últimas 6 horas, o fechamento de 7 e 30 dias e se a instituição está respondendo. Escolher instituição sem olhar esses números é escolher no escuro. O ID é **estável**: não muda quando você reordena as instituições, troca de modo ou desabilita outra. ### Fixar não é preferir Quando você envia `pspCredentialId`, a cobrança sai por aquela instituição **ou não sai**. Não existe fallback: | Situação | Resposta | | -------------------------------------------------------------------- | ------------------------------------------------- | | Instituição fora do ar (timeout, erro de infra, credencial recusada) | `500` — `Payment service temporarily unavailable` | | Instituição sem capacidade de saída no ciclo | `400` — `reason: out_capacity_exhausted` | Em nenhum dos dois a cobrança é criada em outra instituição. Isso é deliberado. Cair para outra faria o QR nascer num lugar que você não pediu, e você só descobriria conferindo a resposta — o que é pior do que falhar, justamente para quem fixa a instituição por conciliação, limite ou contrato. Quem prefere conversão a previsibilidade não deve enviar o campo: é para isso que o roteamento com failover existe. ### Recibo na resposta Fixou a instituição, a resposta ecoa `pspCredentialId` com a que realmente emitiu — use na conciliação. Sem o campo no request, ele também não vem na resposta. ```json Resposta 201 theme={null} { "id": "e3b0c442-98fc-1c14-9afb-f4c8996fb924", "status": "pending", "amount": 100.00, "pixCopyPaste": "00020126580014br.gov.bcb.pix...", "pspCredentialId": "6e307aa4-4772-4230-a648-d88cee308f54", "expiresAt": "2026-08-22T18:00:00.000Z" } ``` ### Erros da escolha Todos `400`, com o código em `reason`: | `reason` | Quando acontece | | ------------------------ | --------------------------------------------------------------------------- | | `self_routing_disabled` | A conta não tem a escolha de instituição habilitada — fale com o suporte | | `credential_not_linked` | O `pspCredentialId` não é uma instituição de PIX desta conta | | `credential_not_enabled` | A instituição existe na conta, mas está desabilitada para receber cobranças | | `credential_inactive` | A instituição está inativa no momento | A validação acontece **antes** de qualquer chamada à instituição: recusa aqui nunca deixa cobrança pendurada. A escolha vale só para **cobranças PIX**. Saques continuam saindo pela instituição definida para saque — ali a escolha é nossa, porque é a mesma que paga taxas e devoluções. ## Recursos Disponíveis Criar cobranças PIX Receber notificações de eventos Organizar pagamentos por projeto Criar saques via PIX Visualizar detalhes de transações Consultar dados da conta e saldo Carteiras filhas com saldo próprio