Referência da API de lojista

ZexosPay API de lojista

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.

Pronto para produção
POST /api/v1/initiate-payment
GET /api/v1/verify-payment/{trxId}
Sandbox Várias moedas API assinada Trava de gateway
Fluxo atual do lojista Os gateways agora são configurados depois de gerar a API, na página de configuração da API do lojista. O checkout só mostra gateways que correspondem à moeda do lojista e à carteira de recebimento ativa.

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.

Moeda ligada à carteira

A moeda pedida precisa estar ativada para o lojista e ter uma carteira de lojista ativa.

Gateways configuráveis

O lojista escolhe os gateways na configuração da API sem gerar novas credenciais.

Autenticação

ZexosPay A API usa chaves para autenticar as requisições. Pegue suas credenciais no painel do lojista.

Integração por ambiente

ZexosPay A API tem ambiente sandbox (testes) e produção. Sempre teste no sandbox antes de ir ao ar.

Configuração de ambiente
Modo sandbox

Use para: Desenvolvimento, testes, integração

X-Environment: sandbox

Credenciais: Use chaves de API com prefixo test_*

Modo produção

Use para: Pagamentos reais, dinheiro de verdade

X-Environment: production

Credenciais: Use chaves de API de produção (sem prefixo)

Configuração de gateways A escolha de gateways é feita no painel. Depois de gerar as credenciais, abra Lojista -> Configuração -> Controles de gateway de pagamento para escolher os gateways sem mudar as chaves da integração.
Requisições assinadas Toda chamada à API precisa incluir X-Timestamp e X-Signature, a menos que as assinaturas tenham sido desativadas na configuração do administrador.
Proteção contra replay O horário precisa ser recente. A tolerância padrão é de 300 segundos, configurável pelo administrador.
Limite de requisições As chamadas da API têm limite por lojista e por IP. O padrão é 120 requisições por minuto.

Credenciais obrigatórias

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
Aviso de segurança Nunca exponha seu Client Secret no código do navegador. Guarde todas as credenciais com segurança no servidor.
Conteúdo assinado

Quando as assinaturas forem obrigatórias, assine exatamente este conteúdo com seu Client Secret:

timestamp.HTTP_METHOD.path_with_query.raw_body

Início rápido

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.

01

Gerar chaves de API

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.

02

Confirmar moedas

Confira se o lojista aceita a moeda do checkout e se o dono tem uma carteira ativa nessa moeda.

03

Escolher gateways

Na configuração da API, ative os gateways que devem aparecer no checkout para cada moeda aceita.

04

Assinar e criar pagamento

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.

Configuração da API Moeda + carteira Filtro de gateway Checkout hospedado
Abrir console de testes

Use primeiro as credenciais de sandbox e troque para produção quando o checkout e o IPN estiverem conferidos.

Última atualização do lojista A configuração da API controla o checkout depois de gerar as chaves

Configuração do lojista e da API

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.

Painel do lojista

Uma integração, checkout controlado pelo painel

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.

Chaves de sandbox Chaves de produção Moedas da carteira Controles de gateway
Modo padrão Sandbox
Acesso em produção Exige aprovação
Origem do gateway Configuração da API

Status de análise do 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.

Moedas

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.

Carteira de recebimento compatível

O dono da loja precisa ter uma carteira ativa na moeda pedida; senão, a API retorna um erro de disponibilidade de carteira.

Controles de gateway de pagamento

Só gateways automáticos ativos que correspondem à moeda pedida e à seleção do lojista aparecem no checkout.

Ordem de decisão

  1. 01
    Autenticar o ambiente

    X-Environment decide qual chave de lojista, chave de API e segredo de API são usados.

  2. 02
    Verificar disponibilidade do lojista

    Lojistas rejeitados ou desativados são bloqueados. A produção também exige status aprovado.

  3. 03
    Validar a moeda pedida

    currency_code deve ser uma moeda aceita pelo lojista, como BRL, USD ou EUR.

  4. 04
    Confirmar carteira de recebimento

    O dono da loja precisa de uma carteira ativa nessa mesma moeda.

  5. 05
    Resolver gateways configurados

    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.

  6. 06
    Aplicar filtro opcional da API

    allow_payment_methods pode reduzir a lista de gateways, mas não libera um gateway não configurado ou de outra moeda.

Casos reais e resultados

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.
Sem gateways entre moedas diferentes

Um gateway configurado para USD não processa checkout em EUR, a não ser que exista um gateway EUR separado.

Os segredos ficam no servidor

O API Secret só é usado para assinar requisições servidor a servidor e verificar assinaturas de IPN.

A URL assinada do checkout expira

A payment_url retornada tem prazo. Crie uma nova sessão de pagamento para links de checkout expirados.

A verificação é restrita ao lojista

Um lojista só pode verificar as próprias transações e só no ambiente correspondente (sandbox ou produção).

Regras de moeda e gateway

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.

Matriz de gateways

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.

Origem no painel Lojista -> Configuração -> Controles de gateway de pagamento
Moeda ativada para o lojista O currency_code da requisição precisa estar na lista de moedas aceitas pelo lojista.
Existe uma carteira de lojista ativa O dono da loja precisa ter uma carteira ativa na moeda pedida.
A moeda do gateway corresponde Só métodos de depósito automáticos ativos dessa moeda exata são aceitos.
A seleção de gateways do lojista é aceita Quando há gateways selecionados na configuração da API, o checkout fica restrito a eles.

Como o allow_payment_methods funciona agora

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.
Padrão seguro Se o lojista não escolheu nenhum gateway, o checkout usa todos os gateways automáticos ativos da moeda pedida. Depois que o lojista escolhe, o checkout usa só essa lista.
POST

Iniciar pagamento

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
Chave de API obrigatória Assinatura HMAC obrigatória Sandbox + produção Carteira da moeda conferida
Seleção de gateway O checkout aplica primeiro as regras de moeda e carteira do lojista e depois os gateways selecionados na configuração da API. allow_payment_methods é só um filtro extra opcional.

Cabeçalhos da requisição

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âmetros da requisição

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 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"].

Campos da resposta de disponibilidade de gateways

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.

Exemplos de código

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;

Resposta de sucesso

200 OK Sessão de pagamento criada
{
  "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"]
  }
}

Respostas de erro comuns

422 A moeda não está ativada para este lojista.

O currency_code pedido não está na lista de moedas aceitas pelo lojista.

422 A carteira de recebimento desta moeda não está disponível.

O dono da loja não tem uma carteira ativa na moeda pedida.

401 Credenciais de API inválidas.

Confira se X-Environment, X-Merchant-Key e X-API-Key são do mesmo ambiente.

GET

Verificar pagamento

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}
Use depois do redirecionamento ou do IPN Restrito ao lojista

Cabeçalhos da requisição

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 de rota

Parâmetro Tipo Obrigatório Descrição
trxId string Sim ZexosPay transaction ID returned by hosted checkout or IPN.

Exemplo cURL

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"

Resposta de sucesso

200 OK Pagamento concluído
{
  "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"
}

Valores de status do pagamento

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.

Exemplos de código

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();
Idempotência Use seu ref_trx e o trx_id retornado para tornar a entrega idempotente. Um webhook e uma verificação podem chegar quase juntos.
POST

Reembolsar pagamento

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
Chave de API obrigatória Assinatura HMAC obrigatória Total ou parcial Restrito ao lojista
O que isso faz Isso estorna o lançamento na plataforma: debita o valor da carteira do lojista e registra um reembolso. A devolução para o cartão do comprador é feita pela plataforma através do gateway original, já que o cartão nunca fica guardado neste sistema.

Cabeçalhos da requisição

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âmetros da requisição

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).

Exemplos de código

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();

Resposta de sucesso

{
    "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"
}

Webhook de reembolso (IPN)

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
}
Erros comuns 422 — "Only completed payments can be refunded", "Refund amount exceeds the refundable balance", "This payment has already been fully refunded" ou "Merchant wallet balance is insufficient to process this refund". A taxa cobrada no pagamento original não é devolvida.
GET

Informações do site

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
Exige autenticação de lojista Marca no checkout Rótulos de ambiente

Exemplo cURL

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"

Resposta de sucesso

200 OK Metadados do gateway
{
  "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"
}
PIX

API PIX

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.

Endpoints

MétodoEndereçoO que faz
POST/api/v1/pix/chargesCria 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}/simulateSó no sandbox: aprova ({"status":"paid"}) ou recusa ({"status":"failed"}).
POST/api/v1/pix/payoutsEnvia um PIX do seu saldo para uma chave PIX (saque).
GET/api/v1/pix/payouts/{id}Consulta o saque.
GET/api/v1/balanceSaldo disponível e valor em saque.
GET/api/v1/statementExtrato paginado de cobranças e saques.
GET/api/v1/webhooksRegistro das entregas de webhook.
POST/api/v1/webhooks/{id}/resendReenvia 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.

Sem cobrança ou saque em dobro. Envie 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.

Criar cobrança PIX

CampoTipoObrigatórioDescrição
amountdecimalSimValor em reais, até 2 casas (ex.: "49.90").
ref_trxstringSimSeu código do pedido ou depósito (até 60 caracteres).
customer.namestringSimNome de quem paga.
customer.documentstringSimCPF ou CNPJ de quem paga (dígitos verificados).
customer.email, customer.phonestringNãoContato de quem paga.
descriptionstringNãoDescrição (até 255 caracteres).
ipn_urlurlNãoEndereço HTTPS público que recebe os webhooks desta cobrança.
metadataobjetoNãoAté 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" }
  }'
201 Created Cobrança criada
{
  "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.

Saque PIX

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.

Antes do primeiro saque: cadastre no painel, em "IPs Autorizados (API)", os IPs dos servidores que vão pedir saques. Pedidos de outros IPs recebem 403. A chave Idempotency-Key é obrigatória.
CampoTipoObrigatórioDescrição
amountdecimalSimValor em reais, até 2 casas.
ref_trxstringSimSeu código do saque.
pix_key_typestringSimcpf, cnpj, email, phone ou random.
pix_keystringSimA chave PIX de destino.
recipient.name, recipient.documentstringNãoNome e CPF/CNPJ de quem recebe.
description, ipn_url, metadata—NãoComo 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"
  }'
201 Created Saque registrado
{
  "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.

Saldo e extrato

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.

Webhooks

EventoQuando
payment.paidCobrança paga (PIX, cartão, cripto ou checkout).
payment.failedCobrança recusada ou cancelada.
payment.refundedEstorno total ou parcial.
payout.paidSaque pago.
payout.failedSaque 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);
});

Erros

Os erros da API PIX vêm assim: {"status":"error","code":"insufficient_balance","message":"..."}.

HTTPcodeSignificado
400idempotency_key_requiredSaque sem Idempotency-Key.
403ip_whitelist_empty, ip_not_authorizedIP não cadastrado para saques.
403payout_disabledSaque por API desligado na plataforma.
403sandbox_only/simulate fora do sandbox.
404not_foundCobrança, saque ou webhook inexistente neste ambiente.
409duplicate_ref_trxJá existe cobrança ou saque ativo com este ref_trx (vem o id).
409idempotency_key_reusedMesma Idempotency-Key com outros dados.
422validation_errorCampo inválido (detalhes em errors).
422invalid_pix_key, amount_out_of_range, insufficient_balanceChave PIX inválida, valor fora dos limites ou saldo insuficiente.
429—Limite de requisições por minuto (veja Retry-After).
502/503provider_error, pix_unavailable, payout_unavailableProvedor indisponível. Pode repetir com a mesma Idempotency-Key.
SPLIT

Split de pagamento

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.

CampoTipoObrigatórioDescrição
split[].walletstringSimID 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[].percentdecimalUm dos doisPercentual do valor da cobrança (até 2 casas, máximo 100). Arredonda para baixo no centavo.
split[].amountdecimalUm dos doisValor fixo na moeda da cobrança.
split[].labelstringNãoNome para você identificar (ex.: coprodutor, afiliado).
split[].refund_liablebooleanNãoSe 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 }
  ]
}

Regras

  • A taxa da ZexosPay é cobrada só de você. A soma das partes não pode passar do seu valor líquido (valor da cobrança menos a taxa); se passar, a cobrança é recusada com 422 (invalid_split na API PIX) e a mensagem diz o limite.
  • Você fica com o que sobra: líquido menos a soma das partes.
  • O repasse acontece na mesma operação que credita você: ou tudo entra, ou nada entra.
  • No sandbox nada se move, mas o split aparece como settled com "sandbox": true para você testar a integração.

Estornos

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.

Na resposta e nos webhooks

"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.

POST

API de cartão

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).

O cartão nunca passa pelo seu sistema. Esta API não recebe número de cartão, validade nem CVV. O cliente digita o cartão na página segura do processador do cartão, depois de abrir o payment_url. Não envie dados de cartão em nenhum campo.

Endpoints

MétodoEndereçoO 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.

Autenticação

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.

Criar cobrança — corpo da requisição

Os mesmos campos de Iniciar pagamento:

ParâmetroTipoObrigatórioDescrição
payment_amountdecimalSimValor da cobrança.
currency_codestringSimMoeda da cobrança (ex.: BRL, USD). Precisa estar ativa na sua conta de lojista.
ref_trxstringSimO código do pedido no seu sistema.
ipn_urlurlSimEndereço que recebe o aviso de pagamento (webhook).
success_redirecturlSimPara onde o cliente volta depois de pagar.
cancel_redirecturlSimPara onde o cliente volta se desistir ou se o pagamento for recusado.
descriptionstringNãoDescrição mostrada no checkout.
customer_name, customer_emailstringNãoDados de quem paga.

Exemplo cURL

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"
  }'

Resposta

201 Created Cobrança criada
{
  "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
}
422 Sem processador de cartão para a moeda
{
  "error": "Card payments are not available for this currency right now.",
  "code": "card_unavailable"
}

Consultar e estornar

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.

Moeda e conversão

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.

Sandbox: com X-Environment: sandbox, o pagamento é aprovado automaticamente ao clicar em pagar no checkout — nenhum cartão é cobrado.

Pagamentos recorrentes e assinaturas

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.

Cobrança recorrente autorizada pelo cliente A ZexosPay cria automaticamente cada fatura de renovação, mas não guarda o cartão nem uma autorização de débito do comprador. O cliente autoriza cada checkout. Cobrança automática com cartão salvo ainda exige uma personalização de cobrança recorrente específica do gateway.

Planos nativos

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.

Ciclo de vida próprio na API

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.

Autorização do cliente

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.

Endpoints de assinatura

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çalhos obrigatórios

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.

Campos para criar assinatura

Campo Obrigatório Regras
external_referenceSimÚnica por lojista e ambiente; máximo de 100 caracteres.
billing_cycleSimdaily, weekly, monthly, half_yearly, ou yearly.
payment_amountSimNúmero de pelo menos 1 na moeda selecionada.
currency_codeSimUma moeda ativada para este lojista.
customer_emailSimE-mail válido; máximo de 150 caracteres.
success_redirect, cancel_redirect, ipn_urlSimURLs 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, descriptionNãoContexto para o cliente na fatura hospedada.
starts_atNãoData e hora ISO 8601. Omita para checkout imediato; datas de início no passado são recusadas.
allow_payment_methodsNãoUm código de método, códigos separados por vírgula ou uma lista de códigos ativos.
metadataNãoObjeto JSON com no máximo 50 entradas de primeiro nível. Não guarde segredos nem dados de cartão.

Ciclo de status da assinatura

Status Significado Ação do lojista
pendingA 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.
activeO período atual tem um pagamento concluído e verificado.Libere o acesso só até current_period_end.
past_dueO 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.
cancelledNenhuma outra fatura será gerada.Crie uma nova assinatura para voltar a cobrar.

Fluxo de renovação recomendado

PASSO 1

Criar assinatura

Faça POST com cliente, valor, ciclo de cobrança, retornos e sua external_reference única.

PASSO 2

Cobrar a primeira fatura

Abra latest_invoice.payment_url para o cliente autorizar o primeiro checkout.

PASSO 3

Confirmar pagamento

Verifique o IPN de conclusão. A ZexosPay marca a fatura como paga, ativa o acesso e define next_billing_at.

PASSO 4

Cobrar renovações

O agendador cria as faturas vencidas. Consulte a assinatura com GET e entregue ao cliente a payment_url da nova fatura pendente.

Criar assinatura Fatura hospedada IPN de conclusão Período ativo Próxima fatura

Exemplo completo em PHP: renovação mensal

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']);

Resposta esperada do checkout

201 Created Assinatura e primeira fatura hospedada criadas
{
  "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"
    }
  }
}

Exemplos de listar, cancelar e renovar

# 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}
Requisito do agendador Rode php artisan schedule:run a cada minuto. A ZexosPay executa merchant-subscriptions:process --limit=100 sem sobreposição, cria uma fatura vencida sob trava no banco e muda um período ativo expirado para past_due até o pagamento ser concluído.

Respostas HTTP e novas tentativas seguras

Status Significado O que fazer
200Consulta, cancelamento ou renovação concluídos.Use o recurso retornado como fonte da verdade.
201Assinatura criada, inclusive na repetição da resposta original de criação.Guarde data.id e a Idempotency-Key.
401 / 403Credenciais, assinatura, ambiente ou status do lojista inválidos.Corrija a autenticação; não tente de novo às cegas.
404A assinatura não existe neste lojista/ambiente.Confira o ID e o X-Environment.
409Conflito 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.
422A validação dos dados ou da configuração de pagamento falhou.Corrija os campos antes de tentar de novo.
429Limite de requisições da API de lojista excedido.Aguarde o Retry-After e tente de novo com espera exponencial.
503Falha temporária ao criar o checkout.Repita o mesmo POST com a mesma Idempotency-Key.

Regras de confirmação de pagamento

  • Mantenha o acesso pendente: status=pending e uma URL de pagamento da fatura não significam que o pagamento foi concluído.
  • Verifique a assinatura do IPN: calcule o HMAC-SHA256 do corpo bruto do webhook com o segredo de API do ambiente do webhook e compare com X-Signature.
  • Confira sua referência: data.ref_trx deve corresponder à fatura de renovação aberta e data.environment ao ambiente esperado.
  • Confirmar status concluído: só status=completed deve ativar ou estender o acesso. Use data.trx_id com GET /api/v1/verify-payment/{trxId} quando precisar de uma checagem extra servidor a servidor.
  • Consultar faturas agendadas: Faça GET na assinatura em next_billing_at ou depois. Uma nova latest_invoice pendente traz a URL do checkout de renovação autorizado pelo cliente.
  • Torne a entrega idempotente: guarde o ID da transação ZexosPay e nunca libere seu serviço duas vezes se um IPN for reenviado.
  • Tratar renovações com falha: o status vira past_due depois de uma falha. Faça POST no endpoint de renovação para criar um novo checkout para o período em aberto.
Resultado prático A API aceita ciclos diário, semanal, mensal, semestral e anual, com registros separados de sandbox e produção, mantendo a segurança de cartão do checkout hospedado.

Webhooks (IPN)

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.

Webhooks por ambiente

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.

Entrega confiável ZexosPay retries timeout webhook deliveries up to 3 attempts. Your endpoint should return a 2xx response as soon as the payload is safely queued or processed.

Cabeçalhos do webhook

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

Conteúdo do webhook

Todos os webhooks trazem a informação de ambiente para você diferenciar transações de sandbox e de produção:

Contexto de ambiente: 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
}

Verificação de assinatura

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:

Segredos por ambiente: Usar 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.

Boas práticas por ambiente

Webhooks de sandbox
  • Use para testar a integração de webhooks
  • Sem transações com dinheiro real
  • Não entregue pedidos reais
  • Não mande e-mails para clientes reais
  • Use o segredo de webhook de teste para verificar
Webhooks de produção
  • Processe pedidos reais de clientes
  • Mande e-mails de confirmação
  • Atualize o estoque
  • Dispare os processos de entrega
  • Use o segredo de webhook de produção para verificar

Exemplos de integração

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.

Configuração de ambiente: Troque {environment} por sandbox ou production e use as credenciais correspondentes: prefixo test_ no sandbox, sem prefixo em produção.
Regras atuais do checkout A moeda pedida precisa bater com a configuração do lojista e com uma carteira ativa. Os gateways visíveis são controlados na configuração da API; allow_payment_methods só reduz a lista de gateways já aceitos.
Assinatura obrigatória Os exemplos devem incluir X-Timestamp e X-Signature gerados com o API Secret do ambiente selecionado (sandbox ou produção). Veja em Autenticação o conteúdo exato da assinatura.
<?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

WooCommerce Integration

Advanced ZexosPay payment gateway with modern WooCommerce Blocks support, dynamic branding, and enterprise-grade security features.

Advanced WooCommerce Integration

Production-ready payment gateway with WooCommerce Blocks (Gutenberg) support, dynamic branding, and secure webhook processing.

3 Minutes Setup
99.9% Uptime
24/7 Webhook Support
Latest Plugin Download

Enterprise-grade WooCommerce payment gateway with modern Blocks support and dynamic branding.

Plugin Size: 45.2 KB
Version: 2.8.0
Last Updated: Oct 26, 2026
System Requirements
  • WordPress 5.8+
  • WooCommerce 6.0+
  • PHP 8.1+ (8.2+ Recommended)
  • SSL Certificate (Required)
  • ZexosPay Merchant Account
  • WooCommerce Blocks Support
Production Ready

Advanced Features

Enterprise-grade payment processing with modern architecture

WooCommerce Blocks

Full Gutenberg checkout compatibility with React-based UI

Marca dinâmica

Auto-fetch logo, colors, and branding from ZexosPay API

Webhooks seguros

HMAC-SHA256 signature verification for payment callbacks

Interface compacta no celular

Space-efficient, responsive design for all devices

Segurança avançada

Multi-header authentication with environment isolation

Modo teste/produção

Seamless sandbox testing with production deployment

Guia rápido de instalação

Comece a integração ZexosPay com WooCommerce em minutos

1
Baixar o plugin mais recente

Download ZexosPay WooCommerce Gateway v2.8.0 from the download section above. This includes all latest features and security updates.

2
Instalar pelo admin do WordPress

Navigate to Plugins → Add New → Upload Plugin and select the downloaded ZIP file. The plugin will auto-extract and install.

3
Ativar e configurar

Activate the plugin and go to WooCommerce → Settings → Payments → ZexosPay. Enter your API credentials and webhook secret.

4
Testar integração

Enable Test Mode, process a sandbox transaction to verify Blocks checkout, webhook delivery, and order completion.

5
Ir ao ar

Disable test mode, ensure production API keys are configured, and start accepting real payments with full webhook processing.

Configuração da API

Configurações essenciais da API para processar pagamentos com segurança

URL base da API

https://usepay.online

Auto-configured
ID de lojista e chave de API

Your unique merchant credentials from ZexosPay dashboard

Required
Segredo do webhook

HMAC-SHA256 signature verification for secure callbacks

Recommended
Cabeçalhos de autenticação

Cabeç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

Configuração do webhook

Status do pagamento e processamento do pedido em tempo real

Endpoint do webhook
https://yoursite.com/wc-api/zexospay_webhook

Configure this URL in your ZexosPay merchant dashboard for automatic order updates.

Eventos aceitos
  • Payment Success
  • Payment Failed
  • Payment Cancelled
  • Payment Pending
  • Refund Processed
  • Payment Timeout

Integração com WooCommerce Blocks

Checkout Gutenberg moderno com interface de pagamento em React

Design responsivo

Compact, mobile-optimized payment interface that adapts to any screen size.

Marca dinâmica

Automatically fetches and displays your ZexosPay branding and logos.

Indicadores de segurança

Clear SSL and security badges to build customer trust during checkout.

Suporte a modo de teste

Clear sandbox indicators for testing without affecting live transactions.

Checklist para produção

Confira se está tudo configurado antes de ir ao ar

Requisitos técnicos
Configuração da API
Verificação final

Solução de problemas

Problemas comuns e soluções da integração ZexosPay com WooCommerce

O método de pagamento não aparece no checkout

Solutions:

  • Verify plugin is activated and enabled in WooCommerce → Settings → Payments
  • Clear browser cache and WooCommerce cache
  • Check if API credentials are correctly configured
  • Ensure SSL certificate is properly installed
Erros 401 Unauthorized da API

Solutions:

  • Verify Merchant ID and API Key are correct
  • Ensure environment (sandbox/production) matches your credentials
  • Check that all required headers are being sent
  • Contact ZexosPay support to verify account status
Pedidos não atualizam depois do pagamento

Solutions:

  • Verify webhook URL is configured in ZexosPay dashboard
  • Check webhook secret key matches plugin configuration
  • Review WordPress error logs for webhook processing errors
  • Test webhook delivery using ZexosPay dashboard tools
Prontidão para lançamento Sandbox primeiro, produção após a aprovação

Checklist de sandbox e ida ao ar

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.

Sandbox

Use as credenciais de teste e X-Environment: sandbox. As transações ficam marcadas como sandbox e não movimentam dinheiro real.

  • Gere ou copie o ID de lojista, a chave de API e o segredo de API de teste.
  • Envie requisições assinadas com o segredo de sandbox.
  • Teste os fluxos de sucesso, cancelamento, pendente, falha, webhook e verificação.

Produção

Use as credenciais de produção e X-Environment: production só depois da aprovação do administrador, das carteiras prontas e dos gateways configurados.

  • O status do lojista precisa estar aprovado.
  • Cada moeda em produção precisa de uma carteira de lojista ativa.
  • Os Controles de gateway de pagamento devem ter só os gateways que você quer mostrar aos clientes.
Checagens para ir ao ar Obrigatório antes de tráfego real
Revisar configuração
Lojista aprovado A API de produção retorna 403 até a aprovação do administrador.
Assinatura no servidor Cada requisição inclui X-Timestamp e X-Signature gerados com o segredo de API correspondente.
Cobertura de carteiras Cada moeda do lojista tem uma carteira de recebimento ativa.
Cobertura de gateways Os gateways selecionados correspondem às moedas que os clientes vão usar.
URLs de redirecionamento success_redirect e cancel_redirect usam HTTPS e aguentam visitas repetidas com segurança.
Verificação do IPN A assinatura do webhook é verificada antes da entrega ou de atualizar o pedido.
Importante Nunca troque só o cabeçalho X-Environment. Troque sempre o ID de lojista, a chave de API e o segredo juntos, para o ambiente e as credenciais baterem.

Testes interativos da API

Testar ZexosPay endpoints da API direto desta documentação. Use as credenciais de demonstração abaixo para testar no sandbox.

Dados de pagamento de demonstração MODO SANDBOX

Use estas credenciais de demonstração para testar todos os métodos de pagamento no sandbox:

Carteira de demonstração
ID da carteira: 123456789 PIN da carteira: 123456
Aprovado automaticamente no sandbox
Voucher de demonstração
Código do voucher: TESTVOUCHER
Resgate na hora
Pagamento por gateway
Comportamento: Sucesso automático
Sem redirecionamento externo
Orientações de teste
  • Cabeçalho de ambiente: Sempre inclua X-ENVIRONMENT: sandbox nas suas requisições
  • Credenciais de demonstração: Use os códigos de carteira/voucher de demonstração para testar os fluxos de pagamento
  • Comportamento do sandbox: Todos os pagamentos são concluídos automaticamente, sem movimentar dinheiro real
  • Controles de gateway: O checkout respeita os gateways configurados na configuração da API para a moeda selecionada.
  • Status da transação: As transações de sandbox ficam marcadas com "SANDBOX_TRANSACTION" nas observações
  • Notificações IPN: As notificações de webhook funcionam normalmente no modo sandbox
Configuração de ambiente: Usar sandbox 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.
Console de testes da API
Cabeçalhos de autenticação
Sandbox: test_*, produção: sem prefixo
Sandbox: test_*, produção: sem prefixo
Usado localmente para gerar o X-Signature. Prefira segredos de sandbox no console do navegador.
Parâmetros da requisição
O código da moeda deve estar em maiúsculas (ex.: BRL, USD, EUR). Use a moeda configurada na sua loja.
Limite os métodos do checkout pelo nome. Aceita texto separado por vírgula ou lista JSON. Não diferencia maiúsculas.
Ambiente sandbox

URL base: https://usepay.online

Cabeçalho de ambiente: X-Environment: sandbox

Credenciais: Usar test_ chaves com prefixo

Finalidade: Testes seguros sem dinheiro real

Ambiente de produção

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

Códigos de erro

ZexosPay A API usa códigos HTTP convencionais para indicar sucesso ou falha das requisições.

Códigos de status HTTP

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ódigos de erro da API

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

Formato da resposta de erro

{
  "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"
}
Tratamento de erros Sempre confira o campo success nas respostas e trate os erros na sua aplicação.

Suporte

Suporte técnico

Precisa de ajuda com a integração da API ZexosPay? Nossa equipe técnica dá suporte.

Horário de suporte: 24/7 para problemas críticos