VKX Technologies Docs

VKX Pay

Você cobra em reais; quem paga escolhe a cripto. O valor do lojista e a taxa da VKX saem na mesma transação on-chain — ou as duas acontecem, ou nenhuma. Sem custódia em momento algum.

Começar

Antes do código: crie a conta em /pay/painel com sua conta Google e cadastre um endereço de carteira por rede. É a única configuração que existe.

npm install @vkx/pay
Se você não quiser escrever código, pare aqui: o painel gera link e QR Code de cobrança sozinho.

Criar a cobrança

No seu servidor — a chave secreta nunca vai para o navegador.

const { createPaymentIntent } = require('@vkx/pay');

const payment = await createPaymentIntent({
  apiKey: process.env.VKX_PAY_SECRET_KEY,   // sk_vkxpay_...
  amount: '199.90',                          // reais, string
  orderId: pedido.id,                        // o id no SEU sistema
});

// payment.checkoutUrl → mande o pagador para cá
// (botão no site, link no WhatsApp, QR no balcão)

Parâmetros

CampoObrigatórioDescrição
apiKeysimSua chave secreta sk_vkxpay_...
amountsimValor em reais, como string: '199.90'
orderIdnãoId do pedido no seu sistema — volta no webhook
metadatanãoObjeto livre, guardado com a cobrança
expiresInSecondsnãoValidade da cobrança (padrão 1800, entre 120 e 86400)

Receber a confirmação

Quando a blockchain confirma, a VKX chama sua URL. Use o corpo cru da requisição — antes de qualquer JSON.parse do framework.

const { constructWebhookEvent } = require('@vkx/pay');

app.post('/webhooks/vkx', express.raw({ type: 'application/json' }), (req, res) => {
  const event = constructWebhookEvent({
    secret: process.env.VKX_PAY_WEBHOOK_SECRET,   // whsec_...
    body: req.body,
    signature: req.headers['x-vkx-signature'],
  });

  if (event.event === 'payment.completed') {
    liberarPedido(event.data.orderId);
  }
  res.sendStatus(200);
});

A assinatura chega como t=<unix>,v1=<hmac>, um HMAC-SHA256 de "<t>.<corpo>". O SDK recusa corpo adulterado, segredo errado e requisição antiga (mais de 5 minutos).

Corpo do evento

{
  "event": "payment.completed",
  "createdAt": "2026-08-15T18:30:44.603Z",
  "data": {
    "paymentIntentId": "pay_c-M_7otXmizP",
    "orderId": "PEDIDO-123",
    "amount": "199.90",
    "currency": "BRL",
    "network": "bsc",
    "txHash": "0x…",
    "payer": "0x…",
    "confirmedAt": "2026-08-15T18:31:02.114Z"
  }
}

Eventos: payment.completed e payment.expired. Responda 2xx; a VKX repete a entrega com espera crescente (1min, 5min, 30min, 2h, 6h, 12h, 24h) até desistir.

Estados de uma cobrança

EstadoSignifica
OPENCriada, esperando pagamento
PENDINGTransação vista na blockchain, aguardando confirmações
PAIDConfirmada — o webhook foi disparado
EXPIREDVenceu sem pagamento
CANCELEDCancelada por você antes do pagamento
REFUNDED_EXTERNALDevolvida por fora e registrada no histórico
Reembolso executado pelo painel está em desenvolvimento. Hoje você devolve pela sua carteira e registra a devolução.

Redes e moedas

RedeMoedasConfirmações
BNB ChainUSDT, USDC, USD1, BNB3
PolygonUSDT, USDC, POL30
BaseUSDC, ETH12
SolanaUSDC, SOLfinalizada

Moedas nativas são opcionais — você liga no painel se quiser aceitá-las. A cotação em reais é congelada durante o checkout (cerca de 5 minutos em stablecoin, menos em moeda nativa, que oscila mais).

Endpoints REST

Se você não usa Node.js, fale direto com a API. Base: https://api.vkxtech.com.br

MétodoRotaO que faz
POST/pay/v1/payment-intentsCria a cobrança
GET/pay/v1/payment-intents/:idConsulta status e pagamentos
POST/pay/v1/payment-intents/:id/cancelCancela antes do pagamento
POST/pay/v1/payment-intents/:id/refunded-externalRegistra devolução feita por fora
PUT/pay/v1/walletsDefine onde receber em cada rede
POST/pay/v1/webhook-endpointsCadastra a URL do webhook
GET/pay/v1/meResumo de vendas (aceita chave de leitura)
curl -X POST https://api.vkxtech.com.br/pay/v1/payment-intents \
  -H "Authorization: Bearer sk_vkxpay_..." \
  -H "Content-Type: application/json" \
  -d '{"amount":"199.90","orderId":"PEDIDO-123"}'

Outras linguagens

O pacote npm é conveniência, não requisito. O VKX Pay é uma API REST com JSON: qualquer linguagem que faça uma requisição HTTP integra — PHP, Python, Ruby, Go, Java, C#, Elixir, o que você usar.

São só duas operações: criar a cobrança (uma requisição autenticada) e validar o webhook (um HMAC-SHA256, que toda linguagem tem na biblioteca padrão).

Python

import requests, hmac, hashlib, time

# criar a cobrança
r = requests.post(
    "https://api.vkxtech.com.br/pay/v1/payment-intents",
    headers={"Authorization": f"Bearer {VKX_PAY_SECRET_KEY}"},
    json={"amount": "199.90", "orderId": pedido_id},
).json()
checkout_url = r["checkoutUrl"]

# validar o webhook
def valido(corpo_cru: bytes, header: str, segredo: str) -> bool:
    partes = dict(p.split("=", 1) for p in header.split(","))
    t = int(partes["t"])
    if abs(time.time() - t) > 300:
        return False
    esperado = hmac.new(segredo.encode(),
                        f"{t}.".encode() + corpo_cru,
                        hashlib.sha256).hexdigest()
    return hmac.compare_digest(esperado, partes["v1"])

Go

body, _ := json.Marshal(map[string]string{"amount": "199.90", "orderId": pedidoID})
req, _ := http.NewRequest("POST", apiBase+"/pay/v1/payment-intents", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("VKX_PAY_SECRET_KEY"))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)

Qualquer coisa que rode cURL

curl -X POST https://api.vkxtech.com.br/pay/v1/payment-intents \
  -H "Authorization: Bearer $VKX_PAY_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount":"199.90","orderId":"PEDIDO-123"}'
Sem servidor nenhum? Gere a cobrança pelo painel e use o link ou o QR Code. Serve para landing page estática, Instagram, WhatsApp e balcão físico.

WordPress

WordPress é PHP, então a integração usa wp_remote_post — sem plugin e sem dependência externa. Cole no functions.php do seu tema (ou num plugin próprio):

<?php
function vkx_criar_cobranca($valor, $pedido_id) {
    $resposta = wp_remote_post('https://api.vkxtech.com.br/pay/v1/payment-intents', [
        'headers' => [
            'Authorization' => 'Bearer ' . VKX_PAY_SECRET_KEY,
            'Content-Type'  => 'application/json',
        ],
        'body' => wp_json_encode([
            'amount'  => $valor,        // '199.90'
            'orderId' => $pedido_id,
        ]),
        'timeout' => 20,
    ]);

    if (is_wp_error($resposta)) return null;
    $dados = json_decode(wp_remote_retrieve_body($resposta), true);
    return $dados['checkoutUrl'] ?? null;   // redirecione o comprador para cá
}

// Webhook: registre uma rota REST e valide a assinatura
add_action('rest_api_init', function () {
    register_rest_route('vkx/v1', '/webhook', [
        'methods'  => 'POST',
        'permission_callback' => '__return_true',
        'callback' => function (WP_REST_Request $req) {
            $corpo  = $req->get_body();                       // corpo CRU
            $header = $req->get_header('x-vkx-signature');
            parse_str(str_replace(',', '&', $header), $p);   // t=...,v1=...

            if (abs(time() - (int) $p['t']) > 300) return new WP_REST_Response('velho', 400);
            $esperado = hash_hmac('sha256', $p['t'] . '.' . $corpo, VKX_PAY_WEBHOOK_SECRET);
            if (!hash_equals($esperado, $p['v1'])) return new WP_REST_Response('invalido', 400);

            $evento = json_decode($corpo, true);
            if ($evento['event'] === 'payment.completed') {
                // marque o pedido como pago: $evento['data']['orderId']
            }
            return new WP_REST_Response('ok', 200);
        },
    ]);
});

Em WooCommerce, chame vkx_criar_cobranca() no seu gateway e redirecione para a checkoutUrl; no webhook, use $order->payment_complete().

Um plugin oficial de WooCommerce está em desenvolvimento. Até lá, o trecho acima é a integração completa.

React / Next.js

A chave secreta nunca vai para o browser. Crie a cobrança no servidor e devolva só a URL do checkout.

// app/api/pagar/route.ts  (Next.js App Router)
import { createPaymentIntent } from '@vkx/pay';

export async function POST(req: Request) {
  const { orderId, total } = await req.json();
  const payment = await createPaymentIntent({
    apiKey: process.env.VKX_PAY_SECRET_KEY!,
    amount: total,
    orderId,
  });
  return Response.json({ checkoutUrl: payment.checkoutUrl });
}
// componente do cliente
async function pagar() {
  const r = await fetch('/api/pagar', {
    method: 'POST',
    body: JSON.stringify({ orderId: pedido.id, total: '199.90' }),
  }).then((r) => r.json());
  window.location.assign(r.checkoutUrl);
}

Chaves de API

ChavePodeOnde usar
sk_vkxpay_…Criar cobranças, configurar a contaSó no seu servidor
rk_vkxpay_…Somente leitura: consultar vendasPainéis e aplicativos
whsec_…Validar a assinatura do webhookSó no seu servidor

Cada chave aparece uma única vez ao ser criada — guardamos apenas um hash. Perdeu? Gere outra e revogue a anterior no painel.

Painel no celular

Gere uma chave rk_ no painel e use no aplicativo VKX Wallet para acompanhar as vendas do celular. Como ela é somente leitura, não cria cobrança nem move fundos, mesmo que o aparelho se perca.

curl https://api.vkxtech.com.br/pay/v1/me \
  -H "Authorization: Bearer rk_vkxpay_..."

A resposta traz volume do dia, volume total, número de vendas, ticket médio, movimentação por rede e as últimas cobranças.