Receba e envie pagamentos com a API PagzPay
Plataforma de pagamentos focada no mercado brasileiro. Cobranças PIX via QR Code, cartão de crédito (Pagar.me), transferências para qualquer chave, saldo em tempo real, split de pagamentos entre contas PagzPay e webhooks assinados — em uma API REST, sem SDK obrigatório.
Autenticação#
Gera um token JWT para autenticar as demais requisições. Concatene API Key:API Secret (gerados no Dashboard em Configurações → API Keys), codifique em Base64 e envie como Basic Auth. Esta rota não exige body — apenas o header Authorization. Body vazio com Content-Type: application/json (axios) ou application/x-www-form-urlencoded (PHP CURLOPT_POST) é aceito.
Como montar o header
| Header | Valor |
|---|---|
Authorization | Basic base64(API Key:API Secret) |
Resposta
| Campo | Tipo | Descrição |
|---|---|---|
success | boolean | Indica se a autenticação foi bem-sucedida. |
token | string | Token JWT usado nas demais requisições. |
tokenType | string | Sempre Bearer. |
expiresIn | integer | Validade do token em milissegundos (60000). |
Authorization: Bearer {token} em todas as chamadas seguintes.
credentials=$(echo -n "SUA_API_KEY:SEU_API_SECRET" | base64)
curl -X POST 'https://api.pagzpay.com/api/auth' \
-H "Authorization: Basic $credentials"
const credentials = Buffer.from('SUA_API_KEY:SEU_API_SECRET').toString('base64')
const response = await fetch('https://api.pagzpay.com/api/auth', {
method: 'POST',
headers: {
'Authorization': `Basic ${credentials}`
}
})
const { token } = await response.json()
import requests
import base64
credentials = base64.b64encode(b'SUA_API_KEY:SEU_API_SECRET').decode()
response = requests.post(
'https://api.pagzpay.com/api/auth',
headers={'Authorization': f'Basic {credentials}'}
)
token = response.json()['token']
$credentials = base64_encode('SUA_API_KEY:SEU_API_SECRET');
$ch = curl_init('https://api.pagzpay.com/api/auth');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Basic ' . $credentials,
'Accept: application/json'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
$token = $response['token'];
{
"success": true,
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"tokenType": "Bearer",
"expiresIn": 60000
}Valores monetários#
Todos os valores enviados e recebidos pela API são centavos, em inteiros — nunca reais fracionados. A única exceção é o endpoint de saldo, que retorna reais como string com duas casas decimais.
| Valor em reais | Enviar na API |
|---|---|
| R$ 1,00 | 100 |
| R$ 10,50 | 1050 |
| R$ 150,00 | 15000 |
10.50 será interpretado de forma incorreta — envie 1050.
{
"amountInCents": 15000
}Criar QR Code#
Cria um QR Code PIX para receber um pagamento imediato. Retorna o código EMV (copia e cola) e a imagem do QR Code em Base64, prontos para exibir ao seu cliente.
postbackUrl e você recebe uma notificação assim que o pagamento for confirmado, sem precisar fazer polling.
Corpo da requisição
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
amountInCents | integer | Sim | Valor da cobrança em centavos (mínimo R$ 1,00). |
customer | object | Sim | Dados do pagador — documentType e document obrigatórios. |
description | string | Não | Até 140 caracteres. Aparece no extrato do pagador. |
postbackUrl | string | Não | URL de confirmação do pagamento. Pode incluir UTMs na query — ver Rastreamento UTMs. |
trackingParameters | object | Não | UTMs e click IDs para Utmify/atribuição. Obrigatório na prática se você usa API + Utmify. Ver Rastreamento UTMs. |
items | array | Não | Itens do pedido: title (nome real do produto), imageUrl (foto do produto), tangible, quantity, amountInCents. |
salesSiteUrl | string | Não | URL do site onde o produto é vendido — ver Dados do produto. |
checkoutUrl | string | Não | URL da página de checkout onde o pagamento foi feito — ver Dados do produto. |
supportContact | object | Não | Contato de suporte do vendedor: email, phone, whatsapp e/ou url — ver Dados do produto. |
splits | array | Não | Distribui o valor líquido para outras empresas PagzPay. Ver Split de pagamentos. |
Objeto customer
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
documentType | string | Sim | cpf ou cnpj. |
document | string | Sim | Apenas dígitos, sem pontuação. |
name | string | Não | Nome completo do pagador. |
email | string | Não | E-mail válido do pagador. |
phone | string | Não | Telefone de contato. |
billingAddress | object | Não | street, number, neighborhood, city, state, zipCode. |
curl -X POST 'https://api.pagzpay.com/api/v1/pix/in/qrcode' \
-H 'Authorization: Bearer SEU_TOKEN_AQUI' \
-H 'Content-Type: application/json' \
-d '{
"amountInCents": 5000,
"description": "Pagamento de serviços",
"postbackUrl": "https://exemplo.com.br/webhook",
"customer": {
"name": "João Silva",
"email": "joao@exemplo.com",
"documentType": "cpf",
"document": "11122233344",
"phone": "(11) 91234-5678"
},
"trackingParameters": {
"src": "facebook",
"sck": "sck-exemplo",
"utm_source": "meta",
"utm_campaign": "campanha-exemplo",
"utm_medium": "cpc",
"utm_content": "criativo-1",
"utm_term": "tenis",
"fbclid": "fbclid-exemplo",
"gclid": "gclid-exemplo",
"ttclid": "ttclid-exemplo",
"xcod": "xcod-exemplo"
}
}'
const response = await fetch('https://api.pagzpay.com/api/v1/pix/in/qrcode', {
method: 'POST',
headers: {
'Authorization': 'Bearer SEU_TOKEN_AQUI',
'Content-Type': 'application/json'
},
body: JSON.stringify({
amountInCents: 5000,
description: 'Pagamento de serviços',
postbackUrl: 'https://exemplo.com.br/webhook',
customer: {
name: 'João Silva',
email: 'joao@exemplo.com',
documentType: 'cpf',
document: '11122233344',
phone: '(11) 91234-5678'
},
trackingParameters: {
src: 'facebook',
sck: 'sck-exemplo',
utm_source: 'meta',
utm_campaign: 'campanha-exemplo',
utm_medium: 'cpc',
utm_content: 'criativo-1',
utm_term: 'tenis',
fbclid: 'fbclid-exemplo',
gclid: 'gclid-exemplo',
ttclid: 'ttclid-exemplo',
xcod: 'xcod-exemplo'
}
})
})
const { data } = await response.json()
console.log(data.pix.emv) // código copia e cola
console.log(data.pix.qrCode) // imagem Base64
import requests
response = requests.post(
'https://api.pagzpay.com/api/v1/pix/in/qrcode',
headers={
'Authorization': 'Bearer SEU_TOKEN_AQUI',
'Content-Type': 'application/json'
},
json={
'amountInCents': 5000,
'description': 'Pagamento de servicos',
'postbackUrl': 'https://exemplo.com.br/webhook',
'customer': {
'name': 'Joao Silva',
'email': 'joao@exemplo.com',
'documentType': 'cpf',
'document': '11122233344',
'phone': '(11) 91234-5678'
},
'trackingParameters': {
'src': 'facebook',
'sck': 'sck-exemplo',
'utm_source': 'meta',
'utm_campaign': 'campanha-exemplo',
'utm_medium': 'cpc',
'utm_content': 'criativo-1',
'utm_term': 'tenis',
'fbclid': 'fbclid-exemplo',
'gclid': 'gclid-exemplo',
'ttclid': 'ttclid-exemplo',
'xcod': 'xcod-exemplo'
}
}
)
data = response.json()['data']
print(data['pix']['emv'])
$payload = json_encode([
'amountInCents' => 5000,
'description' => 'Pagamento de servicos',
'postbackUrl' => 'https://exemplo.com.br/webhook',
'customer' => [
'name' => 'Joao Silva',
'email' => 'joao@exemplo.com',
'documentType' => 'cpf',
'document' => '11122233344',
'phone' => '(11) 91234-5678'
],
'trackingParameters' => [
'src' => 'facebook',
'sck' => 'sck-exemplo',
'utm_source' => 'meta',
'utm_campaign' => 'campanha-exemplo',
'utm_medium' => 'cpc',
'utm_content' => 'criativo-1',
'utm_term' => 'tenis',
'fbclid' => 'fbclid-exemplo',
'gclid' => 'gclid-exemplo',
'ttclid' => 'ttclid-exemplo',
'xcod' => 'xcod-exemplo'
]
]);
$ch = curl_init('https://api.pagzpay.com/api/v1/pix/in/qrcode');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer SEU_TOKEN_AQUI',
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
{
"success": true,
"message": "Transação criada com sucesso",
"data": {
"id": "trx_1a2b3c4d5e6f7g8h9i0j",
"pix": {
"emv": "00020126580014br.gov.bcb.pix0136...",
"qrCode": "iVBORw0KGgo..."
},
"status": "pending",
"fees": 0
}
}Rastreamento (UTMs / Utmify)#
Dois jeitos de receber PIX no PagzPay — checkout hospedado ou API. A Utmify recebe a venda nos dois casos, mas a forma de enviar UTMs é diferente. Escolha o fluxo que você usa e siga a configuração abaixo.
Qual fluxo é o seu?
| Checkout hospedado | API PIX | |
|---|---|---|
| Pagamento | Página PagzPay (link de checkout) | Seu site/app gera QR via API |
| UTMs | Na URL do checkout | Objeto trackingParameters no JSON |
| Automático? | Sim — página captura query/cookies | Não — você monta o body |
| Referência | Configurar checkout ↓ | Configurar API ↓ |
seusite.com/?utm_...) não saltam sozinhas para outro domínio. No checkout: UTMs na URL do link PagzPay. Na API: trackingParameters no POST.
Checkout hospedado
Link criado no PagzPay — ex. https://checkout.pagzpay.com/{slug}/{token} ou domínio custom /checkout/{token}.
- Crie/copie o link em Checkout no dashboard.
- No redirect do funil (Skale, Meta, etc.), aponte para o checkout com query UTM:
…/seu-token?utm_source=meta&utm_campaign=natal&utm_medium=cpc - Cliente abre, paga PIX — a página PagzPay grava UTMs e envia à Utmify ao confirmar.
- Teste: abra o link do checkout já com
?utm_source=teste&utm_campaign=doce confira a venda na Utmify.
Não precisa chamar POST /qrcode nem enviar trackingParameters manualmente neste fluxo.
API PIX
Sua aplicação chama POST /api/v1/pix/in/qrcode (ou /cob).
- Autentique com
POST /api/auth(Bearer nas próximas chamadas). - Inclua
trackingParametersno body — não usetrackingouutms. - Preencha a partir da URL do funil (front) ou sessão/query (back-end).
- Opcional: UTMs na query da
postbackUrl(body tem prioridade). customer:documentType+document(nãocpf).
Campos de trackingParameters
| Campo | Descrição |
|---|---|
utm_* | source, campaign, medium, content, term |
src, sck, xcod | Utmify |
fbclid, gclid, ttclid | Click IDs |
Validar
Metadata da venda com trackingParameters · Dashboard → Integrações → Utmify → Reenviar (ID da transação).
const q = new URLSearchParams(window.location.search)
const trackingParameters = {
src: q.get('src'),
sck: q.get('sck'),
utm_source: q.get('utm_source'),
utm_campaign: q.get('utm_campaign'),
utm_medium: q.get('utm_medium'),
utm_content: q.get('utm_content'),
utm_term: q.get('utm_term'),
fbclid: q.get('fbclid'),
gclid: q.get('gclid'),
ttclid: q.get('ttclid'),
xcod: q.get('xcod'),
}
await fetch('https://api.pagzpay.com/api/v1/pix/in/qrcode', {
method: 'POST',
headers: {
Authorization: 'Bearer TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
amountInCents: 3590,
customer: {
name: 'Cliente',
documentType: 'cpf',
document: '11122233344',
email: 'cliente@exemplo.com',
},
trackingParameters,
}),
})
Dados do produto (compliance)#
A adquirente pede informações sobre o que está sendo vendido para análise de compliance. Na API esses campos são opcionais — a cobrança funciona sem eles —, mas recomendamos enviá-los sempre que possível. O PagzPay repassa tudo à adquirente junto com o pedido.
Campos
Valem para POST /api/v1/pix/in/qrcode e POST /api/v1/card.
| Campo | Tipo | Descrição |
|---|---|---|
items[].title | string | Nome real do produto. |
items[].imageUrl | string (URL) | URL pública da foto real do produto. |
salesSiteUrl | string (URL) | URL do site onde o produto é vendido. |
checkoutUrl | string (URL) | URL da página de checkout onde o pagamento foi feito. |
supportContact.email | string | E-mail de suporte do vendedor. |
supportContact.phone | string | Telefone de suporte com DDD. |
supportContact.whatsapp | string | WhatsApp de suporte com DDD. |
supportContact.url | string (URL) | Site ou página de ajuda. |
Em supportContact, envie os canais que preferir. URLs precisam ser completas (com https://) e a foto precisa estar acessível publicamente.
curl -X POST 'https://api.pagzpay.com/api/v1/pix/in/qrcode' \
-H 'Authorization: Bearer SEU_TOKEN_AQUI' \
-H 'Content-Type: application/json' \
-d '{
"amountInCents": 9790,
"description": "Pedido #4321",
"customer": {
"name": "Ana Lima",
"email": "ana@exemplo.com",
"documentType": "cpf",
"document": "12345678909"
},
"items": [
{
"title": "Tênis Corrida Pro",
"imageUrl": "https://minhaloja.com.br/img/tenis-corrida-pro.jpg",
"tangible": true,
"quantity": 1,
"amountInCents": 9790
}
],
"salesSiteUrl": "https://minhaloja.com.br",
"checkoutUrl": "https://minhaloja.com.br/checkout/4321",
"supportContact": {
"email": "suporte@minhaloja.com.br",
"whatsapp": "(11) 99999-0000"
}
}'
Consultar QR Code#
Consulta uma cobrança PIX criada anteriormente e retorna o EMV, a imagem do QR Code e o status atual.
Parâmetro de rota
| Parâmetro | Tipo | Descrição |
|---|---|---|
transactionId | string | ID da transação retornado na criação do QR Code. |
Status possíveis
| Status | Significado |
|---|---|
pending | Cobrança criada, aguardando pagamento. |
paid | Cobrança paga e liquidada. |
canceled | Cobrança cancelada. |
refunded | Cobrança devolvida ao pagador. |
curl -X GET 'https://api.pagzpay.com/api/v1/pix/in/qrcode/trx_1a2b3c4d5e6f7g8h9i0j' \
-H 'Authorization: Bearer SEU_TOKEN_AQUI'
const transactionId = 'trx_1a2b3c4d5e6f7g8h9i0j'
const response = await fetch(
`https://api.pagzpay.com/api/v1/pix/in/qrcode/${transactionId}`,
{ headers: { 'Authorization': 'Bearer SEU_TOKEN_AQUI' } }
)
const { data } = await response.json()
console.log(data.pix.emv)
import requests
transaction_id = 'trx_1a2b3c4d5e6f7g8h9i0j'
response = requests.get(
f'https://api.pagzpay.com/api/v1/pix/in/qrcode/{transaction_id}',
headers={'Authorization': 'Bearer SEU_TOKEN_AQUI'}
)
data = response.json()['data']
print(data['pix']['emv'])
$transactionId = 'trx_1a2b3c4d5e6f7g8h9i0j';
$ch = curl_init("https://api.pagzpay.com/api/v1/pix/in/qrcode/{$transactionId}");
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer SEU_TOKEN_AQUI'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
{
"success": true,
"message": "QR Code PIX encontrado com sucesso",
"data": {
"id": "trx_1a2b3c4d5e6f7g8h9i0j",
"pix": {
"emv": "00020126580014br.gov.bcb.pix0136...",
"qrCode": "iVBORw0KGgo..."
},
"status": "pending",
"fees": 0
}
}Tokenização (Pagar.me)#
Na integração direta (POST /api/v1/card), não envie PAN/CVV para a PagzPay. Gere um token no browser (ou app) chamando a API da Pagar.me com a chave pública da conta.
pk_test_… / pk_…) vinculada à adquirente de cartão da sua empresa. No checkout hospedado, ela vem em paymentCapabilities.card.publicKey na carga pública do link.
Body (JSON)
| Campo | Descrição |
|---|---|
type | Sempre card. |
card.number | Só dígitos. |
card.holder_name | Nome impresso. |
card.exp_month / exp_year | Ex.: 12 e 28 (AA). |
card.cvv | CVV — nunca persista nem envie à PagzPay. |
Resposta: { "id": "token_…" } — use em card.token no POST /api/v1/card.
curl -X POST 'https://api.pagar.me/core/v5/tokens?appId=pk_test_XXXX' \
-H 'Content-Type: application/json' \
-d '{
"type": "card",
"card": {
"number": "4111111111111111",
"holder_name": "JOAO SILVA",
"exp_month": "12",
"exp_year": "28",
"cvv": "123"
}
}'{
"id": "token_xxxxxxxx",
"type": "card",
"created_at": "2026-01-15T12:00:00Z"
}Criar cobrança com cartão#
Cria uma cobrança com cartão de crédito via adquirente Pagar.me. Disponível quando a empresa tem adquirente de cartão configurada no admin (cardAdquirenceId).
customer.billingAddress é obrigatório (rua, número, bairro, cidade, UF, CEP).
card.token (token Pagar.me gerado no browser) em vez de PAN (number, cvv).
Corpo da requisição
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
amountInCents | integer | Sim | Valor em centavos (mínimo R$ 1,00). |
customer | object | Sim | Mesmo formato do PIX + billingAddress obrigatório. |
card | object | Sim | holderName, installments (1–12). Token ou PAN + validade + CVV. |
description | string | Não | Descrição da cobrança. |
postbackUrl | string | Não | URL de callback quando o status mudar. |
trackingParameters | object | Não | UTMs para Utmify — ver Rastreamento UTMs. |
items, salesSiteUrl, checkoutUrl, supportContact | — | Não | Dados do produto para compliance, mesmo formato do PIX — ver Dados do produto. |
Status comuns na resposta
| Status | Significado |
|---|---|
paid | Aprovado na adquirente. |
pending | Em análise ou processamento. |
refused | Recusado pelo emissor/adquirente. |
curl -X POST 'https://api.pagzpay.com/api/v1/card' \
-H 'Authorization: Bearer SEU_TOKEN_AQUI' \
-H 'Content-Type: application/json' \
-d '{
"amountInCents": 5000,
"postbackUrl": "https://exemplo.com.br/webhook",
"customer": {
"name": "João Silva",
"email": "joao@exemplo.com",
"documentType": "cpf",
"document": "11122233344",
"billingAddress": {
"street": "Av. Paulista",
"number": "1000",
"neighborhood": "Bela Vista",
"city": "São Paulo",
"state": "SP",
"zipCode": "01310100"
}
},
"card": {
"token": "tok_xxxxxxxx",
"holderName": "JOAO SILVA",
"installments": 1
},
"trackingParameters": {
"src": "facebook",
"sck": "sck-exemplo",
"utm_source": "meta",
"utm_campaign": "campanha-exemplo",
"utm_medium": "cpc",
"utm_content": "criativo-1",
"utm_term": "tenis",
"fbclid": "fbclid-exemplo",
"gclid": "gclid-exemplo",
"ttclid": "ttclid-exemplo",
"xcod": "xcod-exemplo"
}
}'
const response = await fetch('https://api.pagzpay.com/api/v1/card', {
method: 'POST',
headers: {
Authorization: 'Bearer SEU_TOKEN_AQUI',
'Content-Type': 'application/json',
},
body: JSON.stringify({
amountInCents: 5000,
customer: {
name: 'João Silva',
email: 'joao@exemplo.com',
documentType: 'cpf',
document: '11122233344',
billingAddress: {
street: 'Av. Paulista',
number: '1000',
neighborhood: 'Bela Vista',
city: 'São Paulo',
state: 'SP',
zipCode: '01310100',
},
},
card: { token: 'tok_xxxxxxxx', holderName: 'JOAO SILVA', installments: 1 },
trackingParameters: {
src: 'facebook',
sck: 'sck-exemplo',
utm_source: 'meta',
utm_campaign: 'campanha-exemplo',
utm_medium: 'cpc',
utm_content: 'criativo-1',
utm_term: 'tenis',
fbclid: 'fbclid-exemplo',
gclid: 'gclid-exemplo',
ttclid: 'ttclid-exemplo',
xcod: 'xcod-exemplo',
},
}),
})
{
"success": true,
"message": "Transação criada com sucesso",
"data": {
"id": "trx_1a2b3c4d5e6f7g8h9i0j",
"card": {
"token": "tok_xxxxxxxx",
"brand": "visa",
"last4": "4242"
},
"status": "paid",
"fees": 150
}
}Consultar cobrança#
Após POST /api/v1/card, use o id retornado para consultar status e detalhes (mesmo endpoint serve PIX e cartão).
Status comuns (cartão)
| Status | Significado |
|---|---|
paid | Aprovado e confirmado. |
pending | Em análise ou aguardando confirmação. |
refused | Recusado pela adquirente. |
refund / chargeback | Estorno ou chargeback. |
O endpoint /status retorna só { "success": true, "status": "paid" } — útil para polling leve.
curl -X GET 'https://api.pagzpay.com/api/v1/transactions/trx_abc123' \
-H 'Authorization: Bearer SEU_TOKEN_AQUI'{
"success": true,
"data": {
"id": "trx_abc123",
"status": "paid",
"paymentMethod": "credit_card",
"amount": 5000,
"fees": 150,
"Card": {
"brand": "visa",
"last4": "1111"
}
}
}Checkout hospedado com cartão#
Quando o cliente paga em um link de checkout PagzPay, você pode oferecer cartão junto com PIX — sem integrar a API de cartão no seu backend.
Como habilitar
- No admin PagzPay, configure o roteamento de cartão (global ou por empresa) para Pagar.me.
- No builder do checkout, marque Cartão de crédito em métodos aceitos.
- A página pública retorna
paymentCapabilities.card(incluipublicKeypara tokenização no browser). - O comprador envia o pagamento; o front chama a rota abaixo (sem Bearer do lojista).
Rota de pagamento (pública)
Base URL: https://api.pagzpay.com (mesma API; rota pública do checkout).
Consultar status
Mesmo fluxo de polling usado para PIX no checkout hospedado.
x-idempotency-key — ver Idempotência.
Tipos de chave PIX aceitos
| Tipo | Formato | Exemplo |
|---|---|---|
| CPF | Apenas dígitos | 11122233344 |
| CNPJ | Apenas dígitos | 11222333000181 |
| Email válido | destino@email.com | |
| Telefone | Com +55 | +5511999999999 |
| Chave aleatória | UUID | 123e4567-e89b-... |
Headers
| Header | Obrig. | Descrição |
|---|---|---|
x-idempotency-key | Sim | UUID único por operação — evita transferências duplicadas em caso de retry. |
Corpo da requisição
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
pixKey | string | Sim | Chave PIX de destino. |
amount | integer | Sim | Valor da transferência em centavos. |
currency | string | Não | Moeda — apenas BRL (padrão). |
description | string | Não | Até 140 caracteres. |
postbackUrl | string | Não | URL para receber notificação de status da transferência. |
curl -X POST 'https://api.pagzpay.com/api/v1/pix/out/pixkey' \
-H 'Authorization: Bearer SEU_TOKEN_AQUI' \
-H 'Content-Type: application/json' \
-H 'x-idempotency-key: 550e8400-e29b-41d4-a716-446655440000' \
-d '{
"pixKey": "fornecedor@exemplo.com",
"amount": 10000,
"currency": "BRL",
"description": "Pagamento de fornecedor",
"postbackUrl": "https://exemplo.com.br/webhook/pix-out"
}'
const { randomUUID } = require('crypto')
const response = await fetch('https://api.pagzpay.com/api/v1/pix/out/pixkey', {
method: 'POST',
headers: {
'Authorization': 'Bearer SEU_TOKEN_AQUI',
'Content-Type': 'application/json',
'x-idempotency-key': randomUUID()
},
body: JSON.stringify({
pixKey: 'fornecedor@exemplo.com',
amount: 10000,
currency: 'BRL',
description: 'Pagamento de fornecedor',
postbackUrl: 'https://exemplo.com.br/webhook/pix-out'
})
})
const { data } = await response.json()
console.log(data.status) // 'pending'
import requests
import uuid
response = requests.post(
'https://api.pagzpay.com/api/v1/pix/out/pixkey',
headers={
'Authorization': 'Bearer SEU_TOKEN_AQUI',
'Content-Type': 'application/json',
'x-idempotency-key': str(uuid.uuid4())
},
json={
'pixKey': 'fornecedor@exemplo.com',
'amount': 10000,
'currency': 'BRL',
'description': 'Pagamento de fornecedor',
'postbackUrl': 'https://exemplo.com.br/webhook/pix-out'
}
)
data = response.json()['data']
print(data['status'])
$payload = json_encode([
'pixKey' => 'fornecedor@exemplo.com',
'amount' => 10000,
'currency' => 'BRL',
'description' => 'Pagamento de fornecedor',
'postbackUrl' => 'https://exemplo.com.br/webhook/pix-out'
]);
$ch = curl_init('https://api.pagzpay.com/api/v1/pix/out/pixkey');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer SEU_TOKEN_AQUI',
'Content-Type: application/json',
'x-idempotency-key: ' . bin2hex(random_bytes(16))
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
{
"success": true,
"message": "Transferência criada com sucesso",
"data": {
"id": "transfer_abc123def456",
"status": "pending",
"amount": 10000,
"netAmount": 10000,
"fees": 0,
"pixKey": "fornecedor@exemplo.com"
}
}Consultar transferência#
Consulta uma transferência PIX criada anteriormente e retorna o status atual.
Status possíveis
| Status | Significado |
|---|---|
queued / processing | Recebida, aguardando processamento. |
pending / pending_analysis | Em análise antes do envio bancário. |
banking_processing | Enviada ao banco, aguardando confirmação. |
manual_analysis | Retida para revisão manual. |
completed | Transferência concluída com sucesso. |
canceled / refused | Cancelada ou recusada — não foi debitada. |
banking_refused / banking_error / error | Falha no envio bancário. |
curl -X GET 'https://api.pagzpay.com/api/v1/pix/out/pixkey/transfer_abc123def456' \
-H 'Authorization: Bearer SEU_TOKEN_AQUI'
const transferId = 'transfer_abc123def456'
const response = await fetch(
`https://api.pagzpay.com/api/v1/pix/out/pixkey/${transferId}`,
{ headers: { 'Authorization': 'Bearer SEU_TOKEN_AQUI' } }
)
const { data } = await response.json()
console.log(data.status)
import requests
transfer_id = 'transfer_abc123def456'
response = requests.get(
f'https://api.pagzpay.com/api/v1/pix/out/pixkey/{transfer_id}',
headers={'Authorization': 'Bearer SEU_TOKEN_AQUI'}
)
data = response.json()['data']
print(data['status'])
$transferId = 'transfer_abc123def456';
$ch = curl_init("https://api.pagzpay.com/api/v1/pix/out/pixkey/{$transferId}");
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer SEU_TOKEN_AQUI'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
{
"success": true,
"data": {
"id": "transfer_abc123def456",
"status": "completed",
"amount": 10000,
"netAmount": 10000,
"fees": 0,
"pixKey": "fornecedor@exemplo.com",
"endToEndId": "E1234567820241231000000000000002",
"createdAt": "2026-01-15T13:44:25.838Z",
"updatedAt": "2026-01-15T13:45:10.120Z",
"processedAt": "2026-01-15T13:45:10.120Z"
}
}Consultar saldo#
Retorna os saldos atuais das carteiras da empresa autenticada. Os valores são retornados em reais, como string com 2 casas decimais (ex: "150.00") — a única exceção à regra de centavos da API.
Carteiras retornadas
| Campo | Descrição |
|---|---|
pix.balance | Saldo livre, disponível para uso e transferências. |
pixBlocked.balance | Saldo bloqueado por cautelar ou MED (indisponível). |
reserve.balance | Valor em reserva, aguardando liquidação. |
curl -X GET 'https://api.pagzpay.com/api/v1/balance' \
-H 'Authorization: Bearer SEU_TOKEN_AQUI'
const response = await fetch('https://api.pagzpay.com/api/v1/balance', {
headers: { 'Authorization': 'Bearer SEU_TOKEN_AQUI' }
})
const { data } = await response.json()
console.log('Saldo disponível: R$', data.pix.balance)
console.log('Bloqueado: R$', data.pixBlocked.balance)
console.log('Reserva: R$', data.reserve.balance)
import requests
response = requests.get(
'https://api.pagzpay.com/api/v1/balance',
headers={'Authorization': 'Bearer SEU_TOKEN_AQUI'}
)
data = response.json()['data']
print(f"Saldo disponivel: R$ {data['pix']['balance']}")
print(f"Bloqueado: R$ {data['pixBlocked']['balance']}")
print(f"Reserva: R$ {data['reserve']['balance']}")
$ch = curl_init('https://api.pagzpay.com/api/v1/balance');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer SEU_TOKEN_AQUI'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
$saldo = $response['data']['pix']['balance'];
echo "Saldo disponivel: R$ {$saldo}";
{
"success": true,
"data": {
"pix": { "balance": "1250.00" },
"pixBlocked": { "balance": "0.00" },
"reserve": { "balance": "300.00" }
}
}Como funcionam#
Configure uma URL e escolha quais eventos deseja monitorar. O PagzPay envia um POST com o payload do evento para a URL configurada. Além dos webhooks cadastrados em /api/v1/webhook, quando uma cobrança ou transferência é criada com postbackUrl, o mesmo callback também é enviado para essa URL.
Eventos disponíveis
| Fluxo | Evento | Quando é enviado |
|---|---|---|
| PIX IN | transaction_created | Cobrança PIX criada. |
| PIX IN | transaction_paid | Cobrança PIX paga. |
| PIX IN | transaction_refunded | Cobrança PIX estornada. |
| PIX IN | transaction_updated | Cobrança PIX atualizada com outro status. |
| PIX IN | infraction | Infração/MED criada ou atualizada para uma cobrança. |
| PIX OUT | transfer_created | Transferência PIX criada. |
| PIX OUT | transfer_updated | Transferência PIX atualizada com outro status. |
| PIX OUT | transfer_completed | Transferência PIX concluída. |
| PIX OUT | transfer_canceled | Transferência PIX cancelada ou recusada. |
Headers enviados no callback
| Header | Valor |
|---|---|
Content-Type | application/json |
User-Agent | PagzPay |
PagzPay-Signature | HMAC-SHA256 no formato t={timestamp},v1={hash} — apenas quando o webhook possui signatureSecret. |
id da transação, transferência ou disparo do webhook.
Objeto Webhook
| Campo | Tipo | Descrição |
|---|---|---|
id | integer | ID único do webhook. |
name | string | Nome do webhook, se definido. |
url | string | URL que recebe as notificações. |
events | array | Eventos configurados. |
isActive | boolean | Se o webhook está ativo. |
signatureSecret | string | Secret para validar a assinatura HMAC dos callbacks. |
curl -X GET 'https://api.pagzpay.com/api/v1/webhook' \
-H 'Authorization: Bearer SEU_TOKEN_AQUI'
const response = await fetch('https://api.pagzpay.com/api/v1/webhook', {
headers: { 'Authorization': 'Bearer SEU_TOKEN_AQUI' }
})
const { data } = await response.json()
const { webhooks } = data
import requests
response = requests.get(
'https://api.pagzpay.com/api/v1/webhook',
headers={'Authorization': 'Bearer SEU_TOKEN_AQUI'}
)
webhooks = response.json()['data']['webhooks']
$ch = curl_init('https://api.pagzpay.com/api/v1/webhook');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer SEU_TOKEN_AQUI'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
$webhooks = $response['data']['webhooks'];
{
"success": true,
"data": {
"webhooks": [
{
"id": 123,
"name": "Meu webhook",
"url": "https://exemplo.com.br/webhook",
"events": ["transaction_paid", "transfer_completed"],
"isActive": true,
"signatureSecret": "secret_abc123",
"createdAt": "2024-12-31T12:00:00Z"
}
],
"pagination": {
"offset": 0, "pageSize": 10, "totalCount": 1,
"currentPage": 1, "totalPages": 1,
"hasNext": false, "hasPrevious": false
}
}
}Corpo da requisição
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
url | string | Sim | URL HTTPS que receberá as notificações via POST. |
events | array | Sim | Eventos que devem disparar a notificação (mín. 1). |
Validando a assinatura
O PagzPay envia um signatureSecret na criação. Use-o para validar que as notificações são legítimas via HMAC-SHA256:
const crypto = require('crypto')
function isValidPagzPayWebhook(payload, signature, secret) {
const [timestampPart, signaturePart] = signature.split(',')
const timestamp = timestampPart.replace('t=', '')
const receivedSignature = signaturePart.replace('v1=', '')
const expected = crypto
.createHmac('sha256', secret)
.update(`${timestamp}.${JSON.stringify(payload)}`)
.digest('hex')
return expected === receivedSignature
}curl -X POST 'https://api.pagzpay.com/api/v1/webhook' \
-H 'Authorization: Bearer SEU_TOKEN_AQUI' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://exemplo.com.br/webhook",
"events": ["transaction_paid", "transfer_completed"]
}'
const response = await fetch('https://api.pagzpay.com/api/v1/webhook', {
method: 'POST',
headers: {
'Authorization': 'Bearer SEU_TOKEN_AQUI',
'Content-Type': 'application/json'
},
body: JSON.stringify({
url: 'https://exemplo.com.br/webhook',
events: ['transaction_paid', 'transfer_completed']
})
})
const webhook = await response.json()
import requests
response = requests.post(
'https://api.pagzpay.com/api/v1/webhook',
headers={
'Authorization': 'Bearer SEU_TOKEN_AQUI',
'Content-Type': 'application/json'
},
json={
'url': 'https://exemplo.com.br/webhook',
'events': ['transaction_paid', 'transfer_completed']
}
)
$payload = json_encode([
'url' => 'https://exemplo.com.br/webhook',
'events' => ['transaction_paid', 'transfer_completed']
]);
$ch = curl_init('https://api.pagzpay.com/api/v1/webhook');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer SEU_TOKEN_AQUI',
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($ch), true);
{
"success": true,
"data": {
"id": 123,
"name": "Meu webhook",
"url": "https://exemplo.com.br/webhook",
"events": ["transaction_paid", "transfer_completed"],
"isActive": true,
"signatureSecret": "secret_abc123",
"createdAt": "2024-12-31T12:00:00Z"
}
}Parâmetro de rota
| Parâmetro | Tipo | Descrição |
|---|---|---|
id | string | ID do webhook a ser removido. |
curl -X DELETE 'https://api.pagzpay.com/api/v1/webhook/webhook_abc123xyz' \
-H 'Authorization: Bearer SEU_TOKEN_AQUI'
const webhookId = 'webhook_abc123xyz'
const response = await fetch(
`https://api.pagzpay.com/api/v1/webhook/${webhookId}`,
{ method: 'DELETE', headers: { 'Authorization': 'Bearer SEU_TOKEN_AQUI' } }
)
if (response.status === 200) {
console.log('Webhook removido com sucesso')
}
import requests
webhook_id = 'webhook_abc123xyz'
response = requests.delete(
f'https://api.pagzpay.com/api/v1/webhook/{webhook_id}',
headers={'Authorization': 'Bearer SEU_TOKEN_AQUI'}
)
if response.status_code == 200:
print('Webhook removido com sucesso')
$webhookId = 'webhook_abc123xyz';
$ch = curl_init("https://api.pagzpay.com/api/v1/webhook/{$webhookId}");
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer SEU_TOKEN_AQUI'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($httpCode === 200) {
echo 'Webhook removido com sucesso';
}
{ "success": true }Formato: pagamento#
Enviado nos eventos transaction_created, transaction_paid, transaction_refunded e transaction_updated. Referência de formato — não é uma rota da API.
{
"id": "8d0f3b8f-5c2f-4a10-8dd6-8bbf5e9b1d11",
"type": "transaction",
"event": "transaction_paid",
"scope": "user",
"transaction": {
"id": "transaction_abc123",
"amount": 5000,
"status": "paid",
"pix": {
"endToEndId": "E1234567820241231000000000000001",
"payerInfo": {
"name": "Joao Silva",
"document": "11122233344"
}
}
}
}Formato: transferência#
Enviado nos eventos transfer_created, transfer_updated, transfer_completed e transfer_canceled. Referência de formato — não é uma rota da API.
{
"id": "5f9e0c94-60a4-4df8-bb81-7f6efc6f61b0",
"type": "transfer",
"event": "transfer_completed",
"scope": "user",
"transfer": {
"id": "transfer_abc123",
"amount": 10000,
"status": "paid",
"pix": {
"endToEndId": "E1234567820241231000000000000002",
"creditorAccount": {
"name": "Fornecedor Exemplo",
"document": "12345678000199"
}
}
}
}Formato: infração#
Enviado no evento infraction, quando uma infração ou MED é criada ou atualizada para uma cobrança PIX. Referência de formato — não é uma rota da API.
{
"id": "3db3ac40-a069-45e6-8cb8-6d55d09f516d",
"type": "infraction",
"event": "infraction",
"scope": "user",
"infraction": {
"id": "infraction_abc123",
"amount": 5000,
"status": "OPEN",
"pix": {
"endToEndId": "E1234567820241231000000000000001"
}
},
"transaction": {
"id": "transaction_abc123",
"amount": 5000,
"status": "infraction",
"pix": {
"endToEndId": "E1234567820241231000000000000001",
"payerInfo": {
"name": "Joao Silva",
"document": "11122233344"
}
}
}
}Como funcionam#
O MED (Mecanismo Especial de Devolução) é o processo do Banco Central para contestar um PIX recebido — por suspeita de fraude ou pedido de devolução do pagador. Quando uma cobrança PIX IN da sua conta é contestada, o PagzPay registra uma infração, bloqueia o valor contestado e avisa pelo webhook infraction a cada mudança.
Tipos
| Tipo | Significado |
|---|---|
FRAUD | Suspeita de fraude na cobrança. |
REFUND_REQUEST | Pedido de devolução feito pelo pagador. |
REFUND_CANCELLED | Pedido de devolução cancelado. |
Status (infraction.status)
| Status | Significado | Aceita defesa? |
|---|---|---|
OPEN | Infração aberta. O valor fica bloqueado. | Sim |
ACKNOWLEDGED | Infração reconhecida pelo PSP; bloqueio mantido. | Sim |
WAITING_PSP | Aguardando o PSP; bloqueio mantido. | Sim |
DEFENDED | Defesa enviada, em análise. | Não |
ANSWERED · WAITING_ADJUSTMENTS | Em andamento no PSP; bloqueio mantido. | Não |
CLOSED | Final. Desfecho em transaction.status (veja abaixo). | Não |
CANCELLED | Final. Infração cancelada; bloqueio liberado. | Não |
Efeito no saldo e na cobrança
| Momento | transaction.status | Saldo |
|---|---|---|
| Infração aberta ou em andamento | infraction | O valor sai de pix.balance e aparece em pixBlocked.balance (Consultar saldo). |
| Encerrada a seu favor ou cancelada | paid | Bloqueio liberado; o valor volta para pix.balance. |
| Encerrada a favor do pagador | refund | O valor é devolvido ao pagador e o bloqueio é encerrado. |
CLOSEDO payload não traz o resultado da análise. Use o transaction.status do mesmo evento: paid = valor liberado para você; refund = valor devolvido ao pagador.
Como se defender
| Onde | Pelo Dashboard, em Pagamentos → Infrações. Não há endpoint de defesa na API. |
| Quando | Enquanto o status for OPEN, ACKNOWLEDGED ou WAITING_PSP. |
| O quê | Uma descrição (mínimo de 5 caracteres) e, se quiser, arquivos de comprovação — nota fiscal, comprovante de entrega, conversa com o cliente. |
| Limite | Uma defesa por infração. Depois do envio o status vira DEFENDED e não é possível editar. |
OPEN — depois que o status avança, o envio deixa de ser aceito.
Tratando o webhook
infraction é reenviado a cada mudança de status da mesma infração. Use infraction.id + infraction.status para processar cada transição uma única vez.
function onInfraction({ infraction, transaction }) {
const { status } = infraction
if (['OPEN', 'ACKNOWLEDGED', 'WAITING_PSP'].includes(status)) {
// Valor bloqueado: suspenda a entrega e envie a defesa pelo Dashboard
return holdOrder(transaction.id)
}
if (status === 'CANCELLED' || (status === 'CLOSED' && transaction.status === 'paid')) {
return releaseOrder(transaction.id) // valor liberado
}
if (status === 'CLOSED' && transaction.status === 'refund') {
return cancelOrder(transaction.id) // valor devolvido ao pagador
}
}Split de pagamentos#
Distribui automaticamente parte do valor líquido de uma cobrança PIX IN (Criar QR Code) para outras empresas PagzPay — útil para marketplaces e plataformas com parceiros. O split é executado no momento em que o pagamento é confirmado.
Objeto splits[]
| Campo | Tipo | Obrig. | Descrição |
|---|---|---|---|
email | string | Sim | E-mail da empresa PagzPay que recebe o split — precisa ter conta ativa. |
percentage | number | Sim | De 0,01 a 100. A soma de todos os splits não pode ultrapassar 100%. |
splits não pode passar de 100% do valor líquido da cobrança.
{
"amountInCents": 20000,
"description": "Venda marketplace #5678",
"customer": { "documentType": "cpf", "document": "33344455566" },
"splits": [
{ "email": "parceiro1@empresa.com", "percentage": 30 },
{ "email": "parceiro2@empresa.com", "percentage": 15 }
]
}Idempotência#
Para transferências PIX (PIX OUT), envie o header x-idempotency-key com um UUID único por operação para garantir que não haja duplicação em caso de retry.
| Situação | Comportamento |
|---|---|
| Mesma chave, retry de rede | Nenhuma transferência duplicada é criada. |
| Mesma chave reaproveitada com corpo diferente | 409 IDEMPOTENCY_CONFLICT. |
| Sem cabeçalho | A requisição é rejeitada — o header é obrigatório em PIX OUT. |
-H "x-idempotency-key: 550e8400-e29b-41d4-a716-446655440000"Erros#
Erros sempre respondem em JSON com os campos error (código) e message (legível). Alguns também trazem details com informações adicionais.
| Status | Código | Significado |
|---|---|---|
| 400 | INVALID_REQUEST | Corpo da requisição inválido — message aponta o campo. |
| 401 | UNAUTHORIZED | Token ausente, inválido ou expirado. |
| 404 | NOT_FOUND | Recurso não encontrado ou pertence a outra conta. |
| 409 | IDEMPOTENCY_CONFLICT | x-idempotency-key reaproveitada com corpo diferente. |
| 429 | RATE_LIMITED | Muitas requisições — tente novamente em alguns minutos. |
{ "error": "NOT_FOUND", "message": "QR Code PIX não encontrado" }
PagzPay