API Reference

Invoices API

Create and manage payment invoices. Each invoice gets a unique deposit address for receiving USDT payments.

Default Network: All invoices are created on USDT BEP20 (Binance Smart Chain) by default. You don't need to specify chain or token - simply send the amount and the system handles everything.

Create Invoice

POST/v1/invoices

Create a new payment invoice with a unique deposit address

Request

create-invoice.js
const response = await fetch('https://api.fromchain.plus/v1/invoices', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer gw_live_your_api_key_here',
    'Content-Type': 'application/json',
    'Idempotency-Key': 'order_12345_payment'
  },
  body: JSON.stringify({
    amount: '100.50',
    externalId: 'order_12345',
    description: 'Payment for Order #12345',
    metadata: {
      customerId: 'user_789',
      orderId: 'order_12345',
      plan: 'premium'
    }
  })
});

const invoice = await response.json();

Response

create-invoice-response.json
{
  "id": "inv_abc123",
  "externalId": "order_12345",
  "chain": "BSC",
  "token": "USDT",
  "depositAddress": "0x1234567890123456789012345678901234567890",
  "amountExpected": "100.50",
  "amountReceived": "0",
  "status": "PENDING",
  "confirmationsRequired": 5,
  "expiresAt": "2025-12-18T11:30:00.000Z",
  "description": "Payment for Order #12345",
  "metadata": {
    "customerId": "user_789",
    "orderId": "order_12345",
    "plan": "premium"
  },
  "createdAt": "2025-12-18T11:00:00.000Z",
  "updatedAt": "2025-12-18T11:00:00.000Z"
}

💡 Idempotency: Use the Idempotency-Key header to safely retry requests without creating duplicates.

Request Body Reference

FieldTypeRequiredDefaultDescription
amountstringYes-Amount in USDT (e.g., "100.50")
externalIdstringNonullYour external reference ID
chainstringNo"BSC"Blockchain network (always BSC for USDT BEP20)
tokenstringNo"USDT"Token symbol (always USDT)
confirmationsnumberNo5Block confirmations required (1-100)
descriptionstringNonullInvoice description
metadataobjectNonullCustom JSON metadata
payinCurrencystringNonullCurrency customer pays with (BTC, ETH, etc). Omit for direct USDT payment.
postBackUrlstringNonullTransaction-level callback URL (HTTPS only). When set, ignores configured webhooks and sends all notifications exclusively to this URL.

💡 Minimal Request: For direct USDT BEP20 payments, you only need to send amount. All other fields are optional and have sensible defaults.

🔔 PostBack URL: Use postBackUrl to receive notifications for this specific invoice at a custom HTTPS URL. When set, all status updates (created, detected, confirmed, paid_out, etc.) are sent exclusively to this URL, ignoring your configured webhooks. This is useful when you need different callback URLs per transaction or for third-party integrations.

List Invoices

GET/v1/invoices

Retrieve a paginated list of invoices with optional filters

Query Parameters

?status=PENDING,CONFIRMED

Filter by status (comma-separated)

?page=1&pageSize=20

Pagination (default: page=1, pageSize=20)

?externalId=order_12345

Find by your external reference ID

list-invoices.js
const response = await fetch(
  'https://api.fromchain.plus/v1/invoices?status=CONFIRMED&page=1&pageSize=10',
  {
    headers: {
      'Authorization': 'Bearer gw_live_your_api_key_here'
    }
  }
);

const data = await response.json();
console.log(data);
// {
//   "items": [...],
//   "pagination": {
//     "total": 42,
//     "page": 1,
//     "pageSize": 10,
//     "totalPages": 5
//   }
// }

Get Single Invoice

GET/v1/invoices/:id

Retrieve detailed information about a specific invoice

get-invoice-response.json
{
  "id": "inv_abc123",
  "externalId": "order_12345",
  "chain": "BSC",
  "token": "USDT",
  "depositAddress": "0x1234567890123456789012345678901234567890",
  "amountExpected": "100.50",
  "amountReceived": "100.50",
  "status": "PAID_OUT",
  "confirmationsRequired": 5,
  "detectedBlockNumber": "45678901",
  "confirmedAt": "2025-12-18T11:15:00.000Z",
  "paidOutAt": "2025-12-18T11:20:00.000Z",
  "expiresAt": "2025-12-18T11:30:00.000Z",
  "description": "Payment for Order #12345",
  "metadata": {
    "customerId": "user_789",
    "orderId": "order_12345"
  },
  "transfers": [
    {
      "txHash": "0xabc...",
      "amount": "100.50",
      "confirmed": true
    }
  ],
  "payout": {
    "status": "COMPLETED",
    "feeTxHash": "0xfee...",
    "custodyTxHash": "0xcustody..."
  },
  "createdAt": "2025-12-18T11:00:00.000Z",
  "updatedAt": "2025-12-18T11:20:00.000Z"
}

Multi-Currency Payments (Optional)

Accept payments in any cryptocurrency (BTC, ETH, etc.) and receive USDT automatically. Your customers pay how they want, you always receive USDT.

When to use Multi-Currency:
Direct USDT BEP20 (default): Don't include payinCurrency - payment is processed directly by our blockchain listener
Multi-Currency (BTC, ETH, etc): Include payinCurrency - conversion handled via FixedFloat exchange service

List Available Currencies

GET/v1/invoices/payin/currencies

Get list of available currencies for payment

payin-currencies-response.json
{
  "available": true,
  "currencies": [
    { "code": "BTC", "name": "Bitcoin", "network": "BTC", "available": true },
    { "code": "ETH", "name": "Ethereum", "network": "ETH", "available": true },
    { "code": "LTC", "name": "Litecoin", "network": "LTC", "available": true }
  ]
}

Get Quote

POST/v1/invoices/payin/quote

Get a quote for how much customer needs to send in their chosen currency

payin-quote.js
const response = await fetch('https://api.fromchain.plus/v1/invoices/payin/quote', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer gw_live_your_api_key_here',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    amount: 100,      // USDT amount to receive
    currency: 'BTC'   // Currency customer will pay with
  })
});

const quote = await response.json();
// {
//   "fromCurrency": "BTC",
//   "toCurrency": "USDTBEP20",
//   "amountToSend": "0.00234",
//   "amountToReceive": "100",
//   "rate": "42735.04",
//   "expiresIn": 60
// }

Create Multi-Currency Invoice

Add payinCurrency to create an invoice that accepts a specific cryptocurrency.

create-multicurrency-invoice.js
const response = await fetch('https://api.fromchain.plus/v1/invoices', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer gw_live_your_api_key_here',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    amount: '100.00',         // Amount in USDT you want to receive
    payinCurrency: 'BTC',     // Customer pays in Bitcoin
    externalId: 'order_12345'
  })
});

const invoice = await response.json();
multicurrency-invoice-response.json
{
  "id": "inv_abc123",
  "amountExpected": "100.00",
  "depositAddress": "bc1q...",
  "payinCurrency": "BTC",
  "payinAmount": "0.00234",
  "status": "PENDING",
  "expiresAt": "2025-12-18T11:20:00.000Z"
}

💡 Note: For multi-currency invoices, depositAddress is where the customer sends their crypto. The conversion happens automatically and you receive USDT.

Invoice Lifecycle & Statuses

An invoice goes through several states from creation to completion:

PENDING

Waiting for payment. Customer should send funds to the deposit address.

PAID_DETECTED

Exact payment detected, waiting for blockchain confirmations (0 of 5 confirmations).

PARTIALLY_PAID

Received less than expected amount. Customer needs to send the difference.

OVERPAID

Received more than expected. The extra amount will be credited to your balance.

CONFIRMED

Payment confirmed with required blockchain confirmations (5 blocks on BSC).

PROCESSING_PAYOUT

Internal settlement in progress. Funds being transferred to custody.

PAID_OUT

✅ Complete! Funds credited to your balance (minus platform fee). Ready to withdraw.

EXPIRED

No payment received within the expiration window (default 30 minutes).

LATE_PAYMENT

Payment received after expiration. Will still be processed.

FAILED

Settlement failed due to an error. Manual intervention may be required.

Best Practices

Use Idempotency Keys

Always include an Idempotency-Key header when creating invoices to prevent duplicates on retries.

fetch('https://api.fromchain.plus/v1/invoices', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer gw_live_...',
    'Idempotency-Key': 'order_12345_payment', // ← Important!
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ ... })
})

Use Webhooks for Real-Time Updates

Don't poll the API repeatedly. Instead, configure webhooks to receive real-time notifications when invoice status changes.

Handle All Statuses

Your integration should handle all possible invoice statuses, including PARTIALLY_PAID, OVERPAID, and LATE_PAYMENT edge cases.

Store External IDs

Use the externalId field to link invoices to your internal order/transaction IDs for easy reconciliation.