Invoices API
Create and manage payment invoices. Each invoice gets a unique deposit address for receiving USDT payments.
Create Invoice
/v1/invoicesCreate a new payment invoice with a unique deposit address
Request
const response = await fetch('https://api.fromchain.io/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({
amountExpected: '100.50',
externalId: 'order_12345',
description: 'Payment for Order #12345',
expiresInMinutes: 30,
metadata: {
customerId: 'user_789',
orderId: 'order_12345',
plan: 'premium'
}
})
});
const invoice = await response.json();Response
{
"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.
List Invoices
/v1/invoicesRetrieve a paginated list of invoices with optional filters
Query Parameters
?status=PENDING,CONFIRMEDFilter by status (comma-separated)
?page=1&pageSize=20Pagination (default: page=1, pageSize=20)
?externalId=order_12345Find by your external reference ID
const response = await fetch(
'https://api.fromchain.io/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
/v1/invoices/:idRetrieve detailed information about a specific invoice
{
"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"
}Invoice Lifecycle & Statuses
An invoice goes through several states from creation to completion:
PENDINGWaiting for payment. Customer should send funds to the deposit address.
PAID_DETECTEDExact payment detected, waiting for blockchain confirmations (0 of 5 confirmations).
PARTIALLY_PAIDReceived less than expected amount. Customer needs to send the difference.
OVERPAIDReceived more than expected. The extra amount will be included in the payout.
CONFIRMEDPayment confirmed with required blockchain confirmations (5 blocks on BSC).
PROCESSING_PAYOUTFunds are being swept and split between fee wallet and custody wallet.
PAID_OUT✅ Complete! Funds successfully transferred to fee and custody wallets.
EXPIREDNo payment received within the expiration window (default 30 minutes).
LATE_PAYMENTPayment received after expiration. Will still be processed.
FAILEDPayout 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.io/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.