Crie cobranças em criptomoeda diretamente do seu sistema e libere o acesso do cliente automaticamente quando o pagamento confirmar.
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.
| Endereço da API | https://api.stackfy.io/v1 |
| Seu store_id | SEU_STORE_ID |
| Moeda padrão | BRL |
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.
POSThttps://api.stackfy.io/v1/invoices
| Campo | Obrigatório | Descrição |
|---|---|---|
price | sim | Valor (string), ex.: "49.90" |
currency | sim | Moeda do valor: BRL, USD, EUR… (ou USDT p/ preço direto em dólar 1:1, só com pay_currency=USDT) |
store_id | sim | Sua loja: SEU_STORE_ID |
pay_currency | não | Omitido = 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_url | não | Seu webhook (recebe o aviso de pago) |
redirect_url | não | Para onde mandar o cliente após pagar |
metadata | não | Objeto livre (ex.: seu id de pedido/usuário) |
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
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]"}
}'
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)
$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).
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.
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
}]
}
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.
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.
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"
}
A assinatura é HMAC-SHA256 do texto "<timestamp>.<corpo_cru>" usando o seu segredo. Compare em tempo constante. Mesmo esquema do Stripe.
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
});
$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);
complete (ou confirmed).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.
| status | Significado | Liberar acesso? |
|---|---|---|
pending | Aguardando pagamento | Não |
paid | Visto na rede, 0 confirmações | Ainda não (pode reverter) |
confirmed | Confirmado na rede (≥1 conf) | Sim |
complete | Pago e liquidado | Sim |
expired | Tempo esgotado sem pagar | Não |
invalid | Pagamento inválido | Não |
Dúvidas de integração? [email protected]