Stackfy

Documentação da API

Crie cobranças em criptomoeda diretamente do seu sistema e libere o acesso do cliente automaticamente quando o pagamento confirmar.

Como funciona

O fluxo típico de uma integração (assinatura, hospedagem, streaming):

1. Seu sistema cria uma cobrança via API  →  POST https://api.stackfy.io/v1/invoices
2. Você leva o cliente ao pagamento  →  link de checkout OU QR transparente
3. O cliente paga em criptomoeda
4. A Stackfy chama o seu webhook  →  POST na sua notification_url
5. Você confirma a cobrança pela API  →  GET https://api.stackfy.io/v1/invoices/{id}
6. Status "complete"  →  você libera/renova o acesso do cliente

Recorrência: criptomoeda não tem débito automático — a cada ciclo, seu sistema repete o passo 1.

Dados da sua conta

Endereço da APIhttps://api.stackfy.io/v1
Seu store_idSEU_STORE_ID
Moeda padrãoBRL

Autenticação

Crie uma chave em API e integração e envie no cabeçalho de toda chamada:

Authorization: Bearer SUA_CHAVE

A chave dá acesso à sua conta — guarde como uma senha. Se vazar, revogue na hora pelo painel.

Criar uma cobrança

POSThttps://api.stackfy.io/v1/invoices

CampoObrigatórioDescrição
pricesimValor (string), ex.: "49.90"
currencysimMoeda do valor: BRL, USD, EUR… (ou USDT p/ preço direto em dólar 1:1, só com pay_currency=USDT)
store_idsimSua loja: SEU_STORE_ID
pay_currencynãoOmitido = multi-moeda (o comprador escolhe a cripto — veja abaixo). Para FIXAR a rede: BTC, USDT (Tron/TRC-20) ou USDT-MATIC (Polygon). Fixar USDT exige a loja com endereço da rede. O price segue em fiat.
notification_urlnãoSeu webhook (recebe o aviso de pago)
redirect_urlnãoPara onde mandar o cliente após pagar
metadatanãoObjeto livre (ex.: seu id de pedido/usuário)

Multi-moeda — o comprador escolhe a criptomoeda

Basta omitir o campo pay_currency: a Stackfy cria um pedido e o comprador escolhe entre BTC, USDT-Tron e USDT-Polygon na tela de pagamento (as opções dependem do que a loja tem habilitado). O price segue em fiat; a conversão é feita na cotação do momento, quando o comprador escolhe. A resposta traz pay_currency: "ANY" e o checkout_url do seletor.

curl -X POST https://api.stackfy.io/v1/invoices \
  -H "Authorization: Bearer SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -d '{
    "price": "49.90",
    "currency": "BRL",
    "store_id": "SEU_STORE_ID"
  }'
# sem pay_currency = o comprador escolhe a cripto no checkout

Exemplo — cURL

curl -X POST https://api.stackfy.io/v1/invoices \
  -H "Authorization: Bearer SUA_CHAVE" \
  -H "Content-Type: application/json" \
  -d '{
    "price": "49.90",
    "currency": "BRL",
    "store_id": "SEU_STORE_ID",
    "notification_url": "https://seusite.com/webhooks/stackfy",
    "metadata": {"pedido": "1234", "usuario": "[email protected]"}
  }'

Exemplo — Node.js

const r = await fetch("https://api.stackfy.io/v1/invoices", {
  method: "POST",
  headers: {
    "Authorization": "Bearer " + process.env.STACKFY_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    price: "49.90", currency: "BRL", store_id: "SEU_STORE_ID",
    notification_url: "https://seusite.com/webhooks/stackfy",
    metadata: { pedido: "1234" },
  }),
});
const invoice = await r.json();
// invoice.id  -> guarde no seu pedido
// redirecione o cliente para o checkout (ver abaixo)

Exemplo — PHP

$ch = curl_init("https://api.stackfy.io/v1/invoices");
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_POST => true,
  CURLOPT_HTTPHEADER => [
    "Authorization: Bearer " . getenv("STACKFY_KEY"),
    "Content-Type: application/json",
  ],
  CURLOPT_POSTFIELDS => json_encode([
    "price" => "49.90", "currency" => "BRL", "store_id" => "SEU_STORE_ID",
    "notification_url" => "https://seusite.com/webhooks/stackfy",
  ]),
]);
$invoice = json_decode(curl_exec($ch), true);

A resposta é a cobrança criada, com id, status ("pending") e os métodos de pagamento em payments (endereço, valor em cripto e URI para QR).

Levar o cliente ao pagamento

Opção A — Redirect (mais simples)

Mande o cliente para o checkout pronto da Stackfy, usando o id da cobrança:

https://pay.stackfy.io/c/<invoice_id>

O cliente vê o QR, paga e (se você definiu redirect_url) volta ao seu site.

Opção B — Transparente (no seu layout)

Use os dados de payments da resposta para montar o seu próprio QR/endereço:

{
  "id": "...",
  "status": "pending",
  "payments": [{
    "payment_address": "bc1q...",        // endereço para receber
    "amount": "0.00071",                 // valor em cripto
    "currency": "BTC",
    "payment_url": "bitcoin:bc1q...?amount=0.00071"  // vira QR
  }]
}

Webhook (confirmação de pagamento)

Quando a cobrança é paga, a Stackfy faz um POST assinado no seu servidor. Você confere a assinatura com o seu segredo e pronto — não precisa re-consultar nada.

1. Configure

Em API e integração, salve a URL do seu servidor (recebe o aviso) e copie o seu segredo de assinatura (whsec_…). Não precisa configurar notification_url: toda cobrança criada pela Stackfy (API https://api.stackfy.io/v1 ou painel) já aponta sozinha para o nosso relay.

A Stackfy recebe a confirmação, confere o status real da cobrança internamente e só então reenvia, já assinado, para o seu servidor.

2. O que chega no seu servidor

Cabeçalho X-Stackfy-Signature: t=<timestamp>,v1=<hmac_sha256> e corpo JSON:

{
  "id": "<invoice_id>",
  "status": "complete",
  "price": "49.90",
  "currency": "BRL",
  "paid_currency": "BTC",
  "metadata": { "pedido": "1234" },
  "store_id": "SEU_STORE_ID"
}

3. Valide a assinatura

A assinatura é HMAC-SHA256 do texto "<timestamp>.<corpo_cru>" usando o seu segredo. Compare em tempo constante. Mesmo esquema do Stripe.

Node.js / Express

const crypto = require("crypto");
// use o corpo CRU (raw), não o JSON já parseado:
app.post("/webhooks/stackfy", express.raw({type:"*/*"}), (req, res) => {
  const raw = req.body.toString("utf8");
  const [t, v1] = req.headers["x-stackfy-signature"].split(",")
                    .map(p => p.split("=")[1]);
  const expected = crypto.createHmac("sha256", process.env.STACKFY_WHSEC)
                         .update(t + "." + raw).digest("hex");
  const ok = crypto.timingSafeEqual(Buffer.from(v1), Buffer.from(expected));
  if (!ok) return res.status(401).end();              // forjado -> rejeita

  const ev = JSON.parse(raw);
  if (ev.status === "complete") liberar(ev.metadata.pedido);
  res.status(200).end();                               // responda 200 rápido
});

PHP

$raw = file_get_contents("php://input");
parse_str(str_replace(",", "&", $_SERVER["HTTP_X_STACKFY_SIGNATURE"]), $sig);
$expected = hash_hmac("sha256", $sig["t"] . "." . $raw, getenv("STACKFY_WHSEC"));
if (!hash_equals($expected, $sig["v1"])) { http_response_code(401); exit; }

$ev = json_decode($raw, true);
if ($ev["status"] === "complete") liberar_acesso($ev["metadata"]["pedido"]);
http_response_code(200);
Boas práticas: use o corpo cru (não re-serialize o JSON antes de validar); o webhook pode chegar mais de uma vez para a mesma cobrança → trate de forma idempotente; libere o acesso em complete (ou confirmed).

Alternativa: sem webhook (polling)

Se preferir não expor um endpoint, consulte o status quando quiser: GEThttps://api.stackfy.io/v1/invoices/<id> com a sua chave. A verdade está sempre na API.

Referência de status

statusSignificadoLiberar acesso?
pendingAguardando pagamentoNão
paidVisto na rede, 0 confirmaçõesAinda não (pode reverter)
confirmedConfirmado na rede (≥1 conf)Sim
completePago e liquidadoSim
expiredTempo esgotado sem pagarNão
invalidPagamento inválidoNão

Dúvidas de integração? [email protected]

© 2026 Stackfy · stackfy.io · Criar conta grátis · Termos · Privacidade