PayXif
Home

PayXif API v1

Accept crypto payments from any app, website, game or Telegram bot. Base URL https://api.payxif.com. Every response is JSON:

{ "ok": true,  "data":  { ... } }
{ "ok": false, "error": { "code": "unsupported_currency", "message": "..." } }

You create an invoice for an amount in USD (or a specific coin). The customer opens the hosted checkout, picks any coin you accept, and pays. When the payment confirms on-chain, PayXif credits your wallet and sends a signed webhook so your app can deliver the product automatically. No KYC, no accounts for your customers.

Quickstart

  1. In the dashboard open Merchant service → create an API key (starts with pxk_live_). Set a default Webhook URL.
  2. Create an invoice from your backend (below) and redirect the customer to data.pay_link.
  3. Receive the invoice.paid webhook, verify its signature, and fulfil the order.
curl -X POST https://api.payxif.com/v1/invoices \
  -H "X-API-Key: pxk_live_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "amount_usd": "49.99",
    "order_id": "A-1042",
    "description": "Pro plan - 1 month",
    "callback_url": "https://shop.example/payxif/webhook",
    "return_url": "https://shop.example/thanks"
  }'

Response:

HTTP/1.1 201 Created
{
  "ok": true,
  "data": {
    "track_id":   "a1B2c3D4",
    "status":     "new",
    "amount_usd": "49.99",
    "currency":   null,          // set once the customer picks a coin
    "network":    null,
    "address":    null,          // a deposit address is created after coin choice
    "pay_link":   "https://payxif.com/pay/a1B2c3D4",
    "order_id":   "A-1042",
    "fee":        "0",
    "expires_at": "2026-08-29T12:34:56+00:00",
    "expires_in": 3600,
    "created_at": "2026-08-29T11:34:56+00:00"
  }
}

Authentication

Send the merchant API key in any of these headers. Keys start with pxk_live_ (mainnet) or pxk_test_ (testnet). Payout keys start with pxp_ and are used only for the Payout API.

X-API-Key: pxk_live_xxxxxxxx
Authorization: Bearer pxk_live_xxxxxxxx
merchant_api_key: pxk_live_xxxxxxxx

Create invoice

POST /v1/invoices — price in USD (customer picks the coin at checkout) or in a specific coin with amount + currency.

amount_usdstringUSD amount, e.g. "49.99" — customer chooses the coin. Either this OR amount+currency.
amountstringcoin amount, e.g. "25.50" (use with currency)
currencystringUSDT, TRX, USDC, … (with amount)
networkstringTRON (default), BSC, ETH, POLYGON
order_idstringyour reference, echoed in every webhook
descriptionstringshown on the payment page
emailstringcustomer email (optional)
callback_urlurlwebhook for this invoice (falls back to your merchant default)
return_urlurlwhere the customer returns after paying
lifetimeintminutes, 5–1440, default 60 — the USD→coin rate is locked until expiry
underpaid_covernumber% shortfall still accepted as paid (0–60)
fee_paid_by_payerbooladd the service fee on top of the customer total
mixed_paymentboolallow several transfers / coins until the USD total is reached
metadataobjectup to 20 keys, echoed back in webhooks (great for a Telegram chat id)
curl -X POST https://api.payxif.com/v1/invoices \
  -H "X-API-Key: pxk_live_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "amount_usd": "49.99",
    "order_id": "A-1042",
    "description": "Pro plan - 1 month",
    "callback_url": "https://shop.example/payxif/webhook",
    "return_url": "https://shop.example/thanks"
  }'

Get & list invoices

GET /v1/invoices/{track_id}     # one invoice, includes txs[] with confirmations
GET /v1/invoices?status=paid&order_id=A-1042&page=1&per_page=25
GET /v1/balance                 # your wallet balances
GET /v1/me                      # merchant profile, fee %, network mode
GET /v1/currencies              # public: enabled coins & networks

USD pricing & payer coin choice

Invoices created with amount_usd open a checkout where the customer picks any accepted coin. The USD→coin rate locks the moment they choose, until the invoice expires. With mixed_payment the invoice settles by accumulated USD value, allowing several transfers — even in different coins.

Donations for creators (buy me a coffee)

Perfect for streamers, YouTubers, and developers who want tips / “buy me a coffee” in crypto — no store, no code required. In the dashboard open Donation service → create a donation link. The supporter opens it, chooses any amount and any coin you accept, and pays. You can brand it (logo, colour, thanks message) and embed a button anywhere.

Embed the donate button on your site, channel page or blog:

<a href="https://payxif.com/pay/d/coffee4dev" target="_blank" rel="noopener">
  ☕ Buy me a coffee (crypto)
</a>

Live donation alerts. Point the donation link’s webhook at your overlay/bot and every tip fires an invoice.paid event — show it on a stream overlay, in Discord, or as a Telegram message in seconds:

// on invoice.paid (see Webhooks), broadcast to your stream overlay
io.emit("tip", {
  amount: e.paid_amount + " " + e.currency,   // "5 USDT"
  from:   e.metadata?.name || "Anonymous",
  note:   e.description,
});

Invoice statuses

newUSD invoice waiting for the customer to pick a coin
waitingcoin chosen, nothing received yet
confirmingtransfer seen on chain, waiting for confirmations (~1 min on Tron)
paidconfirmed amount ≥ requested — wallet credited (event invoice.paid)
underpaidbelow requested; the address stays open for top-up until expiry
expireddeadline passed — a late payment still credits your wallet (invoice.paid_late)

Webhooks

PayXif POSTs JSON to your callback_url with an HMAC-SHA512 signature of the raw body. Events: invoice.confirming · invoice.paid · invoice.underpaid · invoice.expired · invoice.paid_late. Reply 2xx within 10s; failed deliveries retry with backoff over 8 attempts. Deliveries are idempotent — always key off track_id and ignore an event you already processed.

Example delivery:

POST https://shop.example/payxif/webhook
X-PayXif-Event:     invoice.paid
X-PayXif-Delivery:  1234
X-PayXif-Signature: <hex hmac_sha512(raw_body, webhook_secret)>

{
  "event":        "invoice.paid",
  "type":         "invoice",
  "track_id":     "a1B2c3D4",
  "order_id":     "A-1042",
  "status":       "paid",
  "currency":     "USDT",
  "network":      "TRON",
  "amount":       "49.99",
  "paid_amount":  "49.99",
  "pending_amount": "0",
  "fee":          "0.50",
  "address":      "TR7N...Lj6t",
  "email":        null,
  "description":  "Pro plan - 1 month",
  "metadata":     { "chat_id": 1122334455 },
  "txs": [{ "txid": "7f3a...c91d", "amount": "49.99", "confirmations": 41, "status": "credited" }],
  "paid_at":      "2026-08-29T11:41:03+00:00",
  "expires_at":   "2026-08-29T12:34:56+00:00",
  "sent_at":      "2026-08-29T11:41:04+00:00"
}

Verify the signature before trusting the body:

<?php
$secret = "whsec_your_merchant_webhook_secret";     // Merchant service -> Webhook secret
$body   = file_get_contents("php://input");          // the RAW body (do not re-encode)
$sig    = $_SERVER["HTTP_X_PAYXIF_SIGNATURE"] ?? "";

if (!hash_equals(hash_hmac("sha512", $body, $secret), $sig)) {
    http_response_code(401);
    exit;
}
$e = json_decode($body, true);
if ($e["event"] === "invoice.paid") {
    // fulfil the order: $e["order_id"], $e["paid_amount"], $e["metadata"]
}
http_response_code(200);

Telegram bots — accept crypto, 0 → 100

Want a Telegram bot that sells a file, a subscription, VIP access or a service and gets paid in crypto automatically? Here is the full flow. You do not touch private keys or wallets — PayXif handles the chain and credits your wallet.

  1. Create a merchant key in the dashboard (Merchant service). Copy the webhook secret too.
  2. When a user taps Buy, your bot calls POST /v1/invoices with order_id: "tg:<user id>" and metadata.chat_id so you know who to deliver to.
  3. Send the user an inline button linking to data.pay_link. They pick a coin and pay on the hosted checkout.
  4. PayXif sends invoice.paid to your webhook. Verify the signature, then deliver the product to metadata.chat_id with the Bot API.

Complete example — bot + webhook in one file:

import { Telegraf, Markup } from "telegraf";
import express from "express";
import crypto from "crypto";

const bot     = new Telegraf(process.env.BOT_TOKEN);
const API_KEY = "pxk_live_xxxxxxxx";                 // PayXif merchant key
const SECRET  = process.env.PAYXIF_SECRET;           // PayXif webhook secret

// 1) the customer starts a purchase inside your bot
bot.command("buy", async (ctx) => {
  const res = await fetch("https://api.payxif.com/v1/invoices", {
    method: "POST",
    headers: { "X-API-Key": API_KEY, "Content-Type": "application/json" },
    body: JSON.stringify({
      amount_usd:   "5.00",
      order_id:     "tg:" + ctx.from.id,             // who to deliver to
      description:  "VIP access - 1 month",
      metadata:     { chat_id: ctx.chat.id },        // comes back in the webhook
      callback_url: "https://yourbot.example/payxif/webhook",
    }),
  });
  const { data } = await res.json();

  // 2) send them a one-tap Pay button (opens the hosted crypto checkout)
  await ctx.reply("Pay with crypto to unlock VIP 👇",
    Markup.inlineKeyboard([Markup.button.url("💳 Pay $5", data.pay_link)]));
});

// 3) PayXif calls you the moment it is paid -> deliver automatically
const app = express();
app.post("/payxif/webhook", express.raw({ type: "*/*" }), async (req, res) => {
  const sig = req.get("X-PayXif-Signature") || "";
  const mac = crypto.createHmac("sha512", SECRET).update(req.body).digest("hex");
  if (mac.length !== sig.length || !crypto.timingSafeEqual(Buffer.from(mac), Buffer.from(sig)))
    return res.sendStatus(401);

  const e = JSON.parse(req.body.toString());
  if (e.event === "invoice.paid") {
    await bot.telegram.sendMessage(e.metadata.chat_id,
      "✅ Payment received! Here is your VIP link: https://t.me/+abc123");
  }
  res.sendStatus(200);   // reply 2xx within 10s or PayXif retries
});

bot.launch();
app.listen(3000);

Tips

  • Put the buyer’s Telegram chat id in metadata — it comes straight back in the webhook, so you always know whom to deliver to.
  • Reply 2xx fast and deliver asynchronously; if you crash, PayXif retries the webhook.
  • Use a pxk_test_ key + Tron Nile testnet to try the whole flow with no real funds.
  • Prefer the hosted pay_link — your bot never has to display addresses or handle coins itself.

Payout API

Programmatic withdrawals with a payout-scoped key (pxp_…, created in Payout API with password + 2FA and an optional IP allowlist). Key possession is the auth — no OTP per call.

curl -X POST https://api.payxif.com/v1/payout \
  -H "X-API-Key: pxp_live_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{"address":"TR7N...Lj6t","amount":"25","currency":"USDT","network":"TRON","description":"affiliate payout"}'
GET /v1/payouts       # list payouts made through the API
GET /v1/payout/{id}   # single payout with status, txid + explorer url

Wallet & balance

Every confirmed payment lands in your central wallet. Read balances with the API, or manage funds (deposit, send, internal transfer) from the dashboard wallet.

GET /v1/balance
# { "ok": true, "data": [ { "currency": "USDT", "network": "TRON", "balance": "1240.50", "usd": 1240.50 }, ... ] }

Errors & limits

401 unauthorizedmissing/invalid key, wrong OTP or withdrawal password
403 ip_not_allowedcaller IP not on the key's allowlist
429 rate_limitedover 120 req/min per key — back off
400 amount_too_smallbelow the coin's minimum
400 withdrawal_uneconomicfee would not cover network cost — raised automatically
503 maintenanceshort maintenance window, retry with backoff