PixGo API Documentation

Simple and powerful PIX payment integration

Last updated: October 9, 2026

Introduction

The PixGo API allows you to integrate PIX payments into your application quickly and securely. Our RESTful API uses JSON for communication and provides webhooks for real-time notifications.

Key Features:

  • Instant PIX payment generation
  • Real-time payment status
  • Automatic webhook notifications
  • CPF/CNPJ validation support
  • Secure API key authentication
  • Detailed transaction logs

Base URL:

https://pixgo.org/api/v1
Quick Start: Get your API key, make a POST request to create a payment and receive the PIX QR Code instantly.

Authentication

All API requests require authentication using your API key in the X-API-Key header.

Getting your API Key:

  1. Create an account at pixgo.org
  2. Validate your Liquid wallet information
  3. Navigate to "Checkouts" section
  4. Generate your API key

Header Example:

X-API-Key: pk_1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
Security: Keep your API Key secure. Never expose it in client-side code or public repositories.

API Endpoints

POST /api/v1/payment/create

Create Payment

Creates a new PIX payment request

MANDATORY FIELD since 06/25/2026

The receiver_cpf field (payer CPF or CNPJ) is MANDATORY on every payment creation, as required by the settlement provider. Charges created without it are rejected.

Ownership lock: once the QR Code is generated, only the informed CPF/CNPJ can pay it. If a third party pays, the payment is automatically rejected and the refund to the third party's account can take up to 48 hours. Make sure the document sent belongs to the person who will actually pay. The field is already available: update your integration now.

Parameters:

{ "amount": 25.50, "description": "Produto XYZ", "receiver_name": "João Silva", "receiver_cpf": "12345678901", "receiver_email": "[email protected]", "receiver_phone": "11999999999", "receiver_address": "Rua das Flores, 123, Centro, São Paulo, SP, 01234-567", "external_id": "pedido_123" }
Validation Rules:
  • amount: Required. Minimum R$ 10.00, maximum varies by your level
  • receiver_cpf: Mandatory since 06/25/2026. Payer CPF (11 digits) or CNPJ (14 digits), numbers only, with valid check digit. Only this document will be able to pay the generated QR
  • receiver_name: Optional (recommended). Payer full name, 2 to 100 characters
  • receiver_email: Optional. Valid email, maximum 255 characters
  • receiver_phone: Optional. Phone with area code, 10 or 11 digits, numbers only
  • receiver_address: Optional. Complete address, 10 to 500 characters
  • external_id: Optional. Maximum 50 characters
  • description: Optional. Maximum 200 characters

Success Response: (201)

{ "success": true, "data": { "payment_id": "dep_1234567890abcdef", "external_id": "pedido_123", "amount": 25.50, "status": "pending", "qr_code": "00020126580014BR.GOV.BCB.PIX...", "qr_image_url": "https://pixgo.org/qr/dep_1234567890abcdef.png", "expires_at": "2025-01-15T12:20:00", "created_at": "2025-01-15T12:00:00" } }

Error Response: (400)

{ "success": false, "error": "LIMIT_EXCEEDED", "message": "Valor excede seu limite atual de R$ 300,00", "current_limit": 300.00, "amount_requested": 500.00 }

GET /api/v1/payment/{id}/status

Check Payment Status

Retrieves the current status of a payment

Rate Limit: This endpoint has a limit of 1,000 requests per 24 hours. If you need to increase this limit, contact support via email or through the Telegram group (button available in the PixGo dashboard).

Success Response: (200)

{ "success": true, "data": { "payment_id": "dep_1234567890abcdef", "external_id": "pedido_123", "amount": 25.50, "status": "completed", "customer_name": "João Silva", "customer_cpf": "***.456.789-**", "payer_euid": null, "customer_phone": "(11) 99999-9999", "created_at": "2025-01-15T12:00:00", "updated_at": "2025-01-15T12:15:30" } }

About the CPF: the customer_cpf field is returned masked (***.456.789-**). The full document is never returned by the API.

payer_euid: payer identifier at the provider. Comes as null until the payment is confirmed, and may remain null afterwards depending on the provider — do not use this field as a signal that the payment was made; use status for that.

GET /api/v1/payment/{id}

Get Payment Details

Retrieves complete payment information

Success Response: (200)

{ "success": true, "terminal": false, "data": { "payment_id": "dep_1234567890abcdef", "external_id": "pedido_123", "amount": 25.50, "status": "completed", "customer_name": "João Silva", "customer_phone": "(11) 99999-9999", "customer_address": "Rua das Flores, 123, Centro, São Paulo, SP, 01234-567", "description": "Produto XYZ", "qr_code": "00020126580014BR.GOV.BCB.PIX...", "qr_image_url": "https://pixgo.org/qr/dep_1234567890abcdef.png", "created_at": "2025-01-15T12:00:00", "updated_at": "2025-01-15T12:15:30", "expires_at": "2025-01-15T12:20:00" } }
Warning: this endpoint may respond 410
When the payment reaches a final state (expired, canceled, cancelled or refunded), the response comes with HTTP 410 Gone and "terminal": true — the body is identical to the 200 one. Treat 200 and 410 as valid responses; a 410 means "this payment exists and will not change anymore", not an error. These responses also come with Cache-Control: immutable for 24h, so they can be safely cached.

This endpoint does not return customer_cpf. If you need the masked document, use GET /api/v1/payment/{id}/status.

GET /api/v1/payments

Search payments by your external_id

Use this when you only have the external_id you sent at creation and did not store the payment_id. Always returns a list, because external_id is defined by you and may repeat. If yours is unique, just read data[0].

Parameters (query string)

  • external_id: Required. Maximum 50 characters
  • limit: Optional. Default 20, maximum 100
  • offset: Optional. Default 0
curl -H "X-API-Key: SUA_CHAVE" \ "https://pixgo.org/api/v1/payments?external_id=pedido_123"

Success Response: (200)

{ "success": true, "count": 1, "total": 1, "limit": 20, "offset": 0, "data": [ { "payment_id": "dep_1234567890abcdef", "external_id": "pedido_123", "amount": 25.50, "status": "completed", "terminal": false, "customer_name": "João Silva", "customer_phone": "(11) 99999-9999", "customer_address": "Rua das Flores, 123, Centro, São Paulo, SP, 01234-567", "description": "Produto XYZ", "qr_code": "00020126580014BR.GOV.BCB.PIX...", "qr_image_url": "https://pixgo.org/qr/dep_1234567890abcdef.png", "created_at": "2025-01-15T12:00:00", "updated_at": "2025-01-15T12:15:30", "expires_at": "2025-01-15T12:20:00" } ] }

No results: returns 200 with "data": [] and "total": 0 — not 404. A 404 here would mean the URL is wrong, not that the search found nothing.

Payment Status Values:

  • pending - Awaiting payment
  • completed - Payment confirmed
  • expired - Payment expired (see expires_at field)
  • cancelled - Payment cancelled
Progressive Limit System: Payment limits evolve through 7 levels based on your confirmed transaction history. Liquid wallet must be validated to use the API. Maximum limit per QR Code: R$ 6,000.00. Daily limit per payer CPF/CNPJ: R$ 6,000.00.

Webhooks

Webhooks allow your application to receive automatic real-time notifications when a payment status changes. Configure a webhook URL when creating a payment to receive instant updates.

Configuration

To receive webhooks, include the webhook_url parameter when creating a payment:

{ "amount": 25.50, "description": "Produto XYZ", "receiver_cpf": "12345678901", "webhook_url": "https://seusite.com/webhook/pixgo" }

Endpoint Requirements

  • Your endpoint must accept POST requests
  • Respond with HTTP 200-299 to confirm receipt
  • Timeout: 10 seconds per attempt
  • We recommend using HTTPS for security

Available Events

  • payment.completed - Payment confirmed successfully
  • payment.expired - Payment expired (see expires_at field)
  • payment.refunded - Payment refunded

Payload Structure

Update 2026-04: enriched payload with (1) customer form data (customer object), (2) separate PIX payer data (payer object, masked by BCB/LGPD), (3) full fee breakdown and net amount (amounts object), (4) product/checkout data (product object).

Event: payment.completed

{ "event": "payment.completed", "timestamp": "2026-04-14T12:15:30-03:00", "data": { "payment_id": "019d8d01af2f7015b490df4f04a40956", "external_id": "checkout_313f69e00bec13ba34470bb6b8e46c2c_17761871", "checkout_id": "313f69e00bec13ba34470bb6b8e46c2c", "status": "completed", "description": "X-Frango Premium", "customer": { "name": "Marcos Lins", "cpf": "37933480837", "email": "[email protected]", "phone": "(14) 97515-3504", "address": "Rua Exemplo, 123", "custom_field": { "label": "Apartamento", "value": "205-B" } }, "payer": { "name": "CLEITON HENRIQUE GONCALVES", "cpf": "***.334.808-**" }, "product": { "business_name": "PhedeXs Strategies", "description": "X-Frango Premium: Delicioso e Completo!", "value": 10.00 }, "amount": 10.00, "amounts": { "gross": 10.00, "fee_pixgo": 1.20, "fee_liquid": 0.50, "fee_total": 1.70, "net": 8.30, "currency": "BRL" }, "created_at": "2026-04-14 12:00:00", "updated_at": "2026-04-14 12:15:30", "completed_at": "2026-04-14 12:15:30", "expired_at": null, "refunded_at": null } }

How to interpret: customer = data the customer typed in your checkout (name, CPF, phone). Use these for your spreadsheet/CRM.
payer = data of who actually paid via PIX (masked by LGPD). May differ from customer (e.g. parent paying for child).
amounts.net = net amount you actually receive (after all fees deducted).

Events: payment.expired and payment.refunded

Same structure as payment.completed. The completed_at, expired_at and refunded_at fields indicate which event occurred (only the relevant one is filled).

Request Headers

Each webhook sent includes the following headers:

Content-Type: application/json X-Webhook-Event: payment.completed X-Webhook-Timestamp: 1705328130 X-Webhook-Signature: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2 User-Agent: PixGo-Webhook/1.0

Signature Verification (Webhook Secret)

Each webhook is signed with your Webhook Secret using HMAC-SHA256. The secret is available in the "Checkouts" section of your dashboard, along with your API Key.

How to verify the signature:

  1. Extract the X-Webhook-Timestamp and X-Webhook-Signature from the headers
  2. Concatenate: timestamp + "." + raw JSON request body
  3. Generate the HMAC-SHA256 using your Webhook Secret
  4. Compare with the X-Webhook-Signature header using timing-safe comparison

Verification Example (PHP):

$webhookSecret = 'whsec_seu_webhook_secret_aqui'; $payload = file_get_contents('php://input'); $timestamp = $_SERVER['HTTP_X_WEBHOOK_TIMESTAMP'] ?? ''; $signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? ''; // Gerar assinatura esperada $signaturePayload = $timestamp . '.' . $payload; $expectedSignature = hash_hmac('sha256', $signaturePayload, $webhookSecret); // Comparar de forma segura (timing-safe) if (!hash_equals($expectedSignature, $signature)) { http_response_code(401); exit('Assinatura invalida'); } // Opcional: rejeitar timestamps antigos (protecao contra replay attack) if (abs(time() - intval($timestamp)) > 300) { http_response_code(401); exit('Timestamp expirado'); } // Assinatura valida - processar webhook normalmente $data = json_decode($payload, true);

Verification Example (Node.js):

const crypto = require('crypto'); const WEBHOOK_SECRET = 'whsec_seu_webhook_secret_aqui'; function verifyWebhook(req) { const timestamp = req.headers['x-webhook-timestamp']; const signature = req.headers['x-webhook-signature']; const payload = req.rawBody; // body bruto como string const signaturePayload = timestamp + '.' + payload; const expected = crypto .createHmac('sha256', WEBHOOK_SECRET) .update(signaturePayload) .digest('hex'); // Comparacao timing-safe if (!crypto.timingSafeEqual( Buffer.from(expected, 'hex'), Buffer.from(signature, 'hex') )) { throw new Error('Assinatura invalida'); } // Protecao contra replay attack (5 min) if (Math.abs(Date.now() / 1000 - parseInt(timestamp)) > 300) { throw new Error('Timestamp expirado'); } return JSON.parse(payload); }
Where to find: Your Webhook Secret is available on the Checkouts page of your dashboard, right below your API Key. Never expose the secret in client-side code.

Complete Handler Example (PHP)

<?php $webhookSecret = 'whsec_seu_webhook_secret_aqui'; // Receber dados do webhook $payload = file_get_contents('php://input'); $timestamp = $_SERVER['HTTP_X_WEBHOOK_TIMESTAMP'] ?? ''; $signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? ''; // Verificar assinatura $expected = hash_hmac('sha256', $timestamp . '.' . $payload, $webhookSecret); if (!hash_equals($expected, $signature)) { http_response_code(401); exit('Assinatura invalida'); } $data = json_decode($payload, true); // Validar se é um evento válido if (!$data || !isset($data['event'])) { http_response_code(400); exit('Invalid payload'); } // Processar evento switch ($data['event']) { case 'payment.completed': $paymentId = $data['data']['payment_id']; $amountGross = $data['data']['amounts']['gross']; // valor bruto pago $amountNet = $data['data']['amounts']['net']; // valor líquido recebido $customerName = $data['data']['customer']['name']; // nome do cliente do checkout $customerCpf = $data['data']['customer']['cpf']; // CPF do cliente $payerName = $data['data']['payer']['name']; // nome do pagador PIX (BCB) $payerCpf = $data['data']['payer']['cpf']; // CPF mascarado por LGPD // Atualizar seu banco de dados // marcarPedidoComoPago($data['data']['external_id']); // Enviar email de confirmação // enviarEmailConfirmacao($data['data']); error_log("Pagamento {$paymentId} confirmado: R$ {$amount} de {$payerName}"); break; case 'payment.expired': $paymentId = $data['data']['payment_id']; // Cancelar pedido // cancelarPedido($data['data']['external_id']); error_log("Pagamento {$paymentId} expirou"); break; } // Responder com sucesso http_response_code(200); echo json_encode(['received' => true]);
Tip: Use the external_id field to easily identify the order in your system when receiving the webhook.
Important: Always verify the webhook signature before processing data. For critical payments, also make an additional query to the status endpoint to confirm.

Code Examples

PHP Example:

<?php $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => 'https://pixgo.org/api/v1/payment/create', CURLOPT_RETURNTRANSFER => true, CURLOPT_POST => true, CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'X-API-Key: pk_1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef' ], CURLOPT_POSTFIELDS => json_encode([ 'amount' => 25.50, 'description' => 'Produto XYZ', 'customer_name' => 'João Silva', 'customer_cpf' => '12345678901', 'customer_email' => '[email protected]', 'customer_phone' => '(11) 99999-9999', 'customer_address' => 'Rua das Flores, 123, Centro, São Paulo, SP, 01234-567', 'external_id' => 'pedido_123' ]) ]); $response = curl_exec($curl); $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); if ($httpCode === 201) { $data = json_decode($response, true); echo "Pagamento criado: " . $data['data']['payment_id']; echo "QR Code URL: " . $data['data']['qr_image_url']; } else { echo "Erro: " . $response; }

JavaScript Example:

const axios = require('axios'); async function createPayment() { try { const response = await axios.post('https://pixgo.org/api/v1/payment/create', { amount: 25.50, description: 'Produto XYZ', customer_name: 'João Silva', customer_cpf: '12345678901', customer_email: '[email protected]', customer_phone: '(11) 99999-9999', customer_address: 'Rua das Flores, 123, Centro, São Paulo, SP, 01234-567', external_id: 'pedido_123' }, { headers: { 'Content-Type': 'application/json', 'X-API-Key': 'pk_1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef' } }); console.log('Pagamento criado:', response.data.data.payment_id); console.log('QR Code URL:', response.data.data.qr_image_url); return response.data; } catch (error) { console.error('Erro:', error.response?.data || error.message); } } createPayment();

Check Status (PHP):

function checkPaymentStatus($paymentId) { $curl = curl_init(); curl_setopt_array($curl, [ CURLOPT_URL => "https://pixgo.org/api/v1/payment/{$paymentId}/status", CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ 'X-API-Key: pk_1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef' ] ]); $response = curl_exec($curl); $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); if ($httpCode === 200) { $data = json_decode($response, true); return $data['data']['status']; } return false; } // Uso $status = checkPaymentStatus('dep_1234567890abcdef'); echo "Status do pagamento: " . $status;

Getting Started

Follow these steps to start using the PixGo API:

Registration Process:

  1. Access pixgo.org and create your account
  2. Validate your Liquid wallet information
  3. Navigate to the "Checkouts" section
  4. Generate your production API Key
  5. Start integrating PIX payments

API Keys:

All API keys are for production use - there is no separate test environment

pk_1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef

Progression System - 7 Levels:

  • Level 1 - Beginner (0 to R$ 299.99 confirmed): Limit of R$ 300.00 per QR Code
  • Level 2 - Bronze (R$ 300.00 to R$ 499.99 confirmed): Limit of R$ 500.00 per QR Code
  • Level 3 - Silver (R$ 500.00 to R$ 999.99 confirmed): Limit of R$ 1,000.00 per QR Code
  • Level 4 - Gold (R$ 1,000.00 to R$ 2,999.99 confirmed): Limit of R$ 1,500.00 per QR Code
  • Level 5 - Platinum (R$ 3,000.00 to R$ 4,999.99 confirmed): Limit of R$ 2,000.00 per QR Code
  • Level 6 - Diamond (R$ 5,000.00 to R$ 5,999.99 confirmed): Limit of R$ 2,500.00 per QR Code
  • Maximum Level - Elite (R$ 6,000.00+ confirmed): Limit of R$ 6,000.00 per QR Code
How Limits Work:
  • Limits are based on total confirmed payments (status "completed")
  • Liquid wallet must be validated to use the API
  • Minimum amount: R$ 10.00 per payment
  • Daily limit per payer CPF/CNPJ: R$ 6,000.00
  • Unlimited QR Codes per day
  • Automatic evolution based on transaction history

Status Monitoring:

To track payments, query the status endpoint periodically (recommended every 30 seconds).

Payment Expiration:

Each PIX charge has its own expiration window. Always use the expires_at field returned on creation and on payment lookup — do not assume a fixed value.

Important: All payments are processed in real time in production environment. There is no separate test environment.

Support

Need help? Contact our development team:

  • Email: [email protected]
  • Telegram: Access the support group through the button available in the PixGo dashboard
  • Documentation: Always up-to-date on this page
Additional Resources:
  • Documentation always updated on this page
  • Technical support via email and Telegram for developers
  • API limit increase requests available