Перейти до вмісту
CoinsSendРозробникам
Документація Payments

Invoices API

Відкрити MarkdownПідключити агента

Цей контент ще не доступний вашою мовою.

The Invoices API allows you to create and manage cryptocurrency payment invoices for your customers. Each invoice generates a unique payment page where customers can select their preferred cryptocurrency and complete the payment. Invoices are ideal for e-commerce checkout flows and single-payment scenarios.

An invoice is a payment request with a specific amount that customers can pay using various cryptocurrencies. When an invoice is created, customers receive a payment URL where they can choose their preferred cryptocurrency and complete the payment.

1

Create Invoice

Generate a new invoice with a specified amount using the POST /v1/invoices endpoint.

2

Customer Payment

Customer visits the payment URL, selects direct crypto payment, or uses card checkout when the invoice allows cards and the remaining amount meets the minimum.

3

Payment Confirmation

Once payment is confirmed on the blockchain, the invoice status is updated to "paid". Partial payments are supported - if the customer pays less than the full amount, they can complete the payment with a second transaction for the remaining balance.

4

Webhook Notification

A webhook notification is sent to your server with payment details.

Creates a new invoice for direct cryptocurrency payment, with optional card checkout.

POST /v1/invoices

This endpoint creates a new invoice with the specified amount and options. The invoice will generate a unique payment page URL that you can redirect your customers to for completing the payment.

Authentication required
HeaderRequiredDescription
Content-TypeYesMust be application/json
MerchantYesYour merchant ID
SignYesRequest signature (see Authentication)
TimestampNoInclude only when using timestamped HMAC; X-Timestamp is accepted as an alias

Build the canonical JSON body described in Authentication, sign it, and send that same string as the request body.

ParameterTypeRequiredDefaultDescription
order_idstringYes-Your order identifier (must be unique per merchant)
amountstringYes-Invoice amount in USD (minimum 3.00, e.g., “10.50”)
is_customer_feebooleanNofalseIf true, the customer pays the service fee (CoinsSend commission)
is_customer_network_feebooleanNofalseIf true, the customer pays the blockchain transaction fee; if false, the merchant covers it
allow_card_paymentsbooleanNofalseIf true, card checkout may be shown when the invoice amount or remaining amount is at least $15.00 / 1500 cents
allowed_coinsarrayNoall supported coinsList of currently supported cryptocurrencies to allow for this invoice
coinstringNo-Preselect a currently supported coin for the payment page
networkstringNo-Preselect a network that matches the selected coin
success_urlstringNo-URL to redirect the customer after successful payment
cancel_urlstringNo-URL to redirect the customer if they cancel payment

Important: coin and network must be a currently supported combination. Fetch the live catalog from GET /v1/coins-and-fee. Requests containing an unsupported pair (for example eth on tron) or unsupported allowed_coins entries fail validation with HTTP 422.

See Supported Coins & Networks for the coin/network tables and guidance on selecting invoice payment options.

Card checkout: allow_card_payments defaults to false. Card checkout is not shown or available unless you set allow_card_payments to true for that invoice. Even when cards are allowed, the invoice amount or remaining amount must be at least $15.00 / 1500 cents. Direct crypto payment remains available when cards are disabled or the remaining amount is below the card minimum.

{
"order_id": "order_12345",
"amount": "100.50",
"is_customer_fee": true,
"is_customer_network_fee": false,
"allow_card_payments": true,
"allowed_coins": ["usdt", "eth"],
"coin": "usdt",
"network": "tron",
"success_url": "https://example.com/payment-success",
"cancel_url": "https://example.com/payment-canceled"
}
{
"status": "success",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"order_id": "order_12345",
"url": "https://pay.coinssend.com/invoice_code",
"code": "invoice_code",
"amount": "100.50",
"payer_amount": "100.50",
"expired_at": "2024-01-02T12:00:00+00:00",
"created_at": "2024-01-01T12:00:00+00:00"
}
}
FieldTypeDescription
idstringUnique invoice ID (UUID)
order_idstringUnique order ID in your system
urlstringPayment URL for the invoice
codestringUnique invoice code
amountstringInvoice amount
payer_amountstringTotal amount the payer needs to pay including fees
expired_atstringISO 8601 timestamp when the invoice expires (24 hours after creation)
created_atstringISO 8601 timestamp when the invoice was created

allow_card_payments and provider_card are not returned by POST /v1/invoices. They can appear in invoice lookup and payment-page invoice payloads, where provider_card explains whether card checkout is currently available and why it may be disabled.

Direct crypto payment is always available on the payment page. Card checkout is optional per invoice and requires both of these conditions:

  1. allow_card_payments is true on the invoice.
  2. The invoice amount, or remaining amount after a partial payment, is at least $15.00 / 1500 cents.

If either condition is not met, the payment page does not show card checkout and customers can still pay directly with crypto. In invoice lookup and payment-page invoice payloads, the provider_card object explains the current card state with enabled, disabled_reason, minimum_amount_cents, and remaining_amount_cents.

Provider redirects, KYC success, provider webhooks, and provider status polling are not final payment confirmation. Chain confirmation remains the source of truth for moving an invoice to paid.

Creates a card checkout order for an existing invoice when allow_card_payments is enabled and the remaining invoice amount is at least $15.00 / 1500 cents.

POST /v1/invoices/{invoiceCode}/provider-card-orders
ParameterTypeRequiredDefaultDescription
emailstringNo-Optional customer email to store on the invoice.

Do not send provider, coin, or network fields for card checkout. CoinsSend selects these values. If a client includes them, they are ignored and cannot override the selected checkout route.

{
"email": "customer@example.com"
}
{
"status": "success",
"data": {
"provider_card_order": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"provider": "simpleswap",
"local_status": "redirect_pending",
"expires_at": "2026-05-11T12:30:00+00:00",
"redirect_url": "https://provider.example/checkout/session"
},
"reused": false
}
}

Repeating this operation while the same active order is usable returns that order with reused: true. This narrow active-order reuse is not a general Idempotency-Key contract.

Returns the current public checkout state for an invoice.

GET /v1/invoices/{invoiceCode}

No merchant signature is required. The response uses the standard success envelope with data.invoice and current data.network_fees. The invoice object includes amounts, payment selection, status, allowed payment options, transaction hashes, QR URL, and provider_card capability. See the exact machine-readable schema in OpenAPI.

Treat the invoice code as a public checkout identifier. Do not use it as authorization for merchant balances, fees, wallet creation, or withdrawals.

AI assistant prompt: Build a server-side invoice creation and buyer redirect flow. Create POST /v1/invoices, store the invoice ID, code, status, and URL, then send the buyer to data.url. Treat success/cancel redirect URLs as UX signals only, not payment confirmation. Confirm payment through Webhooks, handle partial as unpaid progress, and handle expired as a terminal failure state. For the full checkout prompt, see AI Integration Prompts.

HTTP statusResponse shapeDescription
400{"error":"Missing headers"}Merchant or Sign header is missing
401{"error":"Invalid merchant"} or {"error":"Invalid sign"}Authentication failed
403authentication or endpoint errorMerchant status blocks invoice creation
409{"status":"error","message":"Order id already exists"}The merchant order ID already exists; the original response is not replayed
422validation error with errors, status, and messageRequest parameters are invalid

When an invoice is paid, the amount your customer must send is shown in the payer_amount field. This value includes the blockchain network fee and may also include the service fee depending on the is_customer_fee setting.

  1. Service Fee (CoinsSend commission) – Calculated as amount × service_fee_percent. It is added to payer_amount only when is_customer_fee is true. Otherwise this fee is deducted from the merchant balance.
  2. Network/Transaction Fee – Specified in the same coin as the invoice payment. Network fee values can be obtained from the network_fees list in the Merchant API. It is added to payer_amount only when is_customer_network_fee is true. When the merchant covers it (false), the customer sees no network surcharge and the fee is deducted from the merchant proceeds.

The final crypto amount to pay is calculated as:

amount_coin = (amount + (service_fee if is_customer_fee else 0)) / rate
total_coin = amount_coin + (network_fee if is_customer_network_fee else 0)

Customer Pays Service Fee

Invoice amount: 100 USD
Network fee: 1 USD
Service fee percent: 0.45%
Service fee: 100 × 0.45% = 0.45 USD
Total amount to pay: 100 + 1 + 0.45 = 101.45 USD

Merchant Pays Service Fee

Invoice amount: 100 USD
Network fee: 1 USD
Service fee percent: 0.45%
Service fee: 100 × 0.45% = 0.45 USD
Total amount to pay: 100 + 1 = 101 USD
Service fee deducted from merchant balance: 0.45 USD

Merchant Pays Network Fee

Invoice amount: 100 USD
Network fee: 1 USD
Service fee percent: 0.45%
Network fee covered by merchant ➜ payer sends: 100.45 USD if customer pays service fee
or 100 USD if merchant also covers service fee.

ETH USDC Example

Using the ETH network with USDC, the exchange rate on 2025‑07‑09 is 1 USDC = 1.0000363274333 USD.

Invoice amount: 100 USD
Network fee: 1 USDC
Service fee percent: 0.45%
Service fee: 100 × 0.45% = 0.45 USD
Amount before network fee: 100 + 0.45 = 100.45 USD
Amount in USDC: 100.45 ÷ 1.000036327 ≈ 100.4463293 USDC
Total to send: 100.4463293 + 1 ≈ 101.4463293 USDC

The service fee is rounded down to 8 decimal places when converting to cryptocurrency because invoice amounts are stored in cents. The formula is:

fee_coin = floor(amount_coin × service_fee_percent × 100000000) / 100000000

Where amount_coin is the invoice amount in the selected coin before the network fee is added.

<?php
// API credentials
$merchantId = 'your_merchant_id';
$apiKey = 'your_api_key';
// Invoice data
$invoiceData = [
'order_id' => 'order_' . time(),
'amount' => '100.50',
'is_customer_fee' => true,
'allow_card_payments' => true,
'success_url' => 'https://example.com/payment-success',
'cancel_url' => 'https://example.com/payment-canceled'
];
// Generate signature
$jsonData = json_encode($invoiceData);
$base64Data = base64_encode($jsonData);
$signature = md5($base64Data . $apiKey);
// Set up request
$ch = curl_init('https://api.coinssend.com/v1/invoices');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Merchant: ' . $merchantId,
'Sign: ' . $signature
]);
// Execute request
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// Process response
if ($httpCode >= 200 && $httpCode < 300) {
$responseData = json_decode($response, true);
if ($responseData['status'] === 'success') {
echo "Invoice created successfully!\n";
echo "Payment URL: " . $responseData['data']['url'] . "\n";
echo "Invoice Code: " . $responseData['data']['code'] . "\n";
}
} else {
echo "Error: " . $response . "\n";
}
// API credentials
const merchantId = 'your_merchant_id';
const apiKey = 'your_api_key';
// Invoice data
const invoiceData = {
order_id: 'order_' + Date.now(),
amount: '100.50',
is_customer_fee: true,
allow_card_payments: true,
success_url: 'https://example.com/payment-success',
cancel_url: 'https://example.com/payment-canceled'
};
// Generate signature
const jsonData = JSON.stringify(invoiceData)
.replace(/\//g, '\\/')
.replace(/[\u0080-\uFFFF]/g, character =>
`\\u${character.charCodeAt(0).toString(16).padStart(4, '0')}`
);
const base64Data = Buffer.from(jsonData, 'utf8').toString('base64');
const crypto = require('node:crypto');
const signature = crypto.createHash('md5').update(base64Data + apiKey).digest('hex');
// Make the API request
fetch('https://api.coinssend.com/v1/invoices', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Merchant': merchantId,
'Sign': signature
},
body: jsonData
})
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
console.log("Invoice created successfully!");
console.log("Payment URL:", data.data.url);
console.log("Invoice Code:", data.data.code);
} else {
console.error("Error:", data);
}
})
.catch(error => console.error("Request failed:", error));
import requests
import json
import base64
import hashlib
import time
# API credentials
merchant_id = 'your_merchant_id'
api_key = 'your_api_key'
# Invoice data
invoice_data = {
'order_id': f'order_{int(time.time())}',
'amount': '100.50',
'is_customer_fee': True,
'allow_card_payments': True,
'success_url': 'https://example.com/payment-success',
'cancel_url': 'https://example.com/payment-canceled'
}
def canonical_json(payload):
encoded = json.dumps(
payload, ensure_ascii=False, separators=(',', ':'), allow_nan=False
)
escaped = []
for character in encoded:
codepoint = ord(character)
if character == '/':
escaped.append(r'\/')
elif codepoint < 0x80:
escaped.append(character)
elif codepoint <= 0xFFFF:
escaped.append(f'\\u{codepoint:04x}')
else:
codepoint -= 0x10000
escaped.append(f'\\u{0xD800 + (codepoint >> 10):04x}')
escaped.append(f'\\u{0xDC00 + (codepoint & 0x3FF):04x}')
return ''.join(escaped)
# Generate signature from the exact body that will be sent
json_data = canonical_json(invoice_data)
base64_data = base64.b64encode(json_data.encode()).decode()
signature = hashlib.md5((base64_data + api_key).encode()).hexdigest()
# Set up headers
headers = {
'Content-Type': 'application/json',
'Merchant': merchant_id,
'Sign': signature
}
# Make the API request
response = requests.post(
'https://api.coinssend.com/v1/invoices',
headers=headers,
data=json_data
)
# Process response
if response.status_code >= 200 and response.status_code < 300:
data = response.json()
if data['status'] == 'success':
print("Invoice created successfully!")
print(f"Payment URL: {data['data']['url']}")
print(f"Invoice Code: {data['data']['code']}")
else:
print(f"Error: {data}")
else:
print(f"HTTP Error: {response.status_code}")
print(f"Response: {response.text}")

Invoices transition through the following states:

StatusDescription
newInvoice created; no payment method selected.
waitingPayment method locked in; awaiting blockchain payment.
partialPartial payment detected; remaining balance still due.
paidFull payment confirmed.
expiredInvoice expired (24 hours after creation) before full payment.
aml_rejectedPayment was rejected by AML processing.
Note: Invoice webhook events are currently emitted for invoice.paid, invoice.expired, and AML rejection. Do not assume every intermediate status has an event. See the Webhooks documentation for details.
  • Store Invoice Data: Always store the invoice code and status in your database for tracking and reconciliation.
  • Handle Webhooks: Implement webhook handling to receive real-time notifications of payment status changes.
  • Support Partial Payments: Implement UI and business logic to handle partially paid invoices, allowing customers to complete payments in multiple transactions.
  • Track Payment Progress: Use payed_usd, payed_crypto, and payer amount fields from invoice lookup to show payment progress.
  • Use Card Checkout Deliberately: Set allow_card_payments only when you want card checkout available. Keep direct crypto payment available for invoices that do not allow cards or fall below the $15.00 card minimum after partial payment.
  • Verify Webhooks: Always verify webhook signatures to ensure they come from CoinsSend.
  • Check Expiration: Invoices expire after 24 hours. Consider this when implementing payment flows.
  • Webhooks - Receive real-time notifications for invoice status changes
  • Authentication - Learn about API authentication and signatures
  • Error Handling - Understand error responses and how to handle them

For complete code examples in various languages, see: