Developers

Developers

Accept crypto anywhere. Create payments with your API key and get signed webhooks (IPN) on every payment event.

1Create a payment
2Redirect to checkout
3Verify the webhook

API credentials

Authenticate server-to-server requests. Treat keys like passwords — never ship them to the browser.

Base URL

https://server.stackalpha.xyz

Webhooks (IPN)

We POST a signed notification to your callback on every payment event.

IPN secret

Signs the x-egofi-signature header

Quickstart

Three steps to accept crypto on your site.

1

Create a payment (server-side, with your API key)

bash
curl -X POST https://server.stackalpha.xyz/invoices \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "displayCurrency": "USD",
    "displayAmount": "49.99",
    "payAsset": "USDT",
    "payChain": "TRON",
    "refundAddress": "OPTIONAL_CUSTOMER_REFUND_ADDRESS",
    "metadata": { "orderId": "ORDER-1234" }
  }'

# Response → { "id": "inv_...", ... }
# Redirect your customer to the hosted checkout:
#   https://checkout.stackalpha.xyz/pay/{id}
2

What we POST to your callback

http
POST  https://your-store.com/webhooks/egofi
Headers:
  Content-Type: application/json
  x-egofi-signature: sha256=<hmac-sha256 hex of the raw body>

Body:
{
  "id": "<delivery id>",
  "event": "invoice.paid",
  "invoiceId": "inv_...",
  "merchantId": "mch_...",
  "data": {
    "invoiceId": "inv_...",
    "merchantId": "mch_...",
    "state": "PAID_CONFIRMED",
    "previousState": "CONVERTING"
  },
  "timestamp": "2026-07-04T10:00:00.000Z"
}

# events: invoice.paid · invoice.failed · invoice.expired
#         invoice.underpaid · invoice.refunded · invoice.compliance_hold
3

Verify the signature, then fulfil the order

node.js
import crypto from "node:crypto";

// IMPORTANT: verify against the RAW request body, before JSON parsing.
app.post("/webhooks/egofi", express.raw({ type: "*/*" }), (req, res) => {
  const signature = req.headers["x-egofi-signature"];       // "sha256=..."
  const expected =
    "sha256=" +
    crypto.createHmac("sha256", process.env.EGOFI_IPN_SECRET)
      .update(req.body)                                     // raw Buffer
      .digest("hex");

  const ok =
    signature &&
    crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
  if (!ok) return res.status(401).send("bad signature");

  const event = JSON.parse(req.body.toString());
  if (event.event === "invoice.paid") {
    // ✅ mark order ${event.data.invoiceId} as paid
  }
  res.sendStatus(200);
});