Checkout hospedado rápido
Crie uma sessão de pagamento, redirecione o cliente e depois verifique ou receba o IPN quando a transação terminar.
Receba pagamentos pela carteira, por gateway e por checkout hospedado, com credenciais por ambiente, controle de moedas por lojista e regras de gateway no painel.
Crie uma sessão de pagamento, redirecione o cliente e depois verifique ou receba o IPN quando a transação terminar.
A moeda pedida precisa estar ativada para o lojista e ter uma carteira de lojista ativa.
O lojista escolhe os gateways na configuração da API sem gerar novas credenciais.
ZexosPay A API usa chaves para autenticar as requisições. Pegue suas credenciais no painel do lojista.
ZexosPay A API tem ambiente sandbox (testes) e produção. Sempre teste no sandbox antes de ir ao ar.
Use para: Desenvolvimento, testes, integração
X-Environment: sandbox
Credenciais: Use chaves de API com prefixo test_*
Use para: Pagamentos reais, dinheiro de verdade
X-Environment: production
Credenciais: Use chaves de API de produção (sem prefixo)
| Credencial | Cabeçalho | Descrição | Localização |
|---|---|---|---|
ID do lojista |
X-Merchant-Key |
Seu identificador único de lojista | Painel → Lojista → Configuração |
Chave de API |
X-API-Key |
Chave de autenticação da API | Painel → Lojista → Configuração |
Horário da requisição |
X-Timestamp |
Timestamp Unix em segundos usado contra replay | Gerado pelo seu servidor a cada requisição |
Assinatura da API |
X-Signature |
Assinatura HMAC-SHA256 da requisição | Gerado com o seu Client Secret |
Client Secret |
- | Usado para assinar requisições e verificar a assinatura dos webhooks | Painel → Lojista → CONFIG |
| Chave de API de produção | X-API-Key |
Chave de API de produção (sem prefixo) | Painel do lojista > Configuração da API > Modo produção |
| Chave de lojista de produção | X-Merchant-Key |
Identificador de lojista de produção (sem prefixo) | Painel do lojista > Configuração da API > Modo produção |
Quando as assinaturas forem obrigatórias, assine exatamente este conteúdo com seu Client Secret:
timestamp.HTTP_METHOD.path_with_query.raw_body
Use este fluxo para uma integração segura em produção. As credenciais identificam o lojista, e a disponibilidade de moedas e gateways é controlada no painel.
Abra Painel -> Lojista -> Configuração e copie a chave de lojista, a chave de API e o Client Secret do sandbox ou da produção.
Confira se o lojista aceita a moeda do checkout e se o dono tem uma carteira ativa nessa moeda.
Na configuração da API, ative os gateways que devem aparecer no checkout para cada moeda aceita.
Faça POST em /api/v1/initiate-payment com X-Timestamp e X-Signature, redirecione o cliente para a payment_url e depois verifique ou aguarde o IPN.
Use primeiro as credenciais de sandbox e troque para produção quando o checkout e o IPN estiverem conferidos.
A API de lojista não é mais um fluxo de moeda única e gateway fixo. O lojista pode aceitar várias moedas, ter credenciais separadas de sandbox e produção e escolher os gateways na página de configuração da API sem gerar novas chaves.
Seu código envia valor, moeda, redirecionamentos, URL de IPN e palavras-chave opcionais de gateway. O painel decide quais moedas, carteiras e gateways estão de fato disponíveis para o lojista.
Lojistas pendentes podem testar no sandbox. A API de produção e o checkout real só ficam disponíveis após a aprovação do administrador.
Cada currency_code da requisição precisa estar na lista de moedas aceitas pelo lojista. Moedas não aceitas são recusadas antes do checkout abrir.
O dono da loja precisa ter uma carteira ativa na moeda pedida; senão, a API retorna um erro de disponibilidade de carteira.
Só gateways automáticos ativos que correspondem à moeda pedida e à seleção do lojista aparecem no checkout.
X-Environment decide qual chave de lojista, chave de API e segredo de API são usados.
Lojistas rejeitados ou desativados são bloqueados. A produção também exige status aprovado.
currency_code deve ser uma moeda aceita pelo lojista, como BRL, USD ou EUR.
O dono da loja precisa de uma carteira ativa nessa mesma moeda.
As seleções na configuração da API restringem o checkout aos gateways escolhidos. Se nenhum for escolhido, o padrão seguro é usar todos os gateways automáticos ativos daquela moeda.
allow_payment_methods pode reduzir a lista de gateways, mas não libera um gateway não configurado ou de outra moeda.
| Caso | Resultado da API | Correção |
|---|---|---|
| O lojista aceita USD e EUR, mas só tem carteira USD. | 422 Receiver wallet for this currency is not available. |
Crie/ative a carteira EUR do lojista antes de aceitar checkout em EUR. |
| O Stripe USD está selecionado, mas a requisição envia currency_code EUR. | O Stripe USD não vai aparecer no checkout. | Selecione um gateway EUR ativo ou envie em USD. |
| O lojista ainda não escolheu nenhum gateway. | O checkout usa todos os gateways automáticos ativos da moeda pedida. | Use a configuração da API para limitar o checkout aos gateways preferidos. |
allow_payment_methods=["paypal"] mas o PayPal não está configurado para o lojista. |
O PayPal continua oculto. | Ative o PayPal em Controles de gateway de pagamento se a moeda dele corresponder. |
| Lojista pendente chama a API de produção. | 403 Merchant Pending Approval |
Use o sandbox até a aprovação do administrador. |
Um gateway configurado para USD não processa checkout em EUR, a não ser que exista um gateway EUR separado.
O API Secret só é usado para assinar requisições servidor a servidor e verificar assinaturas de IPN.
A payment_url retornada tem prazo. Crie uma nova sessão de pagamento para links de checkout expirados.
Um lojista só pode verificar as próprias transações e só no ambiente correspondente (sandbox ou produção).
O checkout pela API é controlado por três camadas: moeda aceita pelo lojista, carteira de recebimento ativa e gateways configurados. Assim as opções do checkout continuam certas depois de gerar as credenciais.
Um gateway só aparece no checkout quando todas as regras abaixo são verdadeiras. Se o lojista escolheu gateways, só esses ficam liberados no checkout.
| Camada | Quem controla | Efeito |
|---|---|---|
currency_code |
Requisição da API | Deve ser uma moeda aceita pelo lojista, com carteira de recebimento ativa. |
Controles de gateway de pagamento |
Painel do lojista | Define os gateways disponíveis no checkout para cada moeda aceita. |
allow_payment_methods |
Requisição da API | Filtro opcional por nome/código aplicado depois das regras do lojista. Ele não libera um gateway que o lojista não configurou. |
Crie uma sessão de checkout para uma moeda aceita pelo lojista. O cliente deve abrir a payment_url retornada.
https://usepay.online/api/v1/initiate-payment
| Cabeçalho | Valor | Obrigatório | Descrição |
|---|---|---|---|
Content-Type |
application/json |
Sim | Tipo de conteúdo da requisição |
Accept |
application/json |
Sim | Tipo de resposta esperado |
X-Environment |
sandbox | production |
Sim | Use sandbox para testes e produção para pagamentos reais |
X-Merchant-Key |
{merchant_key} |
Sim | Identificador do lojista na página de configuração da API |
X-API-Key |
{api_key} |
Sim | Chave de API do ambiente selecionado |
X-Timestamp |
{unix_timestamp} |
Sim | Timestamp Unix atual em segundos. Requisições fora da tolerância são recusadas. |
X-Signature |
sha256={hmac} |
Sim | HMAC-SHA256 de timestamp.METHOD.path_with_query.raw_body usando o API Secret do ambiente selecionado. |
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
payment_amount |
number | Sim | Valor do pagamento. O mínimo é 1.00. |
currency_code |
string | Sim | Código de moeda de 3 letras. Precisa estar ativada para o lojista e ter uma carteira de lojista ativa. |
ref_trx |
string | Sim | Sua referência única de pedido ou transação. Máximo de 60 caracteres. |
success_redirect |
url | Sim | O cliente volta para cá depois de um checkout bem-sucedido. |
cancel_redirect |
url | Sim | O cliente volta para cá quando o checkout é cancelado ou não pode continuar. |
ipn_url |
url | Sim | URL de webhook servidor a servidor para atualizações de status do pagamento. |
description |
string | Não | Descrição do pagamento visível nas transações do lojista. |
customer_name |
string | Não | Nome do cliente. Máximo de 100 caracteres. |
customer_email |
Não | E-mail do cliente. Máximo de 100 caracteres. | |
customer_document |
string | Não | CPF ou CNPJ de quem paga (com ou sem pontuação). Usado no PIX; se não for enviado, o checkout pede ao cliente. |
customer_phone |
string | Não | Telefone de quem paga, com DDD. |
allow_payment_methods |
string | array | Não | Filtro opcional por palavra-chave aplicado depois das regras do lojista. Exemplo: "stripe,paypal" ou ["stripe","paypal"]. |
| Campo | Tipo | Significado |
|---|---|---|
info.merchant_payment_methods_restricted |
boolean | true quando o lojista escolheu gateways específicos na configuração da API. |
info.merchant_payment_method_ids |
array | IDs dos métodos de depósito aceitos para a moeda pedida. |
info.merchant_payment_method_codes |
array | Códigos dos métodos que podem aparecer no checkout. |
curl -X POST "https://usepay.online/api/v1/initiate-payment" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "X-Environment: sandbox" \
-H "X-Merchant-Key: test_merchant_key" \
-H "X-API-Key: test_api_key" \
-H "X-Timestamp: 1778650000" \
-H "X-Signature: sha256=generated_hmac_signature" \
-d '{
"payment_amount": 250.00,
"currency_code": "USD",
"ref_trx": "ORDER_12345",
"description": "Premium Subscription",
"success_redirect": "https://merchant.example/payments/success",
"cancel_redirect": "https://merchant.example/payments/cancel",
"ipn_url": "https://merchant.example/webhooks/zexospay",
"customer_name": "John Doe",
"customer_email": "john@example.com",
"allow_payment_methods": ["stripe", "paypal"]
}'
<?php
use Illuminate\Support\Facades\Http;
$payload = [
'payment_amount' => 250.00,
'currency_code' => 'USD',
'ref_trx' => 'ORDER_12345',
'description' => 'Premium Subscription',
'success_redirect' => route('payments.success'),
'cancel_redirect' => route('payments.cancel'),
'ipn_url' => route('webhooks.zexospay'),
'customer_name' => 'John Doe',
'customer_email' => 'john@example.com',
'allow_payment_methods' => ['stripe', 'paypal'],
];
$body = json_encode($payload, JSON_THROW_ON_ERROR);
$timestamp = (string) time();
$path = '/api/v1/initiate-payment';
$signature = hash_hmac(
'sha256',
$timestamp.'.POST.'.$path.'.'.$body,
config('services.zexospay.api_secret')
);
$response = Http::withHeaders([
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'X-Environment' => 'sandbox',
'X-Merchant-Key' => config('services.zexospay.merchant_key'),
'X-API-Key' => config('services.zexospay.api_key'),
'X-Timestamp' => $timestamp,
'X-Signature' => 'sha256='.$signature,
])->withBody($body, 'application/json')
->post('https://usepay.online/api/v1/initiate-payment')
->throw()
->json();
return redirect()->away($response['payment_url']);
const crypto = require('crypto');
const payload = {
payment_amount: 250.00,
currency_code: 'USD',
ref_trx: 'ORDER_12345',
description: 'Premium Subscription',
success_redirect: 'https://merchant.example/payments/success',
cancel_redirect: 'https://merchant.example/payments/cancel',
ipn_url: 'https://merchant.example/webhooks/zexospay',
customer_name: 'John Doe',
customer_email: 'john@example.com',
allow_payment_methods: ['stripe', 'paypal']
};
const body = JSON.stringify(payload);
const timestamp = Math.floor(Date.now() / 1000).toString();
const path = '/api/v1/initiate-payment';
const signature = crypto
.createHmac('sha256', process.env.DIGIKASH_API_SECRET)
.update(`${timestamp}.POST.${path}.${body}`)
.digest('hex');
const response = await fetch('https://usepay.online/api/v1/initiate-payment', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'X-Environment': 'sandbox',
'X-Merchant-Key': process.env.DIGIKASH_MERCHANT_KEY,
'X-API-Key': process.env.DIGIKASH_API_KEY,
'X-Timestamp': timestamp,
'X-Signature': `sha256=${signature}`
},
body
});
const data = await response.json();
if (!response.ok) {
throw new Error(data.error || 'Payment initiation failed');
}
window.location.href = data.payment_url;
{
"payment_url": "https://ZexosPay.test/payment/checkout?token=encrypted&signature=signed",
"info": {
"ref_trx": "ORDER_12345",
"description": "Premium Subscription",
"ipn_url": "https://merchant.example/webhooks/zexospay",
"cancel_redirect": "https://merchant.example/payments/cancel",
"success_redirect": "https://merchant.example/payments/success",
"customer_name": "John Doe",
"customer_email": "john@example.com",
"merchant_id": 1,
"merchant_name": "Demo Store",
"amount": 250,
"currency_code": "USD",
"environment": "sandbox",
"is_sandbox": true,
"allow_payment_methods": ["stripe", "paypal"],
"merchant_payment_methods_restricted": true,
"merchant_payment_method_ids": [7],
"merchant_payment_method_codes": ["stripe-usd"]
}
}
O currency_code pedido não está na lista de moedas aceitas pelo lojista.
O dono da loja não tem uma carteira ativa na moeda pedida.
Confira se X-Environment, X-Merchant-Key e X-API-Key são do mesmo ambiente.
Busque o status mais recente de uma transação de checkout. Sempre confira pelo servidor antes de entregar um pedido.
https://usepay.online/api/v1/verify-payment/{trxId}
| Cabeçalho | Valor | Obrigatório | Descrição |
|---|---|---|---|
Accept |
application/json |
Sim | Tipo de resposta esperado |
X-Environment |
sandbox | production |
Sim | Deve ser o mesmo ambiente usado para iniciar o pagamento |
X-Merchant-Key |
{merchant_key} |
Sim | Identificador do lojista na configuração da API |
X-API-Key |
{api_key} |
Sim | Chave de API do ambiente selecionado |
X-Timestamp |
{unix_timestamp} |
Sim | Use o mesmo formato de timestamp do início do pagamento. |
X-Signature |
sha256={hmac} |
Sim | Assine timestamp.GET./api/v1/verify-payment/{trxId}. com o API Secret correspondente. O corpo bruto é vazio em requisições GET. |
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
trxId |
string | Sim | ZexosPay transaction ID returned by hosted checkout or IPN. |
curl -X GET "https://usepay.online/api/v1/verify-payment/TXNQ5V8K2L9N3XM1" \
-H "Accept: application/json" \
-H "X-Environment: sandbox" \
-H "X-Merchant-Key: test_merchant_key" \
-H "X-API-Key: test_api_key" \
-H "X-Timestamp: 1778650000" \
-H "X-Signature: sha256=generated_hmac_signature"
{
"status": "success",
"trx_id": "TXNQ5V8K2L9N3XM1",
"amount": 237.5,
"fee": 12.5,
"currency": "USD",
"net_amount": 237.5,
"customer": {
"name": "John Doe",
"email": "john@example.com"
},
"description": "Premium Subscription",
"created_at": "2026-05-13T10:30:00.000000Z",
"updated_at": "2026-05-13T10:35:45.000000Z"
}
| Status | Descrição | Ação recomendada |
|---|---|---|
pending |
O pagamento ainda está em processamento. | Aguarde o IPN ou verifique de novo mais tarde. |
success |
Pagamento concluído com sucesso. | Entregue o pedido depois das checagens de idempotência. |
failed |
O pagamento falhou ou foi cancelado. | Não entregue o pedido; mostre a opção de tentar de novo ou cancelar. |
curl -X GET "https://usepay.online/api/v1/verify-payment/TRXAB12CD34EF" \
-H "Accept: application/json" \
-H "X-Environment: production" \
-H "X-Merchant-Key: live_merchant_key" \
-H "X-API-Key: live_api_key" \
-H "X-Timestamp: 1778650000" \
-H "X-Signature: sha256=generated_hmac_signature"
<?php
use Illuminate\Support\Facades\Http;
$trxId = 'TRXAB12CD34EF';
$timestamp = (string) time();
$path = '/api/v1/verify-payment/'.$trxId;
$signature = hash_hmac(
'sha256',
$timestamp.'.GET.'.$path.'.', // GET has an empty body
config('services.zexospay.api_secret')
);
$response = Http::withHeaders([
'Accept' => 'application/json',
'X-Environment' => 'production',
'X-Merchant-Key' => config('services.zexospay.merchant_key'),
'X-API-Key' => config('services.zexospay.api_key'),
'X-Timestamp' => $timestamp,
'X-Signature' => 'sha256='.$signature,
])->get('https://usepay.online/api/v1/verify-payment/'.$trxId)
->throw()
->json();
// $response['status'], $response['refunded_amount'], $response['fully_refunded']
const crypto = require('crypto');
const trxId = 'TRXAB12CD34EF';
const timestamp = Math.floor(Date.now() / 1000).toString();
const path = `/api/v1/verify-payment/${trxId}`;
const signature = crypto
.createHmac('sha256', process.env.DIGIKASH_API_SECRET)
.update(`${timestamp}.GET.${path}.`) // GET has an empty body
.digest('hex');
const response = await fetch(`https://usepay.online/api/v1/verify-payment/${trxId}`, {
method: 'GET',
headers: {
'Accept': 'application/json',
'X-Environment': 'production',
'X-Merchant-Key': process.env.DIGIKASH_MERCHANT_KEY,
'X-API-Key': process.env.DIGIKASH_API_KEY,
'X-Timestamp': timestamp,
'X-Signature': `sha256=${signature}`
}
});
const data = await response.json();
Reembolse todo ou parte de um pagamento concluído. A carteira do lojista é debitada, uma transação de reembolso é registrada e seu endpoint de IPN é avisado.
https://usepay.online/api/v1/refund-payment
| Cabeçalho | Valor | Obrigatório | Descrição |
|---|---|---|---|
Accept |
application/json |
Sim | Tipo de resposta esperado |
X-Environment |
sandbox | production |
Sim | Deve ser o mesmo ambiente usado para iniciar o pagamento |
X-Merchant-Key |
{merchant_key} |
Sim | Identificador do lojista na configuração da API |
X-API-Key |
{api_key} |
Sim | Chave de API do ambiente selecionado |
X-Timestamp |
{unix_timestamp} |
Sim | Segundos Unix, usados na assinatura HMAC |
X-Signature |
{hmac_sha256} |
Sim | HMAC-SHA256 da requisição, assinado com seu segredo de API |
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
trx_id |
texto | Sim | O trx_id do pagamento concluído a reembolsar |
amount |
número | Não | Valor a reembolsar. Omita para reembolso total; envie um valor menor para reembolso parcial. Reembolsos parciais se acumulam e não podem passar do valor original. |
reason |
texto | Não | Motivo legível opcional salvo com o reembolso |
ref_refund |
texto | Não | Sua própria referência de reembolso. Se enviada, a mesma referência nunca reembolsa duas vezes (idempotente). |
curl -X POST "https://usepay.online/api/v1/refund-payment" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "X-Environment: production" \
-H "X-Merchant-Key: live_merchant_key" \
-H "X-API-Key: live_api_key" \
-H "X-Timestamp: 1778650000" \
-H "X-Signature: sha256=generated_hmac_signature" \
-d '{
"trx_id": "TRXAB12CD34EF",
"amount": 10.00,
"reason": "Customer returned item",
"ref_refund": "RFD-10231"
}'
<?php
use Illuminate\Support\Facades\Http;
// Omit "amount" for a full refund. Pass a unique "ref_refund" so a retry
// never refunds twice.
$payload = [
'trx_id' => 'TRXAB12CD34EF',
'amount' => 10.00,
'reason' => 'Customer returned item',
'ref_refund' => 'RFD-10231',
];
$body = json_encode($payload, JSON_THROW_ON_ERROR);
$timestamp = (string) time();
$path = '/api/v1/refund-payment';
$signature = hash_hmac(
'sha256',
$timestamp.'.POST.'.$path.'.'.$body,
config('services.zexospay.api_secret')
);
$response = Http::withHeaders([
'Content-Type' => 'application/json',
'Accept' => 'application/json',
'X-Environment' => 'production',
'X-Merchant-Key' => config('services.zexospay.merchant_key'),
'X-API-Key' => config('services.zexospay.api_key'),
'X-Timestamp' => $timestamp,
'X-Signature' => 'sha256='.$signature,
])->withBody($body, 'application/json')
->post('https://usepay.online/api/v1/refund-payment')
->throw()
->json();
// $response['refund_trx_id'], $response['remaining_refund'], $response['fully_refunded']
const crypto = require('crypto');
// Omit `amount` for a full refund. A unique `ref_refund` makes the call
// idempotent — the same reference never refunds twice.
const payload = {
trx_id: 'TRXAB12CD34EF',
amount: 10.00,
reason: 'Customer returned item',
ref_refund: 'RFD-10231'
};
const body = JSON.stringify(payload);
const timestamp = Math.floor(Date.now() / 1000).toString();
const path = '/api/v1/refund-payment';
const signature = crypto
.createHmac('sha256', process.env.DIGIKASH_API_SECRET)
.update(`${timestamp}.POST.${path}.${body}`)
.digest('hex');
const response = await fetch('https://usepay.online/api/v1/refund-payment', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
'X-Environment': 'production',
'X-Merchant-Key': process.env.DIGIKASH_MERCHANT_KEY,
'X-API-Key': process.env.DIGIKASH_API_KEY,
'X-Timestamp': timestamp,
'X-Signature': `sha256=${signature}`
},
body
});
const data = await response.json();
{
"status": "success",
"message": "Refund processed successfully.",
"refund_trx_id": "TRXZ9YX87WV65",
"original_trx_id": "TRXAB12CD34EF",
"refunded_amount": 10.00,
"total_refunded": 10.00,
"remaining_refund": 39.99,
"fully_refunded": false,
"currency": "USD"
}
Depois de um reembolso, seu ipn_url recebe um POST assinado. Confira o cabeçalho X-Signature (HMAC-SHA256 do corpo bruto, com seu segredo de API) antes de confiar nele.
{
"event": "payment.refunded",
"status": "refunded",
"data": {
"original_trx_id": "TRXAB12CD34EF",
"refund_trx_id": "TRXZ9YX87WV65",
"ref_trx": "ORDER-10231",
"ref_refund": "RFD-10231",
"refunded_amount": 10.00,
"total_refunded": 10.00,
"remaining_refund": 39.99,
"fully_refunded": false,
"currency": "USD"
},
"message": "Payment refunded.",
"timestamp": 1719750000
}
Busque a marca do gateway, os rótulos de ambiente e os metadados de checkout para uma integração autenticada de lojista.
https://usepay.online/api/v1/site-info
curl -X GET "https://usepay.online/api/v1/site-info" \
-H "Accept: application/json" \
-H "X-Environment: sandbox" \
-H "X-Merchant-Key: test_merchant_key" \
-H "X-API-Key: test_api_key" \
-H "X-Timestamp: 1778650000" \
-H "X-Signature: sha256=generated_hmac_signature"
{
"site_name": "ZexosPay",
"site_logo": "https://usepay.online/frontend/zexos/zexospay-logo-black.svg",
"site_url": "https://usepay.online",
"gateway_name": "ZexosPay Payment Gateway",
"gateway_description": "Secure payment powered by ZexosPay",
"features": {
"ssl_secured": "SSL Secured",
"instant_processing": "Instant",
"global_support": "Global",
"mobile_ready": "Mobile Ready"
},
"environments": {
"production": "Production Mode - Live payment processing is active",
"sandbox": "Test Mode - This is a test transaction. No real money will be charged"
},
"api_version": "1.0",
"status": "active"
}
Cobrança PIX direta (o copia e cola e o QR Code vêm na resposta, sem redirecionar o cliente), saque PIX pelo saldo, saldo, extrato e webhooks com novas tentativas. Feita para operações que recebem e pagam em volume: cassinos e apostas, SaaS, plataformas de infoproduto, plataformas de pagamento e cobrança.
| Método | Endereço | O que faz |
|---|---|---|
POST | /api/v1/pix/charges | Cria a cobrança e devolve o copia e cola e o QR Code. |
GET | /api/v1/pix/charges/{id} | Consulta a cobrança. ?qr_code=0 devolve sem a imagem (resposta menor). |
POST | /api/v1/pix/charges/{id}/simulate | Só no sandbox: aprova ({"status":"paid"}) ou recusa ({"status":"failed"}). |
POST | /api/v1/pix/payouts | Envia um PIX do seu saldo para uma chave PIX (saque). |
GET | /api/v1/pix/payouts/{id} | Consulta o saque. |
GET | /api/v1/balance | Saldo disponível e valor em saque. |
GET | /api/v1/statement | Extrato paginado de cobranças e saques. |
GET | /api/v1/webhooks | Registro das entregas de webhook. |
POST | /api/v1/webhooks/{id}/resend | Reenvia um webhook. |
Autenticação: os mesmos cabeçalhos assinados da API de pagamentos (X-Environment, X-Merchant-Key, X-API-Key, X-Timestamp, X-Signature). Veja Autenticação.
Idempotency-Key (seu id único da operação) em todo POST: repetir a chamada com a mesma chave devolve a mesma resposta, com o cabeçalho Idempotent-Replayed: true. Em saques a chave é obrigatória. Além disso, o ref_trx é único por ambiente: uma segunda cobrança ou saque com o mesmo ref_trx, enquanto o primeiro estiver pendente ou pago, recebe 409 duplicate_ref_trx com o id existente.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
amount | decimal | Sim | Valor em reais, até 2 casas (ex.: "49.90"). |
ref_trx | string | Sim | Seu código do pedido ou depósito (até 60 caracteres). |
customer.name | string | Sim | Nome de quem paga. |
customer.document | string | Sim | CPF ou CNPJ de quem paga (dígitos verificados). |
customer.email, customer.phone | string | Não | Contato de quem paga. |
description | string | Não | Descrição (até 255 caracteres). |
ipn_url | url | Não | Endereço HTTPS público que recebe os webhooks desta cobrança. |
metadata | objeto | Não | Até 20 pares chave/valor seus (ex.: player_id). Volta na consulta e no webhook. |
curl -X POST "https://usepay.online/api/v1/pix/charges" \
-H "Content-Type: application/json" -H "Accept: application/json" \
-H "X-Environment: sandbox" \
-H "X-Merchant-Key: test_merchant_key" -H "X-API-Key: test_api_key" \
-H "X-Timestamp: 1778650000" -H "X-Signature: sha256=generated_hmac_signature" \
-H "Idempotency-Key: dep-881-0001" \
-d '{
"amount": "49.90",
"ref_trx": "DEP-881-0001",
"description": "Depósito",
"ipn_url": "https://suaplataforma.com/webhooks/zexospay",
"customer": { "name": "Maria Souza", "document": "529.982.247-25" },
"metadata": { "player_id": "881" }
}'
{
"id": "TXNBTWKFCIAVYRD",
"object": "pix_charge",
"status": "pending",
"amount": "49.90",
"fee": "0.00",
"net_amount": "49.90",
"currency": "BRL",
"ref_trx": "DEP-881-0001",
"customer": { "name": "Maria Souza", "document": "52998224725", "email": null },
"pix": {
"copy_paste": "000201...6304AE19",
"qr_code_base64": "data:image/svg+xml;base64,..."
},
"payment_url": "https://usepay.online/pix/TXNBTWKFCIAVYRD",
"metadata": { "player_id": "881" },
"environment": "sandbox",
"refunded_amount": "0.00",
"created_at": "2026-10-04T07:56:51+00:00",
"paid_at": null
}Mostre ao cliente o pix.copy_paste e o pix.qr_code_base64 (pode ir direto num <img src>), ou mande-o para o payment_url, a página de pagamento pronta, que se atualiza sozinha. Situações: pending, paid, failed, canceled. No sandbox o copia e cola é marcado como teste e nenhum banco consegue pagá-lo: use /simulate.
Debita o valor (mais a taxa de saque, se houver) do seu saldo em reais e envia o PIX. Saques até o limite automático definido pela ZexosPay saem na hora; acima dele ficam in_review até a aprovação. Se o envio falhar ou o saque for recusado, o valor volta para o saldo.
403. A chave Idempotency-Key é obrigatória.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
amount | decimal | Sim | Valor em reais, até 2 casas. |
ref_trx | string | Sim | Seu código do saque. |
pix_key_type | string | Sim | cpf, cnpj, email, phone ou random. |
pix_key | string | Sim | A chave PIX de destino. |
recipient.name, recipient.document | string | Não | Nome e CPF/CNPJ de quem recebe. |
description, ipn_url, metadata | — | Não | Como na cobrança. |
curl -X POST "https://usepay.online/api/v1/pix/payouts" \
-H "Content-Type: application/json" -H "Accept: application/json" \
-H "X-Environment: production" \
-H "X-Merchant-Key: merchant_key" -H "X-API-Key: api_key" \
-H "X-Timestamp: 1778650000" -H "X-Signature: sha256=generated_hmac_signature" \
-H "Idempotency-Key: saq-881-0001" \
-d '{
"amount": "150.00",
"ref_trx": "SAQ-881-0001",
"pix_key_type": "cpf",
"pix_key": "529.982.247-25",
"recipient": { "name": "Maria Souza", "document": "52998224725" },
"ipn_url": "https://suaplataforma.com/webhooks/zexospay"
}'
{
"id": "TXNAHUVBRHNQ0XT",
"object": "pix_payout",
"status": "processing",
"amount": "150.00",
"fee": "0.00",
"total_debited": "150.00",
"currency": "BRL",
"ref_trx": "SAQ-881-0001",
"pix_key_type": "cpf",
"pix_key": "52998224725",
"recipient": { "name": "Maria Souza", "document": "52998224725" },
"review": "automatic",
"failure_reason": null,
"environment": "production",
"created_at": "2026-10-04T07:58:40+00:00"
}Situações: processing (enviado, aguardando o banco), in_review (aguardando aprovação), paid, failed (o valor voltou para o saldo; o motivo vem em failure_reason). No sandbox o saque é aprovado na hora e não mexe no saldo.
GET /api/v1/balance
{ "object": "balance", "environment": "production", "currency": "BRL", "available": "700.00", "in_payout": "300.00" }GET /api/v1/statement aceita type (payment ou payout), status (paid, pending, failed, canceled), from e to (datas), ref_trx, page e per_page (até 100). A resposta traz data, page, per_page, total e has_more.
| Evento | Quando |
|---|---|
payment.paid | Cobrança paga (PIX, cartão, cripto ou checkout). |
payment.failed | Cobrança recusada ou cancelada. |
payment.refunded | Estorno total ou parcial. |
payout.paid | Saque pago. |
payout.failed | Saque recusado ou com falha (valor devolvido ao saldo). |
Cada envio é um POST JSON para o seu ipn_url com os cabeçalhos X-Signature (HMAC-SHA256 do corpo bruto com o seu API Secret do ambiente), X-Environment, X-Webhook-Id, X-Webhook-Event e X-Webhook-Attempt. O corpo traz event, webhook_id, object (a cobrança ou o saque, no mesmo formato da consulta), status e timestamp.
Responda com qualquer código 2xx em até 10 segundos. Sem resposta 2xx, a ZexosPay tenta de novo depois de 1 min, 5 min, 15 min, 1 h, 3 h, 6 h e 12 h. Use o webhook_id para ignorar entregas repetidas. Você pode consultar o histórico em GET /api/v1/webhooks e reenviar com POST /api/v1/webhooks/{id}/resend.
// PHP: confira a assinatura antes de processar
$body = file_get_contents('php://input');
$expected = hash_hmac('sha256', $body, $apiSecret);
if (! hash_equals($expected, $_SERVER['HTTP_X_SIGNATURE'] ?? '')) {
http_response_code(401); exit;
}
$event = json_decode($body, true);
// ignore se $event['webhook_id'] já foi processado; depois credite/baixe pelo $event['object']['ref_trx']
http_response_code(200);// Node.js (Express): use o corpo bruto
app.post('/webhooks/zexospay', express.raw({ type: 'application/json' }), (req, res) => {
const expected = crypto.createHmac('sha256', process.env.ZEXOSPAY_API_SECRET).update(req.body).digest('hex');
const got = req.get('X-Signature') || '';
if (got.length !== expected.length || !crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(got))) return res.sendStatus(401);
const event = JSON.parse(req.body);
res.sendStatus(200);
});Os erros da API PIX vêm assim: {"status":"error","code":"insufficient_balance","message":"..."}.
| HTTP | code | Significado |
|---|---|---|
| 400 | idempotency_key_required | Saque sem Idempotency-Key. |
| 403 | ip_whitelist_empty, ip_not_authorized | IP não cadastrado para saques. |
| 403 | payout_disabled | Saque por API desligado na plataforma. |
| 403 | sandbox_only | /simulate fora do sandbox. |
| 404 | not_found | Cobrança, saque ou webhook inexistente neste ambiente. |
| 409 | duplicate_ref_trx | Já existe cobrança ou saque ativo com este ref_trx (vem o id). |
| 409 | idempotency_key_reused | Mesma Idempotency-Key com outros dados. |
| 422 | validation_error | Campo inválido (detalhes em errors). |
| 422 | invalid_pix_key, amount_out_of_range, insufficient_balance | Chave PIX inválida, valor fora dos limites ou saldo insuficiente. |
| 429 | — | Limite de requisições por minuto (veja Retry-After). |
| 502/503 | provider_error, pix_unavailable, payout_unavailable | Provedor indisponível. Pode repetir com a mesma Idempotency-Key. |
Divida cada cobrança entre você e até 10 contas ZexosPay — coprodutor, afiliado, parceiro, vendedor do seu marketplace. Quando a cobrança é paga, cada parte cai na carteira do recebedor na hora, junto com o seu crédito.
Funciona em POST /api/v1/pix/charges, POST /api/v1/card/payments e POST /api/v1/initiate-payment: envie o campo split junto com a cobrança.
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
split[].wallet | string | Sim | ID da carteira do recebedor (ex.: DK-BRL-AC58-9CDB). O recebedor vê o ID no painel dele. Precisa ser de outra conta, estar ativa e na mesma moeda da cobrança. |
split[].percent | decimal | Um dos dois | Percentual do valor da cobrança (até 2 casas, máximo 100). Arredonda para baixo no centavo. |
split[].amount | decimal | Um dos dois | Valor fixo na moeda da cobrança. |
split[].label | string | Não | Nome para você identificar (ex.: coprodutor, afiliado). |
split[].refund_liable | boolean | Não | Se o recebedor devolve a parte dele em estornos. Padrão: true. |
{
"amount": "100.00",
"ref_trx": "PEDIDO-1042",
"customer": { "name": "Maria Souza", "document": "529.982.247-25" },
"split": [
{ "wallet": "DK-BRL-AC58-9CDB", "percent": 30, "label": "coprodutor" },
{ "wallet": "DK-BRL-71E9-688E", "amount": "10.00", "label": "afiliado", "refund_liable": false }
]
}422 (invalid_split na API PIX) e a mensagem diz o limite.settled com "sandbox": true para você testar a integração.Em um estorno (total ou parcial), cada recebedor com refund_liable: true devolve a parte proporcional ao valor estornado. Exemplo: cobrança de R$ 100,00 com taxa de 2% (líquido R$ 98,00) e coprodutor com R$ 30,00; um estorno de R$ 49,00 (metade do líquido) traz R$ 15,00 do coprodutor de volta para você antes de debitar o estorno. Se o recebedor não tiver saldo, ele devolve o que tiver e a diferença fica registrada como shortfall (arcada por você). O resumo vem em split_reversal no webhook payment.refunded.
"split": {
"status": "settled",
"currency": "BRL",
"total": "40.00",
"sandbox": false,
"items": [
{ "wallet": "DK-BRL-AC58-9CDB", "label": "coprodutor", "amount": "30.00", "percent": "30.00",
"refund_liable": true, "reversed": "0.00", "shortfall": null },
{ "wallet": "DK-BRL-71E9-688E", "label": "afiliado", "amount": "10.00", "percent": null,
"refund_liable": false, "reversed": "0.00", "shortfall": null }
]
}Situações do split: pending (cobrança ainda não paga) e settled (repasse feito). No extrato de cada conta aparecem os lançamentos Split enviado, Split recebido e Estorno de split.
Uma cobrança que só aceita cartão de crédito ou débito. O link devolvido abre o checkout já no cartão, sem PIX, cripto ou carteira. Use quando o seu fluxo só trabalha com cartão (por exemplo, vendas internacionais).
payment_url. Não envie dados de cartão em nenhum campo.
| Método | Endereço | O que faz |
|---|---|---|
POST |
/api/v1/card/payments |
Cria a cobrança de cartão e devolve o payment_url. |
GET |
/api/v1/card/payments/{trxId} |
Consulta a situação da cobrança de cartão. |
POST |
/api/v1/card/refunds |
Estorna, total ou parcialmente, uma cobrança de cartão concluída. |
Os mesmos cabeçalhos da API de pagamentos: X-Environment, X-Merchant-Key, X-API-Key, X-Timestamp e X-Signature (HMAC-SHA256 de timestamp.MÉTODO.caminho.corpo com o API Secret do ambiente). Veja Autenticação.
Os mesmos campos de Iniciar pagamento:
| Parâmetro | Tipo | Obrigatório | Descrição |
|---|---|---|---|
payment_amount | decimal | Sim | Valor da cobrança. |
currency_code | string | Sim | Moeda da cobrança (ex.: BRL, USD). Precisa estar ativa na sua conta de lojista. |
ref_trx | string | Sim | O código do pedido no seu sistema. |
ipn_url | url | Sim | Endereço que recebe o aviso de pagamento (webhook). |
success_redirect | url | Sim | Para onde o cliente volta depois de pagar. |
cancel_redirect | url | Sim | Para onde o cliente volta se desistir ou se o pagamento for recusado. |
description | string | Não | Descrição mostrada no checkout. |
customer_name, customer_email | string | Não | Dados de quem paga. |
curl -X POST "https://usepay.online/api/v1/card/payments" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "X-Environment: sandbox" \
-H "X-Merchant-Key: test_merchant_key" \
-H "X-API-Key: test_api_key" \
-H "X-Timestamp: 1778650000" \
-H "X-Signature: sha256=generated_hmac_signature" \
-d '{
"payment_amount": "99.90",
"currency_code": "BRL",
"ref_trx": "PEDIDO-1042",
"description": "Pedido #1042",
"ipn_url": "https://sualoja.com/webhooks/zexospay",
"success_redirect": "https://sualoja.com/obrigado",
"cancel_redirect": "https://sualoja.com/carrinho",
"customer_name": "Ana Lima",
"customer_email": "ana@exemplo.com"
}'
{
"payment_url": "https://usepay.online/payment/checkout?expires=...&token=...&signature=...",
"trx_id": "TXNEKJXWKKHOLVX",
"channel": "card",
"info": { "ref_trx": "PEDIDO-1042", "amount": "99.90", "currency_code": "BRL", "channel": "card", "...": "..." },
"fee": 0,
"net_amount": 99.9
}
{
"error": "Card payments are not available for this currency right now.",
"code": "card_unavailable"
}
GET /api/v1/card/payments/{trxId} devolve o mesmo formato de Verificar pagamento, com "channel": "card". POST /api/v1/card/refunds recebe o mesmo corpo de Estornar pagamento (trx_id, amount opcional para estorno parcial, reason, ref_refund). Os dois só enxergam cobranças criadas pela API de cartão; para as demais use os endpoints normais.
O estorno debita o valor do seu saldo na ZexosPay e avisa o seu ipn_url. A devolução do dinheiro ao cartão do cliente é feita pela ZexosPay junto ao processador do cartão em que a compra foi paga.
A cobrança fica na moeda que você escolheu e você recebe esse valor. Se o processador de cartão disponível cobra em outra moeda, o checkout mostra ao cliente o valor convertido e a cotação antes de pagar.
X-Environment: sandbox, o pagamento é aprovado automaticamente ao clicar em pagar no checkout — nenhum cartão é cobrado.
Crie, consulte, cancele e renove assinaturas externas por endpoints próprios da API de lojista. A ZexosPay guarda o agendamento, gera as faturas hospedadas e avança a assinatura depois do pagamento confirmado.
Os planos da plataforma ZexosPay podem renovar automaticamente pela carteira do usuário quando o agendador do servidor está rodando. Testes grátis, carência, cancelamentos, trocas de plano, transações e faturas são tratados dentro da ZexosPay.
A ZexosPay guarda a referência externa, o valor, o ciclo, a próxima cobrança, o status e as faturas. Os endpoints restritos ao lojista mostram o estado atual sem expor outro lojista ou ambiente.
Envie ou mostre a payment_url da fatura. A ZexosPay ativa ou estende a assinatura só depois do pagamento; sua aplicação ainda deve verificar o IPN assinado de conclusão antes de liberar o próprio acesso.
| Método | Endpoint | Finalidade |
|---|---|---|
| POST | /api/v1/subscriptions |
Crie uma assinatura e a primeira fatura, ou agende para começar no futuro. |
| GET | /api/v1/subscriptions |
Liste as assinaturas do lojista autenticado no ambiente selecionado. |
| GET | /api/v1/subscriptions/{subscriptionId} |
Consulte o status atual e as 20 últimas faturas. |
| POST | /api/v1/subscriptions/{subscriptionId}/cancel |
Cancela no fim do período por padrão, ou na hora com at_period_end=false. |
| POST | /api/v1/subscriptions/{subscriptionId}/renew |
Crie ou recupere um checkout de renovação vencido. Assinaturas ativas não podem renovar antes da hora. |
| Cabeçalho | Obrigatório | Descrição |
|---|---|---|
X-Merchant-Key / X-API-Key |
Sim | Use as credenciais do ambiente selecionado (sandbox ou produção). |
X-Environment |
Recomendado | production ou sandbox. O padrão é produção. |
X-Timestamp / X-Signature |
Sim | Autenticação HMAC-SHA256 descrita na seção Autenticação. |
Idempotency-Key |
Altamente recomendado | Um UUID ou outro valor único, de até 255 caracteres. Repetir a mesma requisição em até 24 horas retorna a resposta original com Idempotent-Replayed: true. Reusar a chave com parâmetros diferentes retorna 409. |
| Campo | Obrigatório | Regras |
|---|---|---|
external_reference | Sim | Única por lojista e ambiente; máximo de 100 caracteres. |
billing_cycle | Sim | daily, weekly, monthly, half_yearly, ou yearly. |
payment_amount | Sim | Número de pelo menos 1 na moeda selecionada. |
currency_code | Sim | Uma moeda ativada para este lojista. |
customer_email | Sim | E-mail válido; máximo de 150 caracteres. |
success_redirect, cancel_redirect, ipn_url | Sim | URLs absolutas com no máximo 255 caracteres. O ipn_url precisa usar HTTPS e apontar para um endereço público; redirecionamentos e destinos privados/internos são bloqueados. |
customer_name, description | Não | Contexto para o cliente na fatura hospedada. |
starts_at | Não | Data e hora ISO 8601. Omita para checkout imediato; datas de início no passado são recusadas. |
allow_payment_methods | Não | Um código de método, códigos separados por vírgula ou uma lista de códigos ativos. |
metadata | Não | Objeto JSON com no máximo 50 entradas de primeiro nível. Não guarde segredos nem dados de cartão. |
| Status | Significado | Ação do lojista |
|---|---|---|
pending | A primeira fatura não foi paga ou a data de início ainda não chegou. | Abra latest_invoice.payment_url quando estiver disponível. |
active | O período atual tem um pagamento concluído e verificado. | Libere o acesso só até current_period_end. |
past_due | O período pago terminou ou a renovação falhou e o pagamento ainda é necessário. | Entregue o checkout pendente ou chame o endpoint de renovação depois de falha ou expiração. |
cancelled | Nenhuma outra fatura será gerada. | Crie uma nova assinatura para voltar a cobrar. |
Faça POST com cliente, valor, ciclo de cobrança, retornos e sua external_reference única.
Abra latest_invoice.payment_url para o cliente autorizar o primeiro checkout.
Verifique o IPN de conclusão. A ZexosPay marca a fatura como paga, ativa o acesso e define next_billing_at.
O agendador cria as faturas vencidas. Consulte a assinatura com GET e entregue ao cliente a payment_url da nova fatura pendente.
Este exemplo de servidor cria uma assinatura mensal, assina exatamente o corpo JSON bruto, chama a ZexosPay e redireciona o cliente para a primeira fatura.
<?php
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Str;
$path = '/api/v1/subscriptions';
$payload = [
'external_reference' => 'CUSTOMER-PRO-1042',
'billing_cycle' => 'monthly',
'currency_code' => 'USD',
'payment_amount' => 29.00,
'description' => 'Pro plan monthly subscription',
'customer_name' => 'Jane Doe',
'customer_email' => 'jane@example.com',
'success_redirect' => 'https://merchant.example/billing/success',
'cancel_redirect' => 'https://merchant.example/billing/cancel',
'ipn_url' => 'https://merchant.example/webhooks/zexospay',
];
$body = json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_THROW_ON_ERROR);
$timestamp = (string) time();
$idempotencyKey = (string) Str::uuid(); // Persist this key until the request succeeds.
$signaturePayload = implode('.', [$timestamp, 'POST', $path, $body]);
$signature = hash_hmac(
'sha256',
$signaturePayload,
config('services.zexospay.api_secret'),
);
$checkout = Http::withHeaders([
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'X-Environment' => 'production',
'X-Merchant-Key' => config('services.zexospay.merchant_key'),
'X-API-Key' => config('services.zexospay.api_key'),
'X-Timestamp' => $timestamp,
'X-Signature' => 'sha256='.$signature,
'Idempotency-Key' => $idempotencyKey,
])->withBody($body, 'application/json')
->post('https://usepay.online'.$path)
->throw()
->json();
// Save the subscription ID and open the first hosted invoice.
$subscription = $checkout['data'];
return redirect()->away($subscription['latest_invoice']['payment_url']);
{
"data": {
"id": "2bbcf684-3156-43ac-a06d-a5c641641eef",
"external_reference": "CUSTOMER-PRO-1042",
"environment": "production",
"status": "pending",
"billing_cycle": "monthly",
"amount": "29.00000000",
"currency_code": "USD",
"next_billing_at": "2026-08-13T06:00:00+00:00",
"latest_invoice": {
"id": "cbf09fac-c188-4219-ac66-e114a7b48dc5",
"reference": "MSI-2BBCF684315643AC-1",
"sequence": 1,
"status": "pending",
"payment_url": "https://ZexosPay.example/payment/checkout?token=encrypted&signature=signed",
"checkout_expires_at": "2026-08-13T21:00:00+00:00"
}
}
}
# List, 1-100 records per page. Sign the complete path including the query string.
GET /api/v1/subscriptions?per_page=20&page=1
# Retrieve one subscription and its latest 20 invoices.
GET /api/v1/subscriptions/{subscriptionId}
# Cancel at the end of the paid period (default).
POST /api/v1/subscriptions/{subscriptionId}/cancel
Idempotency-Key: 63632250-3170-421f-8021-9d0a730e90aa
{"at_period_end":true}
# Cancel immediately and invalidate every pending hosted invoice.
POST /api/v1/subscriptions/{subscriptionId}/cancel
Idempotency-Key: a2ce7c46-4bb8-4675-8c45-58f2eed6ff84
{"at_period_end":false}
# Recover a due, failed, or expired renewal checkout.
POST /api/v1/subscriptions/{subscriptionId}/renew
Idempotency-Key: 890508df-f54c-4ec0-a603-e4f5da2a8206
{"force_new":false}
| Status | Significado | O que fazer |
|---|---|---|
200 | Consulta, cancelamento ou renovação concluídos. | Use o recurso retornado como fonte da verdade. |
201 | Assinatura criada, inclusive na repetição da resposta original de criação. | Guarde data.id e a Idempotency-Key. |
401 / 403 | Credenciais, assinatura, ambiente ou status do lojista inválidos. | Corrija a autenticação; não tente de novo às cegas. |
404 | A assinatura não existe neste lojista/ambiente. | Confira o ID e o X-Environment. |
409 | Conflito de referência, mudança de status inválida, chave de idempotência reutilizada ou uma requisição idêntica ainda em execução. | Leia a mensagem; respeite o Retry-After quando houver. |
422 | A validação dos dados ou da configuração de pagamento falhou. | Corrija os campos antes de tentar de novo. |
429 | Limite de requisições da API de lojista excedido. | Aguarde o Retry-After e tente de novo com espera exponencial. |
503 | Falha temporária ao criar o checkout. | Repita o mesmo POST com a mesma Idempotency-Key. |
ZexosPay sends real-time notifications to your specified IPN URL when payment status changes. This ensures you're immediately notified of payment completions, failures, and other status updates. Os webhooks funcionam igual no sandbox e na produção.
Use the same webhook URL for both sandbox and production. ZexosPay will include environment context in webhook payloads to help you differentiate between test and live transactions.
| Cabeçalho | Descrição | Exemplo |
|---|---|---|
Content-Type |
Sempre application/json |
application/json |
X-Signature |
Assinatura HMAC-SHA256 bruta para verificação | a8b9c2d1e5f3... |
X-Environment |
Contexto de ambiente do webhook | sandbox | production |
Todos os webhooks trazem a informação de ambiente para você diferenciar transações de sandbox e de produção:
environment o campo será sandbox para transações de teste ou production para transações reais. Os IDs de transação recebem o prefixo correspondente (SANDBOX_ ou PRODUCTION_).
{
"data": {
"ref_trx": "TXNT4AQFESTAG4F",
"description": "Order #1234",
"ipn_url": "https://webhook.site/5711b7d5-917a-4d94-bbb3-c28f4a37bea5",
"cancel_redirect": "https://merchant.com/cancel",
"success_redirect": "https://merchant.com/success",
"customer_name": "John Doe",
"customer_email": "john@example.com",
"merchant_name": "Xanthus Wiggins",
"amount": 200,
"currency_code": "USD",
"environment": "production",
"is_sandbox": false
},
"message": "Pagamento concluído",
"status": "concluído",
"timestamp": 1705747245
}
Sempre verifique a assinatura dos webhooks para garantir a autenticidade e evitar requisições não autorizadas. Use seu segredo de API (do ambiente correspondente) para verificar:
test_webhook_secret para sandbox e webhook_secret para ambientes de produção.
<?php
// Handler de webhook em Laravel
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use App\Enums\EnvironmentMode;
class ZexosPayWebhookController extends Controller
{
public function handle(Request $request)
{
// Pegue os cabeçalhos do webhook
$environment = $request->header('X-Environment', 'production');
$signature = $request->header('X-Signature');
// Pegue o segredo correto conforme o ambiente
$secret = $this->getSecretForEnvironment($environment);
// Verificar assinatura
if (!$this->verifySignature($request->getContent(), $signature, $secret)) {
Log::warning('ZexosPay webhook signature verification failed', [
'environment' => $environment
]);
return response()->json(['error' => 'Assinatura inválida'], 401);
}
$payload = $request->json()->all();
// Trate conforme o ambiente
if ($environment === EnvironmentMode::SANDBOX->value) {
return $this->handleSandboxWebhook($payload);
} else {
return $this->handleProductionWebhook($payload);
}
}
private function getSecretForEnvironment(string $environment): string
{
// Retorne o segredo de teste no sandbox e o segredo real em produção
return $environment === 'sandbox'
? config('zexospay.test_webhook_secret')
: config('zexospay.webhook_secret');
}
private function verifySignature(string $payload, string $signature, string $secret): bool
{
$expectedSignature = hash_hmac('sha256', $payload, $secret);
$providedSignature = str_starts_with($signature, 'sha256=') ? substr($signature, 7) : $signature;
return hash_equals($expectedSignature, $providedSignature);
}
private function handleSandboxWebhook(array $payload): JsonResponse
{
Log::info('Processando webhook de sandbox', $payload);
// Sua lógica de sandbox aqui
// Não entregue pedidos, não mande e-mails para clientes reais etc.
return response()->json(['status' => 'sandbox_processado']);
}
private function handleProductionWebhook(array $payload): JsonResponse
{
Log::info('Processando webhook de produção', $payload);
// Sua lógica de produção aqui
// Entregue pedidos, mande e-mails de confirmação etc.
return response()->json(['status' => 'processado']);
}
}
const crypto = require('crypto');
const express = require('express');
const EnvironmentMode = {
SANDBOX: 'sandbox',
PRODUCTION: 'production'
};
// Handler do webhook
app.post('/api/webhooks/zexospay', async (req, res) => {
const environment = req.headers['x-environment'] || 'production';
const signature = req.headers['x-signature'];
# Pegue o segredo correto conforme o ambiente
const secret = getSecretForEnvironment(environment);
# Verificar assinatura
if (!verifySignature(JSON.stringify(req.body), signature, secret)) {
console.warn('ZexosPay webhook signature verification failed', {
environment: environment
});
return res.status(401).json({ error: 'Assinatura inválida' });
}
const payload = req.body;
try {
# Trate conforme o ambiente
if (environment === EnvironmentMode.SANDBOX) {
await handleSandboxWebhook(payload);
} else {
await handleProductionWebhook(payload);
}
res.json({ status: 'processado' });
} catch (error) {
console.error('Erro ao processar o webhook:', error);
res.status(500).json({ error: 'O processamento falhou' });
}
});
function getSecretForEnvironment(environment) {
# Retorne o segredo de teste no sandbox e o segredo real em produção
return environment === 'sandbox'
? process.env.ZEXOSPAY_TEST_WEBHOOK_SECRET
: process.env.ZEXOSPAY_WEBHOOK_SECRET;
}
function verifySignature(payload, signature, secret) {
if (!signature) {
return false;
}
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
const providedSignature = signature.startsWith('sha256=') ? signature.slice(7) : signature;
return crypto.timingSafeEqual(
Buffer.from(expectedSignature),
Buffer.from(providedSignature)
);
}
async function handleSandboxWebhook(payload) {
console.log('Processando webhook de sandbox:', payload);
# Sua lógica de sandbox aqui
# Não entregue pedidos, não mande e-mails para clientes reais etc.
}
async function handleProductionWebhook(payload) {
console.log('Processando webhook de produção:', payload);
# Sua lógica de produção aqui
# Entregue pedidos, mande e-mails de confirmação etc.
}
import hmac
import hashlib
import json
import logging
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
logger = logging.getLogger(__name__)
ENVIRONMENT_MODE = {
'SANDBOX': 'sandbox',
'PRODUCTION': 'production'
}
@csrf_exempt
@require_http_methods(["POST"])
def zexospay_webhook(request):
environment = request.headers.get('X-Environment', 'production')
signature = request.headers.get('X-Signature', '')
# Pegue o segredo correto conforme o ambiente
secret = get_secret_for_environment(environment)
# Verificar assinatura
if not verify_signature(request.body, signature, secret):
logger.warning('ZexosPay webhook signature verification failed', extra={
'environment': environment
})
return JsonResponse({'error': 'Assinatura inválida'}, status=401)
try:
payload = json.loads(request.body)
# Trate conforme o ambiente
if environment == ENVIRONMENT_MODE['SANDBOX']:
handle_sandbox_webhook(payload)
else:
handle_production_webhook(payload)
return JsonResponse({'status': 'processado'})
except Exception as e:
logger.error(f'Erro ao processar o webhook:{str(e)}')
return JsonResponse({'error': 'O processamento falhou'}, status=500)
def get_secret_for_environment(environment):
from django.conf import settings
# Retorne o segredo de teste no sandbox e o segredo real em produção
return (settings.ZEXOSPAY_TEST_WEBHOOK_SECRET
if environment == 'sandbox'
else settings.ZEXOSPAY_WEBHOOK_SECRET)
def verify_signature(payload, signature, secret):
if not signature:
return False
expected_signature = hmac.new(
secret.encode('utf-8'),
payload,
hashlib.sha256
).hexdigest()
provided_signature = signature[7:] if signature.startswith('sha256=') else signature
return hmac.compare_digest(expected_signature, provided_signature)
def handle_sandbox_webhook(payload):
logger.info('Processando webhook de sandbox', extra=payload)
# Sua lógica de sandbox aqui
# Não entregue pedidos, não mande e-mails para clientes reais etc.
def handle_production_webhook(payload):
logger.info('Processando webhook de produção', extra=payload)
# Sua lógica de produção aqui
# Entregue pedidos, mande e-mails de confirmação etc.
Exemplos de integração prontos para produção nas plataformas e frameworks mais usados. Deixe a escolha de gateways na configuração da API e assine cada requisição no seu servidor.
<?php
// Laravel Integration Service
namespace App\Services;
use Illuminate\Support\Facades\Http;
use Exception;
class ZexosPayService
{
private string $baseUrl;
private string $merchantKey;
private string $apiKey;
private string $environment;
public function __construct()
{
$this->baseUrl = config('zexospay.base_url');
$this->merchantKey = config('zexospay.merchant_key');
$this->apiKey = config('zexospay.api_key');
$this->environment = config('zexospay.environment'); // 'sandbox' or 'production'
}
public function initiatePayment(array $paymentData): array
{
try {
$response = Http::withHeaders([
'Content-Type' => 'application/json',
'X-Environment' => $this->environment,
'X-Merchant-Key' => $this->merchantKey,
'X-API-Key' => $this->apiKey,
])->post("{$this->baseUrl}/api/v1/initiate-payment", $paymentData);
if ($response->successful()) {
return $response->json();
}
throw new Exception('ZexosPay API Error: Payment initiation failed');
} catch (Exception $e) {
throw new Exception('ZexosPay API Error: ' . $e->getMessage());
}
}
public function verifyPayment(string $transactionId): array
{
try {
$response = Http::withHeaders([
'Accept' => 'application/json',
'X-Environment' => $this->environment,
'X-Merchant-Key' => $this->merchantKey,
'X-API-Key' => $this->apiKey,
])->get("{$this->baseUrl}/api/v1/verify-payment/{$transactionId}");
if ($response->successful()) {
return $response->json();
}
throw new Exception('ZexosPay API Error: Payment verification failed');
} catch (Exception $e) {
throw new Exception('ZexosPay API Error: ' . $e->getMessage());
}
}
}
// Configuration (config/zexospay.php)
return [
'base_url' => env('ZEXOSPAY_BASE_URL', 'https://usepay.online'),
'environment' => env('ZEXOSPAY_ENVIRONMENT', 'sandbox'), // sandbox or production
'merchant_key' => env('ZEXOSPAY_MERCHANT_KEY'), // Use appropriate prefix
'api_key' => env('ZEXOSPAY_API_KEY'), // Use appropriate prefix
];
// Usage in Controller
class PaymentController extends Controller
{
public function initiatePayment(Request $request, ZexosPayService $zexospay)
{
$paymentData = [
'payment_amount' => $request->amount,
'currency_code' => 'USD',
'ref_trx' => 'ORDER_' . time(),
'description' => $request->description,
'success_redirect' => route('payment.success'),
'cancel_redirect' => route('payment.cancelled'),
'ipn_url' => route('webhooks.zexospay'),
'allow_payment_methods' => ['stripe', 'paypal'],
];
try {
$result = $zexospay->initiatePayment($paymentData);
return redirect($result['payment_url']);
} catch (Exception $e) {
return back()->withErrors(['error' => $e->getMessage()]);
}
}
}
// Node.js Integration Service
const axios = require('axios');
class ZexosPayService {
constructor() {
this.baseUrl = process.env.ZEXOSPAY_BASE_URL || 'https://usepay.online';
this.environment = process.env.ZEXOSPAY_ENVIRONMENT || 'sandbox'; // sandbox or production
this.merchantKey = process.env.ZEXOSPAY_MERCHANT_KEY; // Use appropriate prefix
this.apiKey = process.env.ZEXOSPAY_API_KEY; // Use appropriate prefix
}
async initiatePayment(paymentData) {
try {
const response = await axios.post(`${this.baseUrl}/api/v1/initiate-payment`, paymentData, {
headers: {
'Content-Type': 'application/json',
'X-Environment': this.environment,
'X-Merchant-Key': this.merchantKey,
'X-API-Key': this.apiKey
}
});
return response.data;
} catch (error) {
throw new Error(`ZexosPay API Error: ${error.message}`);
}
}
async verifyPayment(transactionId) {
try {
const response = await axios.get(`${this.baseUrl}/api/v1/verify-payment/${transactionId}`, {
headers: {
'Accept': 'application/json',
'X-Environment': this.environment,
'X-Merchant-Key': this.merchantKey,
'X-API-Key': this.apiKey
}
});
return response.data;
} catch (error) {
throw new Error(`ZexosPay API Error: ${error.message}`);
}
}
}
// Express.js Route Example
const express = require('express');
const app = express();
const zexospay = new ZexosPayService();
app.post('/initiate-payment', async (req, res) => {
const paymentData = {
payment_amount: req.body.amount,
currency_code: 'USD',
ref_trx: `ORDER_${Date.now()}`,
description: req.body.description,
success_redirect: `${req.protocol}://${req.get('host')}/payment/success`,
cancel_redirect: `${req.protocol}://${req.get('host')}/payment/cancelled`,
ipn_url: `${req.protocol}://${req.get('host')}/webhooks/zexospay`,
allow_payment_methods: ['stripe', 'paypal'],
};
try {
const result = await zexospay.initiatePayment(paymentData);
res.redirect(result.payment_url);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
module.exports = ZexosPayService;
# Python/Django Integration Service
import os
import requests
from django.conf import settings
class ZexosPayService:
def __init__(self):
self.base_url = getattr(settings, 'ZEXOSPAY_BASE_URL', 'https://usepay.online')
self.environment = getattr(settings, 'ZEXOSPAY_ENVIRONMENT', 'sandbox') # sandbox or production
self.merchant_key = getattr(settings, 'ZEXOSPAY_MERCHANT_KEY') # Use appropriate prefix
self.api_key = getattr(settings, 'ZEXOSPAY_API_KEY') # Use appropriate prefix
def initiate_payment(self, payment_data):
try:
headers = {
'Content-Type': 'application/json',
'X-Environment': self.environment,
'X-Merchant-Key': self.merchant_key,
'X-API-Key': self.api_key
}
response = requests.post(
f"{self.base_url}/api/v1/initiate-payment",
headers=headers,
json=payment_data,
timeout=30
)
response.raise_for_status()
return response.json()
except requests.RequestException as e:
raise Exception(f'ZexosPay API Error: {str(e)}')
def verify_payment(self, transaction_id):
try:
headers = {
'Accept': 'application/json',
'X-Environment': self.environment,
'X-Merchant-Key': self.merchant_key,
'X-API-Key': self.api_key
}
response = requests.get(
f"{self.base_url}/api/v1/verify-payment/{transaction_id}",
headers=headers,
timeout=30
)
response.raise_for_status()
return response.json()
except requests.RequestException as e:
raise Exception(f'ZexosPay API Error: {str(e)}')
# Django Settings Configuration
ZEXOSPAY_BASE_URL = 'https://usepay.online'
ZEXOSPAY_ENVIRONMENT = 'sandbox' # Change to 'production' for live
ZEXOSPAY_MERCHANT_KEY = os.environ.get('ZEXOSPAY_MERCHANT_KEY') # Use appropriate prefix
ZEXOSPAY_API_KEY = os.environ.get('ZEXOSPAY_API_KEY') # Use appropriate prefix
# Django View Example
from django.shortcuts import redirect
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
import json
zexospay = ZexosPayService()
@csrf_exempt
def initiate_payment(request):
if request.method == 'POST':
data = json.loads(request.body)
payment_data = {
'payment_amount': data['amount'],
'currency_code': 'USD',
'ref_trx': f'ORDER_{int(time.time())}',
'description': data['description'],
'success_redirect': request.build_absolute_uri('/payment/success/'),
'cancel_redirect': request.build_absolute_uri('/payment/cancelled/'),
'ipn_url': request.build_absolute_uri('/webhooks/zexospay/'),
'allow_payment_methods': ['stripe', 'paypal'],
}
try:
result = zexospay.initiate_payment(payment_data)
return redirect(result['payment_url'])
except Exception as e:
return JsonResponse({'error': str(e)}, status=500)
# Environment Variables Setup
export ZEXOSPAY_ENVIRONMENT="sandbox" # or "production"
export ZEXOSPAY_MERCHANT_KEY="test_merchant_your_key" # or "merchant_your_key" for production
export ZEXOSPAY_API_KEY="test_your_api_key" # or "your_api_key" for production
# Initiate Payment
curl -X POST "https://usepay.online/api/v1/initiate-payment" \
-H "Content-Type: application/json" \
-H "X-Environment: $ZEXOSPAY_ENVIRONMENT" \
-H "X-Merchant-Key: $ZEXOSPAY_MERCHANT_KEY" \
-H "X-API-Key: $ZEXOSPAY_API_KEY" \
-d '{
"payment_amount": 250.00,
"currency_code": "USD",
"ref_trx": "ORDER_12345",
"description": "Premium Subscription",
"success_redirect": "https://yoursite.com/payment/success",
"cancel_redirect": "https://yoursite.com/payment/cancelled",
"ipn_url": "https://yoursite.com/api/webhooks/zexospay",
"allow_payment_methods": ["stripe", "paypal"]
}'
# Verify Payment
curl -X GET "https://usepay.online/api/v1/verify-payment/TXNQ5V8K2L9N3XM1" \
-H "Accept: application/json" \
-H "X-Environment: $ZEXOSPAY_ENVIRONMENT" \
-H "X-Merchant-Key: $ZEXOSPAY_MERCHANT_KEY" \
-H "X-API-Key: $ZEXOSPAY_API_KEY"
# Environment-specific credential examples:
# Sandbox: test_merchant_xxxxx, test_api_key_xxxxx
# Production: merchant_xxxxx, api_key_xxxxx
Advanced ZexosPay payment gateway with modern WooCommerce Blocks support, dynamic branding, and enterprise-grade security features.
Production-ready payment gateway with WooCommerce Blocks (Gutenberg) support, dynamic branding, and secure webhook processing.
Enterprise-grade WooCommerce payment gateway with modern Blocks support and dynamic branding.
Enterprise-grade payment processing with modern architecture
Full Gutenberg checkout compatibility with React-based UI
Auto-fetch logo, colors, and branding from ZexosPay API
HMAC-SHA256 signature verification for payment callbacks
Space-efficient, responsive design for all devices
Multi-header authentication with environment isolation
Seamless sandbox testing with production deployment
Comece a integração ZexosPay com WooCommerce em minutos
Download ZexosPay WooCommerce Gateway v2.8.0 from the download section above. This includes all latest features and security updates.
Navigate to Plugins → Add New → Upload Plugin and select the downloaded ZIP file. The plugin will auto-extract and install.
Activate the plugin and go to WooCommerce → Settings → Payments → ZexosPay. Enter your API credentials and webhook secret.
Enable Test Mode, process a sandbox transaction to verify Blocks checkout, webhook delivery, and order completion.
Disable test mode, ensure production API keys are configured, and start accepting real payments with full webhook processing.
Configurações essenciais da API para processar pagamentos com segurança
https://usepay.online
Your unique merchant credentials from ZexosPay dashboard
RequiredHMAC-SHA256 signature verification for secure callbacks
RecommendedCabeçalhos obrigatórios em todas as requisições da API ZexosPay:
X-Environment: sandbox|production
X-Merchant-Key: your_merchant_id
X-API-Key: your_api_key
Content-Type: application/json
Status do pagamento e processamento do pedido em tempo real
https://yoursite.com/wc-api/zexospay_webhook
Configure this URL in your ZexosPay merchant dashboard for automatic order updates.
Checkout Gutenberg moderno com interface de pagamento em React
Compact, mobile-optimized payment interface that adapts to any screen size.
Automatically fetches and displays your ZexosPay branding and logos.
Clear SSL and security badges to build customer trust during checkout.
Clear sandbox indicators for testing without affecting live transactions.
Confira se está tudo configurado antes de ir ao ar
Problemas comuns e soluções da integração ZexosPay com WooCommerce
Solutions:
Solutions:
Solutions:
Use este checklist antes de passar dos pagamentos de teste para o checkout real. As mesmas rotas funcionam nos dois modos; só mudam o cabeçalho de ambiente e as credenciais.
Use as credenciais de teste e X-Environment: sandbox. As transações ficam marcadas como sandbox e não movimentam dinheiro real.
Use as credenciais de produção e X-Environment: production só depois da aprovação do administrador, das carteiras prontas e dos gateways configurados.
Testar ZexosPay endpoints da API direto desta documentação. Use as credenciais de demonstração abaixo para testar no sandbox.
Use estas credenciais de demonstração para testar todos os métodos de pagamento no sandbox:
123456789
PIN da carteira:
123456
TESTVOUCHER
Sucesso automático
X-ENVIRONMENT: sandbox nas suas requisiçõessandbox para testes e production para transações reais. Só as credenciais de sandbox usam test_ como prefixo; as credenciais de produção não têm prefixo.
URL base: https://usepay.online
Cabeçalho de ambiente: X-Environment: sandbox
Credenciais: Usar test_ chaves com prefixo
Finalidade: Testes seguros sem dinheiro real
URL base: https://usepay.online
Cabeçalho de ambiente: X-Environment: production
Credenciais: Sem prefixo nas chaves de produção
Finalidade: Transações reais com dinheiro de verdade
ZexosPay A API usa códigos HTTP convencionais para indicar sucesso ou falha das requisições.
| Código | Status | Descrição |
|---|---|---|
| 200 | OK | Requisição bem-sucedida |
| 400 | Requisição inválida | Parâmetros da requisição inválidos |
| 401 | Não autorizado | Credenciais de API inválidas ou ausentes |
| 403 | Proibido | Permissões insuficientes |
| 404 | Não encontrado | Recurso não encontrado |
| 429 | Requisições demais | Limite de requisições excedido |
| 500 | Erro interno do servidor | Ocorreu um erro no servidor |
| Código de erro | Descrição | Solução |
|---|---|---|
INVALID_CREDENTIALS |
Credenciais de API inválidas | Confira seu ID de lojista e sua chave de API |
INSUFFICIENT_FUNDS |
O cliente não tem saldo suficiente | O cliente precisa adicionar saldo na carteira |
PAYMENT_DECLINED |
O pagamento foi recusado pelo processador | O cliente deve tentar outro método de pagamento |
INVALID_AMOUNT |
O valor do pagamento é inválido | Confira os limites mínimo e máximo de valor |
INVALID_CURRENCY |
Código de moeda não aceito | Use um código de moeda aceito (BRL, USD, EUR etc.) |
DUPLICATE_REFERENCE |
A referência da transação já existe | Use uma referência de transação única |
EXPIRED_SESSION |
A sessão de pagamento expirou | Crie um novo pedido de pagamento |
MERCHANT_SUSPENDED |
A conta de lojista está suspensa | Contato ZexosPay suporte |
{
"success": false,
"message": "Validation failed",
"error_code": "INVALID_AMOUNT",
"errors": {
"payment_amount": [
"The payment amount must be at least 1.00"
]
},
"timestamp": "2024-01-20T10:30:00Z"
}
Precisa de ajuda com a integração da API ZexosPay? Nossa equipe técnica dá suporte.