API Documentation

Raw Markdown

Accept crypto payments on your platform with a simple REST API. Multi-chain support, real-time webhooks, 0.4% fees.

Overview

The CryptoSetype API lets you create crypto payment invoices, track their status, and receive webhook notifications when payments are confirmed on-chain. All responses are JSON. All timestamps are Unix milliseconds.

Supported currencies: USDT (TRC-20, ERC-20, BEP-20, Solana), USDC (ERC-20, BEP-20, Solana), BTC, ETH, SOL, BNB, LTC — 12 payment methods across 6 chains.

Quick start: Create a store in your dashboard, get your API key, then call POST /api/payments to create your first payment.

Base URL

https://crypto.setype.com

All API endpoints are relative to this base URL.

Authentication

Authenticate requests with your store's API key in the X-API-Key header. Your API key is shown once when you create a store — save it securely.

# Every authenticated request must include:
X-API-Key: sk_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6
DetailValue
HeaderX-API-Key
Formatsk_ + 48 hex characters (56 chars total)
StorageBcrypt hashed on server — cannot be retrieved after creation
ScopeEach key is bound to a single store
Keep your API key secret. If compromised, regenerate it immediately via POST /api/stores/:id/regenerate-key.

Errors

All errors return a JSON object with an error field:

{
  "error": "Human-readable error message"
}
HTTP CodeMeaning
400Bad request — missing or invalid parameters
401Unauthorized — missing or invalid API key
404Not found — resource doesn't exist or doesn't belong to your store
409Conflict — resource already processed (e.g., double-approval)
503No wallets available — try again in a few seconds

Create Payment

POST /api/payments X-API-Key required

Create a new payment invoice. The customer sends crypto to the returned address.

Request Body

ParameterTypeDescription
amount number required Amount to charge (0.01 – 1,000,000)
currency string required USD for multi-chain checkout, or specific coin: USDT, BTC, ETH, SOL, BNB, LTC
order_id string optional Your internal order ID, returned in webhooks
webhook_url string optional Override store's default webhook URL for this payment
success_url string optional Redirect URL after successful payment (for hosted checkout)
fail_url string optional Redirect URL if payment expires or fails
metadata object optional Arbitrary JSON object, returned in webhooks

Response 201 Created

{
  "id": "pay_a1b2c3d4e5f6g7h8",
  "payment_url": "https://crypto.setype.com/pay/pay_a1b2c3d4e5f6g7h8",
  "address": "TGGrCNwFuzrJbJPHx4pWm6jfgxz5xVVvvv",
  "amount": 25.00,
  "currency": "USDT",
  "chain": "tron",
  "status": "pending",
  "expires_at": 1712345678000
}
Multi-chain checkout: Pass "currency": "USD" to let the customer choose their preferred coin (BTC, ETH, USDT, etc.) on the payment page. The address will be null until the customer selects a chain.

Example: Direct USDT payment

curl -X POST https://crypto.setype.com/api/payments \
  -H "Content-Type: application/json" \
  -H "X-API-Key: sk_your_api_key_here" \
  -d '{
    "amount": 25.00,
    "currency": "USDT",
    "order_id": "order_123",
    "webhook_url": "https://yoursite.com/webhook"
  }'

Example: Multi-chain (customer chooses coin)

curl -X POST https://crypto.setype.com/api/payments \
  -H "Content-Type: application/json" \
  -H "X-API-Key: sk_your_api_key_here" \
  -d '{
    "amount": 50.00,
    "currency": "USD",
    "order_id": "order_456"
  }'

Example: Pay with Bitcoin

curl -X POST https://crypto.setype.com/api/payments \
  -H "Content-Type: application/json" \
  -H "X-API-Key: sk_your_api_key_here" \
  -d '{
    "amount": 0.001,
    "currency": "BTC",
    "order_id": "order_789"
  }'

Example: USDT on Ethereum (ERC-20)

curl -X POST https://crypto.setype.com/api/payments \
  -H "Content-Type: application/json" \
  -H "X-API-Key: sk_your_api_key_here" \
  -d '{
    "amount": 100.00,
    "currency": "USDT",
    "chain": "ethereum",
    "order_id": "order_erc20"
  }'
Token payments: When currency is USDT or USDC, use the chain parameter to select the network: tron (default for USDT), ethereum (ERC-20), bnb (BEP-20), or solana (SPL).

Get Payment

GET /api/payments/:id X-API-Key required

Retrieve full details of a payment. Only returns payments belonging to your store.

Response 200 OK

{
  "id": "pay_a1b2c3d4e5f6g7h8",
  "order_id": "order_123",
  "address": "TGGrCNwFuzrJbJPHx4pWm6jfgxz5xVVvvv",
  "expected_amount": 25.00,
  "expected_crypto": "USDT",
  "received_amount": 25.00,
  "tx_hash": "abc123def456...",
  "status": "confirmed",
  "expires_at": 1712345678000,
  "confirmed_at": 1712344000000,
  "created_at": 1712343000000
}

List Payments

GET /api/payments X-API-Key required

List all payments for your store, newest first.

Query Parameters

ParameterTypeDescription
statusstringoptionalFilter: pending, confirmed, expired, cancelled
limitintegeroptionalMax results (default: 50)
offsetintegeroptionalPagination offset (default: 0)

Response 200 OK

[
  {
    "id": "pay_a1b2c3d4e5f6g7h8",
    "order_id": "order_123",
    "address": "TGGrCNwFuzrJbJPHx4pWm6jfgxz5xVVvvv",
    "expected_amount": 25.00,
    "expected_crypto": "USDT",
    "received_amount": 25.00,
    "status": "confirmed",
    "created_at": 1712343000000
  }
]

Cancel Payment

POST /api/payments/:id/cancel X-API-Key required

Cancel a pending payment. Only works if the payment is still pending. The wallet is released back to the pool.

Response 200 OK

{
  "id": "pay_a1b2c3d4e5f6g7h8",
  "status": "cancelled"
}

Payment Status (Public)

GET /api/payments/:id/status No auth required

Public endpoint for polling payment status. Used by the checkout page and can be polled by your frontend.

Response 200 OK

{
  "status": "pending",
  "expected_amount": 25.00,
  "expected_crypto": "USDT",
  "chain": "tron",
  "received_amount": null,
  "address": "TGGrCNwFuzrJbJPHx4pWm6jfgxz5xVVvvv",
  "amount_usd": 25.00,
  "expires_at": 1712345678000,
  "success_url": "https://yoursite.com/success",
  "fail_url": "https://yoursite.com/fail"
}

List Enabled Chains

GET /api/chains No auth required

Returns all currently enabled blockchain networks and available wallet counts.

Response 200 OK

[
  { "chain": "tron",     "ticker": "USDT", "label": "USDT (TRC-20)",  "isToken": false, "freeWallets": 5 },
  { "chain": "bitcoin",  "ticker": "BTC",  "label": "Bitcoin",       "isToken": false, "freeWallets": 5 },
  { "chain": "ethereum", "ticker": "ETH",  "label": "Ethereum",      "isToken": false, "freeWallets": 5 },
  { "chain": "ethereum", "ticker": "USDT", "label": "USDT (ERC-20)",  "isToken": true,  "freeWallets": 5 },
  { "chain": "ethereum", "ticker": "USDC", "label": "USDC (ERC-20)",  "isToken": true,  "freeWallets": 5 },
  { "chain": "bnb",      "ticker": "USDT", "label": "USDT (BEP-20)",  "isToken": true,  "freeWallets": 5 },
  // ... SOL, BNB, LTC, USDC variants
]

Get Payment Chain Options

GET /api/payments/:id/chains No auth required

For a multi-chain (USD) payment, returns available chains with real-time estimated crypto amounts converted from the USD price.

Response 200 OK

[
  {
    "chain": "tron",
    "ticker": "USDT",
    "estimatedAmount": 50.00,
    "available": true,
    "freeWallets": 5
  },
  {
    "chain": "bitcoin",
    "ticker": "BTC",
    "estimatedAmount": 0.00058214,
    "available": true,
    "freeWallets": 5
  }
]

Select Chain for Payment

POST /api/payments/:id/select-chain No auth required

Select which blockchain and currency to use for a multi-chain (USD) payment. Assigns a wallet and converts USD to the selected coin's amount at current market rate.

Request Body

ParameterTypeDescription
chainstringrequiredtron, bitcoin, ethereum, solana, bnb, or litecoin
tickerstringoptionalToken ticker (e.g., USDT, USDC). Defaults to chain's native coin if omitted.

Response 200 OK

{
  "address": "bc1qzpqrgve9g3sff9ds799f7jx5ktwl0jthp22222",
  "amount": 0.00058214,
  "currency": "BTC",
  "chain": "bitcoin",
  "expires_at": 1712345678000
}

Webhooks

Webhooks notify your server when a payment is confirmed or expires. Set the webhook URL in your store settings or per-payment in the webhook_url field.

Each webhook request is signed with your store's webhook_secret (format: whsec_...), which you receive when creating your store. Verify the signature to confirm authenticity.

Webhook Events

EventTrigger
payment.confirmedOn-chain payment received and confirmed (≥ 99% of expected amount)
payment.expiredPayment not received before the 30-minute expiration

Retry Policy

Webhooks are retried up to 3 times: immediately, after 60 seconds, after 300 seconds. Each attempt has a 10-second timeout. Your server should return 2xx to acknowledge receipt.

Webhook Payload

// POST to your webhook URL
// Headers:
//   Content-Type: application/json
//   X-Signature: <HMAC-SHA256 hex digest>

{
  "event": "payment.confirmed",
  "payment_id": "pay_a1b2c3d4e5f6g7h8",
  "order_id": "order_123",
  "expected_amount": 25.00,
  "received_amount": 25.00,
  "currency": "USDT",
  "tx_hash": "abc123def456...",
  "address": "TGGrCNwFuzrJbJPHx4pWm6jfgxz5xVVvvv",
  "status": "confirmed",
  "metadata": { "user_id": 42 },
  "timestamp": 1712344000
}

Signature Verification

Verify the X-Signature header using HMAC-SHA256 with your webhook_secret as the key and the raw request body as the message.

Always verify signatures. Never trust webhook data without checking the signature first.

Node.js Example

const crypto = require('crypto');

function verifyWebhook(rawBody, signature, webhookSecret) {
  const expected = crypto
    .createHmac('sha256', webhookSecret)
    .update(rawBody)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature, 'hex'),
    Buffer.from(expected, 'hex')
  );
}

// Express middleware:
app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-signature'];
  if (!verifyWebhook(req.body, signature, 'whsec_your_secret')) {
    return res.status(401).send('Invalid signature');
  }

  const event = JSON.parse(req.body);
  if (event.event === 'payment.confirmed') {
    // Fulfill the order
    console.log(`Payment ${event.payment_id} confirmed: ${event.received_amount} ${event.currency}`);
  }

  res.sendStatus(200);
});

Python Example

import hmac, hashlib, json
from flask import Flask, request

app = Flask(__name__)

def verify_webhook(raw_body, signature, secret):
    expected = hmac.new(
        secret.encode(), raw_body, hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(signature, expected)

@app.route('/webhook', methods=['POST'])
def webhook():
    signature = request.headers.get('X-Signature', '')
    if not verify_webhook(request.data, signature, 'whsec_your_secret'):
        return 'Invalid signature', 401

    event = request.json
    if event['event'] == 'payment.confirmed':
        # Fulfill the order
        print(f"Payment {event['payment_id']} confirmed")

    return 'OK', 200

PHP Example

<?php
$rawBody = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_SIGNATURE'] ?? '';
$secret = 'whsec_your_secret';

$expected = hash_hmac('sha256', $rawBody, $secret);

if (!hash_equals($expected, $signature)) {
    http_response_code(401);
    die('Invalid signature');
}

$event = json_decode($rawBody, true);

if ($event['event'] === 'payment.confirmed') {
    // Fulfill the order
    error_log("Payment {$event['payment_id']} confirmed");
}

http_response_code(200);
?>

Check Available Balance

GET /api/withdrawals/available/:store_id JWT cookie required

Check available balance for withdrawal (after platform fees are deducted).

Response 200 OK

{
  "available": 95.50,
  "withdrawal_fee": 3.00,
  "you_receive": 92.50,
  "min_withdrawal": 10.00
}

Request Withdrawal

POST /api/withdrawals JWT cookie required

Submit a withdrawal request. Withdrawals under 500 USDT are auto-approved every 6 hours. Larger amounts require manual admin approval.

Request Body

ParameterTypeDescription
store_idstringrequiredYour store ID
to_addressstringrequiredDestination TRON address
amountnumberrequiredAmount in USDT (min: 10)

Response 201 Created

{
  "id": "wd_a1b2c3d4e5f6g7h8",
  "status": "pending",
  "amount": 50.00,
  "withdrawal_fee": 3.00,
  "you_receive": 47.00,
  "message": "Withdrawal submitted. Fee: 3.0 USDT. You will receive 47.000000 USDT."
}

Create Store

POST /api/stores JWT cookie required

Create a new store. Starts in pending status until approved by admin. You'll receive your API key and webhook secret in the response — save them, they cannot be retrieved later.

Request Body

ParameterTypeDescription
namestringrequiredYour store name
domainstringoptionalYour website domain
webhook_urlstringoptionalDefault webhook URL for payments
business_descriptionstringoptionalBrief description for admin approval

Response 201 Created

{
  "id": "str_a1b2c3d4e5f6g7h8",
  "name": "My Store",
  "api_key": "sk_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6",
  "webhook_secret": "whsec_a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6",
  "message": "Store created. Save the API key and webhook secret - they cannot be retrieved later."
}
Save your credentials! The api_key and webhook_secret are shown only once. Store them securely.

Update Store

PATCH /api/stores/:id JWT cookie required

Update store settings. All fields are optional.

Request Body

ParameterTypeDescription
namestringStore name
domainstringWebsite domain
webhook_urlstringDefault webhook URL
success_urlstringDefault redirect after payment
fail_urlstringDefault redirect on expiration

Regenerate API Key

POST /api/stores/:id/regenerate-key JWT cookie required

Generate a new API key. The old key is immediately invalidated.

Response 200 OK

{
  "api_key": "sk_new_api_key_here_48_hex_characters",
  "message": "Save this key - it cannot be retrieved later."
}

Fee Structure

GET /api/fees No auth required
{
  "payment_fee_rate": 0.004,
  "payment_fee_percent": "0.4%",
  "withdrawal_fees": { "USDT": 3.0, "TRX": 2.0 },
  "min_withdrawal": { "USDT": 10.0, "TRX": 20.0 }
}
FeeAmountWhen
Payment processing0.4% of received amountDeducted from merchant balance
USDT withdrawal3 USDT fixedDeducted from withdrawal amount
TRX withdrawal2 TRX fixedDeducted from withdrawal amount

Payment Statuses

pending confirmed
pending expired
pending cancelled
StatusDescriptionWebhook Event
pendingAwaiting on-chain payment
confirmedPayment received ≥ 99% of expected amountpayment.confirmed
expired30-minute window elapsed without paymentpayment.expired
cancelledCancelled by merchant via API

Supported Chains

ChainNative CoinTokensMin ConfirmationsAddress Format
TRONUSDT (TRC-20)1T... (34 chars)
BitcoinBTC1bc1q... (SegWit bech32)
EthereumETHUSDT (ERC-20), USDC (ERC-20)30x... (42 chars)
SolanaSOLUSDT (SPL), USDC (SPL)1Base58 (32-44 chars)
BNB Smart ChainBNBUSDT (BEP-20), USDC (BEP-20)30x... (42 chars)
LitecoinLTC1ltc1q... (SegWit bech32)
Token payments use the same address as native coin payments. One Ethereum address receives both ETH and USDT/USDC (ERC-20). When creating a payment, specify both currency and chain to select a token (e.g., "currency": "USDT", "chain": "ethereum").

Integration Flow

Seamless (API-only, no redirects)

For services that want full control of the payment UI:

// 1. Create payment
const res = await fetch('https://crypto.setype.com/api/payments', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': 'sk_your_api_key'
  },
  body: JSON.stringify({
    amount: 25.00,
    currency: 'USDT',
    order_id: 'order_123',
    webhook_url: 'https://yoursite.com/webhook'
  })
});
const payment = await res.json();

// 2. Show address + amount to customer in your UI
console.log(payment.address);  // "TGGrCNw..."
console.log(payment.amount);   // 25.00

// 3. Poll for status (or wait for webhook)
const status = await fetch(
  `https://crypto.setype.com/api/payments/${payment.id}/status`
).then(r => r.json());

if (status.status === 'confirmed') {
  // Fulfill the order
}

Hosted Checkout (redirect)

Redirect the customer to our hosted payment page:

// 1. Create payment with success/fail URLs
const payment = await createPayment({
  amount: 25.00,
  currency: 'USD',  // Multi-chain: customer picks coin
  order_id: 'order_123',
  success_url: 'https://yoursite.com/success?order=123',
  fail_url: 'https://yoursite.com/checkout?order=123'
});

// 2. Redirect customer to hosted checkout
window.location.href = payment.payment_url;
// e.g. https://crypto.setype.com/pay/pay_a1b2c3d4e5f6g7h8

// 3. After payment, customer is redirected to success_url
// 4. Verify via webhook (don't trust redirects alone!)
Best practice: Always use webhooks as your source of truth for payment confirmation. The success_url redirect is for UX only — customers can close the tab before being redirected.