Visão geral
O NexusPay aceita pagamentos em USDT-N e NXS nativo na rede NEXUS (chainId 939393) com liquidação em ~3 segundos, taxa de 1,00% (USDT-N) ou 0,50% (NXS) e sem chargeback.
Fluxo típico de integração:
- Seu backend cria uma cobrança (
POST /v1/orders) e recebe opayUrl. - Você exibe o link/QR ao cliente (ou redireciona). O cliente paga com qualquer carteira EVM.
- O contrato NexusPaymentGateway divide o valor: taxa → tesouraria, líquido → sua carteira cadastrada.
- O seu backend é notificado por webhook assinado (
order.paid) e/ou via SSE na página de cobrança. - Confirme o pagamento no explorer:
https://explorer.nxschain.com/tx/<txHash>
https://pay.nxschain.com/api · Explorer: https://explorer.nxschain.com · Gateway (contrato): 0x7828502f1D1f3203b39EFDDF3E3779b999d60218Ambiente de testes / Sandbox
A rede NEXUS opera com uma única chainId: 939393 — não há testnet separada. A homologação de integração é feita na própria rede principal com valores simbólicos (o custo de uma transação é de frações de centavo em NXS e a liquidação é imediata, então testar com R$ 1–5 é seguro e definitivo).
Tokens de homologação
Não existe faucet público. Tokens de teste (NXS para o gás e USDT-N/USDC-N sintéticos) são fornecidos sob demanda pela operação:
- Solicite ao seu contato comercial/operador o par de credenciais (apiKey/secretKey) e a quantidade de tokens de homologação.
- Cada integrador recebe carteiras de teste dedicadas e um ambiente de credenciais isolado.
- Os USDT-N de teste são cunhados 1:1 (mesma regra da produção) — o que você testa é exatamente o que vai operar.
Boas práticas de homologação
- Sempre crie os pedidos de teste com
"description": "HOMOLOGACAO …"para identificação no painel e no explorer. - Valide o fluxo completo ao menos uma vez: criar cobrança → pagar (qualquer carteira EVM com a chain 939393 adicionada) → receber o webhook → conferir o
txHashno explorer. - Teste também o cenário de erro: tentar pagar duas vezes o mesmo
orderId(o contrato rejeita — nada é cobrado) e um webhook endpoint fora do ar (observe as 5 tentativas com backoff e o botão Reenviar no portal). - Em produção, crie novas credenciais por lojista e rotacione sempre que necessário (endpoint de rotação interno).
Autenticação (HMAC)
Cada lojista recebe um par apiKey (identifica o merchant) e secretKey (assina as requisições — nunca envie a secretKey em URLs, logs ou código de front-end).
Toda chamada autenticada deve enviar 3 headers:
| Header | Descrição |
|---|---|
X-Nexus-Api-Key | Sua apiKey pública |
X-Nexus-Timestamp | Epoch em milissegundos (janela de ±300s contra replay) |
X-Nexus-Signature | HMAC-SHA256 em hex minúsculo (ver abaixo) |
String a assinar
{timestamp}:{MÉTODO}:{caminho}:{sha256_hex(corpo)}
Exemplo (POST /v1/orders com body {"token":"USDT-N","amount":"100"}):
1750000000000:POST:/v1/orders:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
- caminho = path sem query string (assinatura ignora parâmetros de URL)
- corpo = o corpo bruto exato (bytes) enviado na requisição
- GET sem corpo → usa
sha256("") - Assinatura =
HMAC_SHA256(secretKey, string_acima)em hexadecimal minúsculo
Criar cobrança
POST /v1/orders
Autenticado (HMAC). O lojista é derivado da apiKey — não envie o endereço do merchant no corpo.
{
"token": "USDT-N", // "USDT-N" | "NXS" | endereço ERC-20
"amount": "1250", // quantidade em unidades do token (string decimal)
"fiatAmount": "6750.00", // opcional: valor em moeda fiduciária (exibição)
"fiatCurrency": "BRL", // opcional
"description": "Fatura 001" // opcional
}
Resposta 201:
{
"orderId": "a99703a7-...",
"orderKey": "0x9655a211...", // idempotência ON-CHAIN (bytes32)
"status": "PENDING",
"asset": "USDT-N", "native": false,
"amount": "1250", "amountWei": "1250000000000000000000",
"feeBps": 100,
"gateway": "0x7828502f...", "chainId": 939393,
"payUrl": "https://pay.nxschain.com/o/a99703a7-...",
"createdAt": "2026-09-07T15:07:10.793Z"
}
payUrl como QR Code (ex.: https://pay.nxschain.com/o/<orderId>) — o cliente paga por ele. A confirmação chega em ~3s.Exemplo em cURL (bash)
O script abaixo monta a assinatura com openssl:
API_KEY="00000000-0000-0000-0000-000000000000"
SECRET_KEY="sua_secret_key_hex"
BASE="https://pay.nxschain.com/api"
BODY='{"token":"USDT-N","amount":"1250","description":"Fatura 001"}'
TS=$(date +%s%3N)
PAYLOAD="$TS:POST:/v1/orders:$(printf '%s' "$BODY" | openssl dgst -sha256 | awk '{print $2}')"
SIG=$(printf '%s' "$PAYLOAD" | openssl dgst -sha256 -hmac "$SECRET_KEY" | awk '{print $2}')
curl -s -X POST "$BASE/v1/orders" \
-H "Content-Type: application/json" \
-H "X-Nexus-Api-Key: $API_KEY" \
-H "X-Nexus-Timestamp: $TS" \
-H "X-Nexus-Signature: $SIG" \
-d "$BODY"
Consultar pedidos (GET, sem corpo):
TS=$(date +%s%3N)
PAYLOAD="$TS:GET:/v1/merchant/orders:$(printf '' | openssl dgst -sha256 | awk '{print $2}')"
SIG=$(printf '%s' "$PAYLOAD" | openssl dgst -sha256 -hmac "$SECRET_KEY" | awk '{print $2}')
curl -s "$BASE/v1/merchant/orders?status=PAID" \
-H "X-Nexus-Api-Key: $API_KEY" \
-H "X-Nexus-Timestamp: $TS" \
-H "X-Nexus-Signature: $SIG"
Exemplo em Node.js (18+)
const crypto = require("crypto");
const API_KEY = process.env.NEXUS_API_KEY;
const SECRET_KEY = process.env.NEXUS_SECRET_KEY;
const BASE = "https://pay.nxschain.com/api";
const sha256 = (s) => crypto.createHash("sha256").update(s || "").digest("hex");
const sign = (data) => crypto.createHmac("sha256", SECRET_KEY).update(data).digest("hex");
async function authedFetch(method, path, body) {
const ts = String(Date.now());
const cleanPath = path.split("?")[0];
const rawBody = body ? JSON.stringify(body) : "";
const payload = `${ts}:${method}:${cleanPath}:${sha256(rawBody)}`;
const res = await fetch(BASE + path, {
method,
headers: {
"Content-Type": "application/json",
"X-Nexus-Api-Key": API_KEY,
"X-Nexus-Timestamp": ts,
"X-Nexus-Signature": sign(payload)
},
body: rawBody || undefined
});
if (!res.ok) throw new Error((await res.json()).error || `HTTP ${res.status}`);
return res.json();
}
// Criar cobrança
const order = await authedFetch("POST", "/v1/orders", {
token: "USDT-N",
amount: "1250",
fiatAmount: "6750.00",
fiatCurrency: "BRL",
description: "Fatura 001"
});
console.log("Pague via:", order.payUrl);
Exemplo em PHP
<?php
$apiKey = getenv('NEXUS_API_KEY');
$secretKey = getenv('NEXUS_SECRET_KEY');
$base = 'https://pay.nxschain.com/api';
function nexus_headers($method, $path, $secretKey, $body = '') {
$ts = (int) round(microtime(true) * 1000);
$payload = $ts . ':' . $method . ':' . $path . ':' . hash('sha256', $body);
$sig = hash_hmac('sha256', $payload, $secretKey);
return [
'Content-Type: application/json',
'X-Nexus-Api-Key: ' . getenv('NEXUS_API_KEY'),
'X-Nexus-Timestamp: ' . $ts,
'X-Nexus-Signature: ' . $sig,
];
}
// Criar cobrança
$body = json_encode([
'token' => 'USDT-N',
'amount' => '1250',
'fiatAmount' => '6750.00',
'fiatCurrency' => 'BRL',
'description' => 'Fatura 001',
]);
$ch = curl_init($base . '/v1/orders');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_HTTPHEADER => nexus_headers('POST', '/v1/orders', $secretKey, $body),
CURLOPT_RETURNTRANSFER => true,
]);
$order = json_decode(curl_exec($ch), true);
curl_close($ch);
echo "Pague via: " . $order['payUrl'] . PHP_EOL;
Consultar cobrança
GET/v1/orders/:id — público (usado pela página de pagamento). Retorna status atual (PENDING, PARTIAL, PAID) e, se pago, paid_tx_hash, fee_wei, net_wei, payer.
GET/v1/orders/:id/events — SSE público: stream de event: status a cada 2s; encerra ao pagar. Útil para a tela de confirmação reativa.
const ev = new EventSource(`https://pay.nxschain.com/api/v1/orders/${orderId}/events`);
ev.addEventListener("status", (e) => {
const s = JSON.parse(e.data);
if (s.status === "PAID") { /* liberar pedido */ ev.close(); }
});
Consulta detalhada do lojista (autenticada): GET/v1/merchant/orders/:id inclui o histórico de entregas do webhook.
Webhooks (order.paid)
Cadastre sua URL no portal (Webhook) — https://pay.nxschain.com/dashboard — ou via PUT/v1/merchant/webhook com {"webhookUrl":"https://seu-sistema.com.br/nexus-webhook"}. A primeira configuração gera um webhook secret.
Quando uma cobrança é paga, o NexusPay envia POST com 5 tentativas (backoff exponencial: 5s, 20s, 80s…) e estes headers:
| Header | Valor |
|---|---|
X-Nexus-Signature | HMAC_SHA256(webhookSecret, corpo_bruto) em hex |
X-Nexus-Timestamp | epoch ms |
X-Nexus-Event-Id | orderId (use p/ idempotência) |
Payload:
{
"event": "order.paid",
"orderId": "a99703a7-...",
"merchant": "0xc07C...", // carteira que recebe o líquido
"token": "0x5cd05BfA...", // address(0) quando pago em NXS nativo
"amount": "1250000000000000000000", // wei
"paidAmount": "1250000000000000000000",
"fee": "12500000000000000000", // 1% em wei
"net": "1237500000000000000000", // líquido ao lojista
"txHash": "0x13d6df...",
"payer": "0x7099...",
"timestamp": 1750000000000
}
Validação (Node.js)
const crypto = require("crypto");
app.post("/nexus-webhook", express.raw({ type: "*/*" }), (req, res) => {
const sig = crypto
.createHmac("sha256", process.env.NEXUS_WEBHOOK_SECRET)
.update(req.body) // corpo BRUTO, sem JSON.parse
.digest("hex");
if (sig !== req.headers["x-nexus-signature"]) {
return res.status(401).send("assinatura invalida");
}
const payload = JSON.parse(req.body);
if (payload.event === "order.paid") {
// Idempotência: processe só uma vez por orderId
liberarPedido(payload.orderId, payload.net, payload.txHash);
}
res.status(200).json({ received: true }); // responda rápido (2xx)
});
Validação (PHP)
<?php
$body = file_get_contents('php://input');
$sig = hash_hmac('sha256', $body, getenv('NEXUS_WEBHOOK_SECRET'));
if (!hash_equals($sig, $_SERVER['HTTP_X_NEXUS_SIGNATURE'] ?? '')) {
http_response_code(401); exit('assinatura invalida');
}
$payload = json_decode($body, true);
if (($payload['event'] ?? '') === 'order.paid') {
// garanta processamento unico por orderId (tabela de eventos processados)
liberarPedido($payload['orderId'], $payload['net'], $payload['txHash']);
}
http_response_code(200); echo json_encode(['received' => true]);
/v1/merchant/orders/:id/replay). Responda sempre 2xx o mais rápido possível; o NexusPay considera entregue apenas com 2xx.Erros
| HTTP | Quando | Corpo (exemplo) |
|---|---|---|
400 | Validação (token/amount/merchant não habilitado/webhookUrl inválida) | {"error":"token invalido (use USDT-N, NXS ou endereco)"} |
401 | Credenciais ausentes, apiKey inválida, assinatura errada ou timestamp fora da janela (±300s) | {"error":"assinatura invalida"} |
404 | Ordem não encontrada | {"error":"ordem nao encontrada"} |
409 | Merchant já cadastrado (admin) | {"error":"merchant ja cadastrado"} |
500 | Erro interno | {"error":"erro interno"} |
Erros de transação on-chain (ex.: orderId já pago, merchant desabilitado, valor 0) revertem no contrato — o cliente vê o erro na carteira e nada é cobrado. O orderKey é a proteção de idempotência na chain: o mesmo pedido não pode ser pago duas vezes.
Boas práticas
- Secret no servidor: apiKey/secretKey/webhook secret vivem apenas no seu backend (variáveis de ambiente / cofre). Nunca no JavaScript do navegador.
- Valide a assinatura antes de liberar qualquer entrega (produto, serviço, acesso).
- Idempotência por orderId: seu sistema pode receber o mesmo webhook mais de uma vez (retries/replay) — processe uma única vez.
- Não confie só no webhook: em caso de dúvida, confira
GET /v1/orders/:idou o txHash no explorerhttps://explorer.nxschain.com/tx/<txHash>. - Valores em wei: amount/fee/net trafegam em wei (18 decimais) — converta na exibição (
BigIntem JS,bcmathem PHP). - Liquidação: o líquido cai direto na carteira cadastrada do lojista em ~3s (1 bloco). Não há etapa de "antecipação".
- Chargeback: pagamentos são irreversíveis por natureza. Defina sua política de reembolso (fora da chain) no contrato comercial com o cliente.
- Taxas: USDT-N 1,00% · NXS nativo 0,50% — configuradas por lojista no contrato; consulte
GET /v1/configpara exibir sempre o valor correto.
Referência rápida
| Método | Rota | Auth | Descrição |
|---|---|---|---|
| GET | /v1/config | pública | Gateway, lojistas, ativos, taxas, cotações |
| POST | /v1/orders | HMAC | Criar cobrança (lojista derivado da apiKey) |
| GET | /v1/orders/:id | pública | Status da cobrança |
| GET | /v1/orders/:id/events | pública | SSE de status em tempo real |
| GET | /v1/merchant/profile | HMAC | Perfil (endereço, fees, webhook configurado) |
| GET | /v1/merchant/orders | HMAC | Lista (filtro ?status=, ?limit=) |
| GET | /v1/merchant/orders/:id | HMAC | Detalhe + entregas do webhook |
| POST | /v1/merchant/orders/:id/replay | HMAC | Reenviar webhook de pedido pago |
| PUT | /v1/merchant/webhook | HMAC | Configurar/limpar URL de webhook ({"webhookUrl":""} limpa) |
/v1/admin/* (criar merchant, rotacionar credenciais) são de uso operacional interno, protegidos por token de administrador — não os exponha publicamente.NEXUS NETWORK · NexusPay · chainId 939393 · Suporte: através do seu contato comercial.