NFT Payment Gateway API

Accept Telegram collectibles (TON NFTs) as payment. Create a payment, send your user to a hosted checkout, and receive a signed webhook once the collectible is received and forwarded to the treasury wallet.

Overview

Each payment generates a unique deposit address. When the user transfers an accepted collectible to it, the gateway verifies on-chain ownership, forwards the NFT to your main wallet, computes the buy price from the pricing list, and fires a webhook to your callback URL with the amount we paid.

Base URL

https://your-gateway.app

Auth

Bearer API key

Settlement

TON (nanoton)

Authentication

All operator endpoints require your API key in the Authorization header. Your key is issued in the admin panel and shown only once — store it securely.

Authorization: Bearer sk_live_xxxxxxxxxxxxxxxxxxxx

Payment flow

  1. 1Create a payment via the API. You receive a paymentId, a unique depositAddress, and a hosted checkoutUrl.
  2. 2Redirect the user to checkoutUrl. They connect their TON wallet and pick an accepted collectible.
  3. 3The user transfers the collectible to the deposit address. The gateway confirms ownership on-chain.
  4. 4The gateway forwards the NFT to the main treasury wallet (auto-funding gas if needed).
  5. 5Once forwarded, we compute the buy price from the pricing list and POST a signed webhook to your callback URL.

Create payment

POST/api/payments

Creates a payment request and derives a unique deposit subwallet. The nftAddress field is optional — if omitted, the user selects the collectible at checkout.

Request

curl -X POST https://your-gateway.app/api/payments \
  -H "Authorization: Bearer sk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{ "nftAddress": "EQ...optional" }'

Response 201

{
  "id": "8f3c...e21",
  "depositAddress": "EQB...deposit",
  "expectedOwner": "EQB...deposit",
  "nftAddress": null,
  "status": "pending",
  "checkoutUrl": "https://your-gateway.app/pay/8f3c...e21",
  "instructions": "Send the payer to checkoutUrl ..."
}

Check status

GET/api/payments

Lists your most recent payments. Each payment progresses through pending received, with forwarded and callbackSent flags marking the later stages.

curl https://your-gateway.app/api/payments \
  -H "Authorization: Bearer sk_live_xxx"

Collection whitelist

Only collections in the pricing list are accepted. At checkout, the user only sees collectibles from whitelisted collections, and any transfer of a non-whitelisted collectible is rejected server-side. The buy price for each collection is computed as:

buyPrice = averageSalePrice × margin × liquidityMultiplier

liquidityMultiplier = 0.85 + min((sales24h / totalSupply) × 10000, 100) / 100 × 0.45

Sale data is sourced from GetGems; the floor is 0.85× and the cap is 1.30×. Collections, supply overrides, and per-collection margin are managed in the admin Pricing tab.

Webhook callbacks

Set a callback URL per operator in the admin panel. After a collectible is received and forwarded to the treasury wallet, we POST the result to your URL. The body is signed with HMAC-SHA256 using your API key hash — verify the X-Signature header.

Webhook payload

POST <your callback URL>
X-Signature: <hmac-sha256 hex>
X-Payment-Id: 8f3c...e21

{
  "event": "payment.completed",
  "paymentId": "8f3c...e21",
  "nftAddress": "EQ...nft",
  "collectionAddress": "EQ...collection",
  "collectionName": "Easter Eggs",
  "payerWallet": "UQ...payer",
  "amount": "1.7965",
  "currency": "TON",
  "forwardedToMainWallet": true,
  "timestamp": "2026-06-28T12:00:00.000Z"
}

Verifying the signature (Node.js)

import crypto from "crypto"

function verify(rawBody, signature, apiKeyHash) {
  const expected = crypto
    .createHmac("sha256", apiKeyHash)
    .update(rawBody)
    .digest("hex")
  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(signature),
  )
}

Respond with a 2xx status to acknowledge. Non-2xx responses are retried on subsequent status checks until delivery succeeds.

Operator dashboard

Log in at /dashboard with your API key to view your own payment stats — totals, received volume, and a live feed of recent payments. The dashboard is scoped to your operator account only.