OPENAPI / REST
Documentação HxPay
Leia o contrato da API sem login. Para criar uma chave e executar operações, acesse sua conta.
Início rápido
- Crie sua chave na área Desenvolvedores da conta. Mantenha o segredo somente no servidor.
- Envie valores inteiros em centavos e uma Idempotency-Key única por pedido.
- Consulte o pagamento e verifique a assinatura do webhook antes de atualizar seu pedido.
API REST e webhooks assinados para criar cobranças e acompanhar eventos. Leia o contrato público; use sua chave somente no servidor.
Documentação pública ↗import {randomUUID} from 'node:crypto';
const auth = {'Authorization': 'Bearer ' + process.env.HXPAY_API_KEY,
'Content-Type': 'application/json', 'X-HxPay-User-IP': 'END_USER_PUBLIC_IP'};
const quoteResponse = await fetch('https://hxpay.com.br/api/v1/quotes', {
method: 'POST', headers: auth,
body: JSON.stringify({amount_cents: 10000})
});
if (!quoteResponse.ok) throw new Error('Quote request failed');
const {data: quote} = await quoteResponse.json();
const paymentResponse = await fetch('https://hxpay.com.br/api/v1/payments', {
method: 'POST', headers: {...auth, 'Idempotency-Key': randomUUID()},
body: JSON.stringify({quote_id: quote.quote_id,
payer: {name: 'PAYER_NAME', document: 'CPF_OR_CNPJ'},
external_reference: 'ORDER_ID'})
});
if (!paymentResponse.ok) throw new Error('Payment request failed');
const {data: payment} = await paymentResponse.json();curl https://hxpay.com.br/api/v1/quotes \
-H "Authorization: Bearer $HXPAY_API_KEY" \
-H "Content-Type: application/json" \
-H "X-HxPay-User-IP: END_USER_PUBLIC_IP" \
-d '{"amount_cents":10000}'
curl https://hxpay.com.br/api/v1/payments \
-H "Authorization: Bearer $HXPAY_API_KEY" \
-H "Idempotency-Key: UNIQUE_ORDER_UUID" \
-H "Content-Type: application/json" \
-d '{"quote_id":"QUOTE_ID","payer":{"name":"PAYER_NAME","document":"CPF_OR_CNPJ"},"external_reference":"ORDER_ID"}'import os, uuid, requests
headers = {'Authorization': 'Bearer ' + os.environ['HXPAY_API_KEY'],
'X-HxPay-User-IP': 'END_USER_PUBLIC_IP'}
quote = requests.post('https://hxpay.com.br/api/v1/quotes', headers=headers,
json={'amount_cents': 10000}, timeout=30)
quote.raise_for_status()
payment = requests.post(
'https://hxpay.com.br/api/v1/payments',
headers={**headers, 'Idempotency-Key': str(uuid.uuid4())},
json={'quote_id': quote.json()['data']['quote_id'],
'payer': {'name': 'PAYER_NAME', 'document': 'CPF_OR_CNPJ'},
'external_reference': 'ORDER_ID'}, timeout=30)
payment.raise_for_status()HTTP 200 / 202 · JSON
{
"data": {
"quote_id": "EXAMPLE_QUOTE_ID", "status": "quoted",
"amount_cents": 10000, "currency": "BRL",
"estimated_usdt": "18.950000",
"settlement": {"asset": "USDT0", "network": "polygon",
"model": "routed_usdt"},
"fees": {"commission_cents": 249, "provider_fee_cents": 99,
"platform_fee_cents": 348}, "net_amount_cents": 9652,
"expires_at": 1791859200
}
}Webhook assinado: valide antes de agir.
HxPay-Signature: t=TIMESTAMP,v1=HMAC_SHA256
HxPay-Event-Id: EVENT_ID
{"id":"EVENT_ID","event":"payment.completed",
"data":{"id":"PAYMENT_ID","status":"depix_sent",
"estimated_usdt":"18.950000","received_usdt":"18.910000",
"settlement_tx_hash":"0xTRANSACTION_HASH"}}Valide HxPay-Signature com HMAC-SHA256 sobre TIMESTAMP.corpo-bruto e comparação em tempo constante. O exemplo aceita até 300 segundos; ajuste sua janela e deduplique por HxPay-Event-Id.
Node · HMAC-SHA256
import {createHmac, timingSafeEqual} from 'node:crypto';
function verifyWebhook(header, rawBody, secret, now = Date.now()) {
const match = /^t=(\d+),v1=([a-f0-9]{64})$/.exec(header || '');
if (!match || Math.abs(now / 1000 - Number(match[1])) > 300) return false;
const expected = createHmac('sha256', secret)
.update(match[1] + '.').update(rawBody).digest();
return timingSafeEqual(expected, Buffer.from(match[2], 'hex'));
}
// rawBody is the exact request bytes; deduplicate HxPay-Event-Id.
// Confirm the canonical payment state with GET /api/v1/payments/{id}.pending → approved / delayed → depix_sent · expired / refunded / under_review / error. Documentação pública
Endpoints e contratos
Especificação OpenAPI ↗HxPay Merchant API · 1.1.0
https://hxpay.com.br/api/v1GET /account — Get account, wallets, pricing and availability
Recebimento configurado pelo cobrador no painel: DePix na Liquid ou USDT. O destino se aplica aos novos pagamentos na API existente, links e QR dinâmico.
HTTP 200
Account
| data | #/components/schemas/Account |
|---|
HTTP 401
POST /quotes — Consultar o valor líquido estimado sem emitir Pix
Cria uma cotação de curta duração usando o destino de recebimento configurado na conta. Não emite Pix nem inicia movimentação financeira. estimated_usdt é uma estimativa; o valor definitivo é recebido em received_usdt após payment.completed.
application/json
| amount_cents | integer | Valor bruto que o pagador pagará, em centavos de BRL |
|---|
HTTP 200
Cotação criada
| data | #/components/schemas/Quote |
|---|
HTTP 400
HTTP 401
HTTP 429
GET /payments — List payments
[
{
"$ref": "#/components/parameters/Limit"
},
{
"$ref": "#/components/parameters/Cursor"
}
]HTTP 200
Payment page
| items | array | |
|---|---|---|
| has_more | boolean | |
| next_cursor | string,null |
HTTP 401
POST /payments — Create an idempotent Pix payment
O nome e CPF/CNPJ são do pagador. Envie quote_id para consumir uma cotação criada em POST /quotes, sem repetir amount_cents; ou mantenha o fluxo compatível enviando amount_cents diretamente. O destino de recebimento é definido pelo cobrador e fica congelado na cotação. Pix já emitidos mantêm seu destino. USDT acrescenta 0,5 ponto percentual à comissão da conta. payment.completed só é emitido após entrega; blockchain_tx_id é a etapa Liquid e settlement_tx_hash/settlement_explorer_url são o comprovante final. Valores acima de R$ 500 sem EUID seguem automaticamente com liberação D+1 tanto em DePix na Liquid quanto em USDT, sujeitos somente ao teto da conta.
[
{
"name": "Idempotency-Key",
"in": "header",
"required": true,
"schema": {
"type": "string",
"minLength": 16,
"maxLength": 128,
"pattern": "^[A-Za-z0-9_-]+Carregando a especificação pública…
quot;
}
}
]application/json
| quote_id | string | Cotação criada em POST /quotes. Quando informado, não envie amount_cents ou wallet_id. |
|---|---|---|
| amount_cents | integer | |
| payer | #/components/schemas/Payer | |
| wallet_id | string | |
| external_reference | string | |
| new_payer_policy | string |
HTTP 200
HTTP 202
HTTP 400
HTTP 409
GET /payments/{payment_id} — Get and refresh a payment
[
{
"$ref": "#/components/parameters/PaymentId"
}
]HTTP 200
HTTP 404
GET /payments/{payment_id}/evidence — Get normalized settlement evidence
[
{
"$ref": "#/components/parameters/PaymentId"
}
]HTTP 200
Evidence
{
"type": "object",
"additionalProperties": true
}POST /crypto/payments — Criar Pix com entrega DePix ou USDT na carteira do cobrador
Nome/documento em payer pertencem ao pagador. receiving é definido pelo servidor do cobrador, ou omitido para usar o destino padrão salvo. Escopos read e payments:write. Mesma Idempotency-Key e JSON retornam a mesma operação. Valores acima de R$ 500 sem EUID recebem a política D+1 do servidor em DePix ou USDT, respeitando o limite da conta. Operações já emitidas mantêm sua referência e acompanhamento.
[
{
"name": "Idempotency-Key",
"in": "header",
"required": true,
"schema": {
"type": "string",
"minLength": 8,
"maxLength": 128
}
}
]application/json
| amount_cents | integer | |
|---|---|---|
| external_reference | string | |
| payer | object | |
| receiving | object |
HTTP 200
Mesma operação, com código Pix/status/estimativa
HTTP 202
Emissão em acompanhamento; não gerar outra cobrança
HTTP 409
Idempotency-Key conflitante ou requisição incompatível com uma operação existente
GET /crypto/payments — Histórico cripto da própria conta
HTTP 200
items de operações, sem dados privados do pagador
GET /crypto/account — Destinos públicos salvos e redes da conta do cobrador
HTTP 200
data.receiving com addresses e default_network; max_single_cents é o teto habilitado da conta
GET /crypto/payments/{id} — Acompanhar Pix, conversão e entrega na carteira
[
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
]HTTP 200
data com status e hashes quando confirmados
HTTP 404
Operação inexistente ou de outra conta
GET /payments/{payment_id}/receipt.pdf — Download the payment receipt
[
{
"$ref": "#/components/parameters/PaymentId"
}
]HTTP 200
PDF receipt
{
"type": "string",
"contentEncoding": "base64"
}HTTP 404
JSON / OpenAPI
{
"openapi": "3.1.0",
"info": {
"title": "HxPay Merchant API",
"version": "1.1.0",
"description": "Pix collection with automatic USDT delivery on Polygon, Ethereum, Tron, Solana, BNB Smart Chain, Arbitrum, Avalanche C-Chain or TON, or direct DePix on Liquid. Amounts are integer BRL cents. The merchant owns the receiving address; payer identity belongs to the Pix payer."
},
"servers": [
{
"url": "https://hxpay.com.br/api/v1",
"description": "Production"
},
{
"url": "http://127.0.0.1:8787/api/v1",
"description": "Local deterministic sandbox"
}
],
"security": [
{
"bearerAuth": []
}
],
"paths": {
"/account": {
"get": {
"operationId": "getAccount",
"summary": "Get account, wallets, pricing and availability",
"responses": {
"200": {
"description": "Account",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"data": {
"$ref": "#/components/schemas/Account"
}
},
"required": [
"data"
]
}
}
}
},
"401": {
"$ref": "#/components/responses/Error"
}
},
"description": "Recebimento configurado pelo cobrador no painel: DePix na Liquid ou USDT. O destino se aplica aos novos pagamentos na API existente, links e QR dinâmico."
}
},
"/quotes": {
"post": {
"operationId": "createQuote",
"summary": "Consultar o valor líquido estimado sem emitir Pix",
"description": "Cria uma cotação de curta duração usando o destino de recebimento configurado na conta. Não emite Pix nem inicia movimentação financeira. estimated_usdt é uma estimativa; o valor definitivo é recebido em received_usdt após payment.completed.",
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateQuote"
}
}
}
},
"responses": {
"200": {
"description": "Cotação criada",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"data": {
"$ref": "#/components/schemas/Quote"
}
},
"required": [
"data"
]
}
}
}
},
"400": {
"$ref": "#/components/responses/Error"
},
"401": {
"$ref": "#/components/responses/Error"
},
"429": {
"$ref": "#/components/responses/Error"
}
}
}
},
"/payments": {
"get": {
"operationId": "listPayments",
"summary": "List payments",
"parameters": [
{
"$ref": "#/components/parameters/Limit"
},
{
"$ref": "#/components/parameters/Cursor"
}
],
"responses": {
"200": {
"description": "Payment page",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/PaymentPage"
}
}
}
},
"401": {
"$ref": "#/components/responses/Error"
}
}
},
"post": {
"operationId": "createPayment",
"summary": "Create an idempotent Pix payment",
"parameters": [
{
"name": "Idempotency-Key",
"in": "header",
"required": true,
"schema": {
"type": "string",
"minLength": 16,
"maxLength": 128,
"pattern": "^[A-Za-z0-9_-]+Carregando a especificação pública…
quot;
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreatePayment"
}
}
}
},
"responses": {
"200": {
"$ref": "#/components/responses/Payment"
},
"202": {
"$ref": "#/components/responses/Payment"
},
"400": {
"$ref": "#/components/responses/Error"
},
"409": {
"$ref": "#/components/responses/Error"
}
},
"description": "O nome e CPF/CNPJ são do pagador. Envie quote_id para consumir uma cotação criada em POST /quotes, sem repetir amount_cents; ou mantenha o fluxo compatível enviando amount_cents diretamente. O destino de recebimento é definido pelo cobrador e fica congelado na cotação. Pix já emitidos mantêm seu destino. USDT acrescenta 0,5 ponto percentual à comissão da conta. payment.completed só é emitido após entrega; blockchain_tx_id é a etapa Liquid e settlement_tx_hash/settlement_explorer_url são o comprovante final. Valores acima de R$ 500 sem EUID seguem automaticamente com liberação D+1 tanto em DePix na Liquid quanto em USDT, sujeitos somente ao teto da conta."
}
},
"/payments/{payment_id}": {
"get": {
"operationId": "getPayment",
"summary": "Get and refresh a payment",
"parameters": [
{
"$ref": "#/components/parameters/PaymentId"
}
],
"responses": {
"200": {
"$ref": "#/components/responses/Payment"
},
"404": {
"$ref": "#/components/responses/Error"
}
}
}
},
"/payments/{payment_id}/evidence": {
"get": {
"operationId": "getPaymentEvidence",
"summary": "Get normalized settlement evidence",
"parameters": [
{
"$ref": "#/components/parameters/PaymentId"
}
],
"responses": {
"200": {
"404": {
"$ref": "#/components/responses/Error"
},
"description": "Evidence",
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": true
}
}
}
}
}
}
},
"/crypto/payments": {
"post": {
"summary": "Criar Pix com entrega DePix ou USDT na carteira do cobrador",
"security": [
{
"bearerAuth": []
}
],
"description": "Nome/documento em payer pertencem ao pagador. receiving é definido pelo servidor do cobrador, ou omitido para usar o destino padrão salvo. Escopos read e payments:write. Mesma Idempotency-Key e JSON retornam a mesma operação. Valores acima de R$ 500 sem EUID recebem a política D+1 do servidor em DePix ou USDT, respeitando o limite da conta. Operações já emitidas mantêm sua referência e acompanhamento.",
"parameters": [
{
"name": "Idempotency-Key",
"in": "header",
"required": true,
"schema": {
"type": "string",
"minLength": 8,
"maxLength": 128
}
}
],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"amount_cents",
"payer"
],
"properties": {
"amount_cents": {
"type": "integer",
"minimum": 500,
"maximum": 600000
},
"external_reference": {
"type": "string",
"maxLength": 100
},
"payer": {
"type": "object",
"required": [
"name",
"document"
],
"properties": {
"name": {
"type": "string"
},
"document": {
"type": "string",
"description": "CPF/CNPJ válido do titular que fará o Pix"
}
}
},
"receiving": {
"type": "object",
"required": [
"network",
"address"
],
"properties": {
"network": {
"type": "string",
"enum": [
"polygon",
"ethereum",
"tron",
"solana",
"bsc",
"arbitrum",
"avax",
"ton",
"liquid"
]
},
"address": {
"type": "string",
"description": "Endereço público de recebimento do cobrador"
},
"memo": {
"type": "string",
"maxLength": 64,
"description": "Memo/comentário opcional para TON, quando exigido pela carteira"
}
}
}
}
}
}
}
},
"responses": {
"200": {
"description": "Mesma operação, com código Pix/status/estimativa"
},
"202": {
"description": "Emissão em acompanhamento; não gerar outra cobrança"
},
"409": {
"description": "Idempotency-Key conflitante ou requisição incompatível com uma operação existente"
}
}
},
"get": {
"summary": "Histórico cripto da própria conta",
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "items de operações, sem dados privados do pagador"
}
}
}
},
"/crypto/account": {
"get": {
"summary": "Destinos públicos salvos e redes da conta do cobrador",
"security": [
{
"bearerAuth": []
}
],
"responses": {
"200": {
"description": "data.receiving com addresses e default_network; max_single_cents é o teto habilitado da conta"
}
}
}
},
"/crypto/payments/{id}": {
"get": {
"summary": "Acompanhar Pix, conversão e entrega na carteira",
"security": [
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "id",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
}
],
"responses": {
"200": {
"description": "data com status e hashes quando confirmados"
},
"404": {
"description": "Operação inexistente ou de outra conta"
}
}
}
},
"/payments/{payment_id}/receipt.pdf": {
"get": {
"operationId": "downloadPaymentReceipt",
"summary": "Download the payment receipt",
"parameters": [
{
"$ref": "#/components/parameters/PaymentId"
}
],
"responses": {
"200": {
"description": "PDF receipt",
"content": {
"application/pdf": {
"schema": {
"type": "string",
"contentEncoding": "base64"
}
}
}
},
"404": {
"$ref": "#/components/responses/Error"
}
}
}
}
},
"components": {
"securitySchemes": {
"bearerAuth": {
"type": "http",
"scheme": "bearer"
}
},
"parameters": {
"PaymentId": {
"name": "payment_id",
"in": "path",
"required": true,
"schema": {
"type": "string"
}
},
"Limit": {
"name": "limit",
"in": "query",
"schema": {
"type": "integer",
"minimum": 1,
"maximum": 100,
"default": 50
}
},
"Cursor": {
"name": "cursor",
"in": "query",
"schema": {
"type": "string"
}
}
},
"responses": {
"Payment": {
"description": "Payment",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"data": {
"$ref": "#/components/schemas/Payment"
}
},
"required": [
"data"
]
}
}
}
},
"Error": {
"description": "Error",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
},
"schemas": {
"CreateQuote": {
"type": "object",
"additionalProperties": false,
"required": [
"amount_cents"
],
"properties": {
"amount_cents": {
"type": "integer",
"minimum": 500,
"maximum": 600000,
"description": "Valor bruto que o pagador pagará, em centavos de BRL"
}
}
},
"Quote": {
"type": "object",
"required": [
"quote_id",
"status",
"amount_cents",
"currency",
"settlement",
"fees",
"expires_at"
],
"properties": {
"quote_id": {
"type": "string",
"pattern": "^[a-f0-9]{32}Carregando a especificação pública…
quot;
},
"status": {
"const": "quoted"
},
"amount_cents": {
"type": "integer"
},
"currency": {
"const": "BRL"
},
"estimated_usdt": {
"type": "string",
"pattern": "^[0-9]+\\.[0-9]{6}Carregando a especificação pública…
quot;
},
"estimated_depix": {
"type": "string"
},
"net_amount_cents": {
"type": "integer"
},
"settlement": {
"type": "object",
"additionalProperties": false,
"required": [
"asset",
"network",
"model"
],
"properties": {
"asset": {
"type": "string"
},
"network": {
"type": "string"
},
"model": {
"type": "string"
}
}
},
"fees": {
"type": "object",
"additionalProperties": {
"type": "integer"
}
},
"rate_type": {
"type": "string"
},
"expires_at": {
"type": "integer",
"description": "Unix timestamp em segundos"
}
}
},
"Account": {
"type": "object",
"required": [
"id",
"wallets",
"availability",
"settlement",
"limits"
],
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"wallets": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
},
"scopes": {
"type": "array",
"items": {
"type": "string"
}
},
"availability": {
"type": "object",
"additionalProperties": true
},
"pricing": {
"type": "object",
"additionalProperties": true
},
"settlement": {
"type": "object",
"properties": {
"asset": {
"const": "DePix"
},
"network": {
"const": "LIQUID"
},
"model": {
"const": "direct_to_customer"
}
},
"required": [
"asset",
"network",
"model"
]
},
"limits": {
"type": "object",
"additionalProperties": true
}
}
},
"Payer": {
"type": "object",
"additionalProperties": false,
"required": [
"name",
"document"
],
"properties": {
"name": {
"type": "string",
"minLength": 3,
"maxLength": 120
},
"document": {
"type": "string",
"maxLength": 20
},
"euid": {
"type": "string"
}
}
},
"CreatePayment": {
"type": "object",
"additionalProperties": false,
"required": [
"payer"
],
"oneOf": [
{
"required": [
"quote_id"
],
"not": {
"required": [
"amount_cents"
]
}
},
{
"required": [
"amount_cents"
],
"not": {
"required": [
"quote_id"
]
}
}
],
"properties": {
"quote_id": {
"type": "string",
"pattern": "^[a-f0-9]{32}Carregando a especificação pública…
quot;,
"description": "Cotação criada em POST /quotes. Quando informado, não envie amount_cents ou wallet_id."
},
"amount_cents": {
"type": "integer",
"minimum": 500
},
"payer": {
"$ref": "#/components/schemas/Payer"
},
"wallet_id": {
"type": "string",
"maxLength": 120
},
"external_reference": {
"type": "string",
"maxLength": 120
},
"new_payer_policy": {
"type": "string"
}
}
},
"Payment": {
"type": "object",
"required": [
"id",
"status",
"amount_cents"
],
"properties": {
"id": {
"type": "string"
},
"status": {
"type": "string"
},
"amount_cents": {
"type": "integer"
},
"net_amount_cents": {
"type": [
"integer",
"null"
]
},
"pix_code": {
"type": "string"
},
"external_reference": {
"type": "string"
},
"settlement_model": {
"type": "string"
},
"fees": {
"type": "object",
"additionalProperties": {
"type": "integer"
}
},
"created_at": {
"type": "string",
"format": "date-time"
},
"updated_at": {
"type": "string",
"format": "date-time"
},
"settled_at": {
"type": "string",
"format": "date-time"
}
}
},
"PaymentPage": {
"type": "object",
"required": [
"items",
"has_more"
],
"properties": {
"items": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Payment"
}
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": [
"string",
"null"
]
}
}
},
"Error": {
"type": "object",
"required": [
"error"
],
"properties": {
"error": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
}
}
}As ações autenticadas e as chaves ficam na sua conta.