Payments with Stablecoins
Once onboarding is complete, you can start accepting payments with SP Cuvex.
Here we show you the main endpoints and how to use them.
1. Create a Payment
Endpoint:
POST /v1/payments
Idempotency
To ensure safe resource creation, it is mandatory to send the x-idempotency-key header:
- Value: UUID v4 generated by the client, unique for each new resource
- Behavior:
- Same payload + same key = returns the object previously created
- Same key + different payload = HTTP 409 error
- Duration: Keys are valid for 24 hours
Request example:
{
"network": "TRON",
"token": "USDT",
"title": "My new payment",
"description": "Purchase of food and groceries on March 3, 2025",
"amount": "1234.56",
"merchant_reference": "INV-25-AUG-0001",
"validity_period": 20
}
Required headers:
Content-Type: application/json
x-idempotency-key: 550e8400-e29b-41d4-a716-446655440000
Response example:
{
"message": "OK",
"timestamp": "2024-04-16T17:44:51Z",
"data": {
"id": "263600a1-1514-4e57-a11d-be91e9c8e9d4",
"merchant_reference": "INV-25-AUG-0001",
"title": "My new payment",
"description": "Purchase of food and groceries on March 3, 2025",
"network": "TRON",
"currency": "USDT",
"amount": "1234.56",
"confirmed_amount": "0",
"status": "OPEN",
"valid_until": 1755532150,
"link": "https://dapp.example.sp.cuvex.io/payment?idsession=123456&amount=1234.56&contract=TVAKUM28o1pNj6pkcckvWHFUs1foRcSwAt",
"created_at": "2024-04-16T17:44:51Z",
"updated_at": "2024-04-16T17:44:51Z"
}
}
Note: The link field is what you must present to your customers (as a button, QR code, or any method you prefer) to proceed with the payment. This link directs to a dApp where customers complete their payment using their preferred wallet. This approach ensures compatibility across all wallet types.
Code examples
- Python
- JavaScript
- cURL
import requests
import uuid
import os
# Sandbox URL for testing - use production URL for live environment
url = "https://sp-dev.cuvex.io/ecommerce/v1/payments"
headers = {
"Content-Type": "application/json",
"x-idempotency-key": str(uuid.uuid4()),
# Never hardcode API keys in source code - always use environment variables
"x-api-key": os.getenv("API_KEY")
}
payload = {
"network": "TRON",
"token": "USDT",
"title": "My new payment",
"description": "Purchase of food and groceries on March 3, 2025",
"amount": "1234.56",
"merchant_reference": "INV-25-AUG-0001",
"validity_period": 20
}
response = requests.post(url, json=payload, headers=headers)
print(response.json())
const fetch = require('node-fetch');
const { v4: uuidv4 } = require('uuid');
// Sandbox URL for testing - use production URL for live environment
const url = 'https://sp-dev.cuvex.io/ecommerce/v1/payments';
const headers = {
'Content-Type': 'application/json',
'x-idempotency-key': uuidv4(),
// Never hardcode API keys in source code - always use environment variables
'x-api-key': process.env.API_KEY
};
const payload = {
network: 'TRON',
token: 'USDT',
title: 'My new payment',
description: 'Purchase of food and groceries on March 3, 2025',
amount: '1234.56',
merchant_reference: 'INV-25-AUG-0001',
validity_period: 20
};
fetch(url, {
method: 'POST',
headers: headers,
body: JSON.stringify(payload)
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
# Sandbox URL for testing - use production URL for live environment
# Never hardcode API keys in source code - always use environment variables
curl -X POST https://sp-dev.cuvex.io/ecommerce/v1/payments -H "Content-Type: application/json" -H "x-idempotency-key: 550e8400-e29b-41d4-a716-446655440000" -H "x-api-key: $API_KEY" -d '{
"network": "TRON",
"token": "USDT",
"title": "My new payment",
"description": "Purchase of food and groceries on March 3, 2025",
"amount": "1234.56",
"merchant_reference": "INV-25-AUG-0001",
"validity_period": 20
}'
2. Retrieve a payment
Endpoint:
GET /v1/payments/{paymentId}
Response example:
{
"message": "OK",
"timestamp": "2024-04-16T17:44:51Z",
"data": {
"id": "263600a1-1514-4e57-a11d-be91e9c8e9d4",
"merchant_reference": "INV-25-AUG-0001",
"title": "My new payment",
"description": "Purchase of food and groceries on March 3, 2025",
"network": "TRON",
"currency": "USDT",
"amount": "1234.56",
"confirmed_amount": "0",
"status": "OPEN",
"valid_until": 1755532150,
"link": "https://dapp.example.sp.cuvex.io/payment?idsession=123456&amount=1234.56&contract=TVAKUM28o1pNj6pkcckvWHFUs1foRcSwAt",
"created_at": "2024-04-16T17:44:51Z",
"updated_at": "2024-04-16T17:44:51Z"
}
}
Code examples
- Python
- JavaScript
- cURL
import requests
import os
# Sandbox URL for testing - use production URL for live environment
payment_id = "263600a1-1514-4e57-a11d-be91e9c8e9d4"
url = f"https://sp-dev.cuvex.io/ecommerce/v1/payments/{payment_id}"
headers = {
# Never hardcode API keys in source code - always use environment variables
"x-api-key": os.getenv("API_KEY")
}
response = requests.get(url, headers=headers)
print(response.json())
const fetch = require('node-fetch');
// Sandbox URL for testing - use production URL for live environment
const paymentId = '263600a1-1514-4e57-a11d-be91e9c8e9d4';
const url = `https://sp-dev.cuvex.io/ecommerce/v1/payments/${paymentId}`;
const headers = {
// Never hardcode API keys in source code - always use environment variables
'x-api-key': process.env.API_KEY
};
fetch(url, {
method: 'GET',
headers: headers
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
# Sandbox URL for testing - use production URL for live environment
# Never hardcode API keys in source code - always use environment variables
curl -X GET https://sp-dev.cuvex.io/ecommerce/v1/payments/263600a1-1514-4e57-a11d-be91e9c8e9d4 -H "x-api-key: $API_KEY"
3. List payments
Endpoint:
GET /v1/payments?page={page}&start_date={start_date}&end_date={end_date}
Results are returned as a list of payments in reverse chronological order (most recent first), paginated in groups of 25 records per page.
Query parameters (optional):
page: Page number (starting at 0). If not specified, page 0 is usedstart_date: Start date of the range in formatyyyy-mm-ddend_date: End date of the range in formatyyyy-mm-dd
If no date filters are provided, all registered payments are listed.
Response example:
{
"message": "OK",
"timestamp": "2024-04-16T17:44:51Z",
"data": {
"total_count": 2551,
"count": 25,
"items": [
{
"id": "263600a1-1514-4e57-a11d-be91e9c8e9d4",
"merchant_reference": "Payment-25-AUG-0001",
"title": "My new payment",
"network": "TRON",
"currency": "USDT",
"amount": "1234.56",
"status": "OPEN",
"valid_until": 1755532150,
"created_at": "2024-04-16T17:44:51Z"
}
]
}
}
Code examples
- Python
- JavaScript
- cURL
import requests
import os
from urllib.parse import urlencode
# Sandbox URL for testing - use production URL for live environment
base_url = "https://sp-dev.cuvex.io/ecommerce/v1/payments"
headers = {
# Never hardcode API keys in source code - always use environment variables
"x-api-key": os.getenv("API_KEY")
}
# Example with pagination and date filters
params = {
"page": 0,
"start_date": "2024-01-01",
"end_date": "2024-12-31"
}
url = f"{base_url}?{urlencode(params)}"
response = requests.get(url, headers=headers)
print(response.json())
const fetch = require('node-fetch');
// Sandbox URL for testing - use production URL for live environment
const baseUrl = 'https://sp-dev.cuvex.io/ecommerce/v1/payments';
const headers = {
// Never hardcode API keys in source code - always use environment variables
'x-api-key': process.env.API_KEY
};
// Example with pagination and date filters
const params = new URLSearchParams({
page: '0',
start_date: '2024-01-01',
end_date: '2024-12-31'
});
const url = `${baseUrl}?${params}`;
fetch(url, {
method: 'GET',
headers: headers
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
# Sandbox URL for testing - use production URL for live environment
# Never hardcode API keys in source code - always use environment variables
# Example with pagination and date filters
curl -X GET "https://sp-dev.cuvex.io/ecommerce/v1/payments?page=0&start_date=2024-01-01&end_date=2024-12-31" -H "x-api-key: $API_KEY"
4. Payment statuses
Payments in SP Cuvex can have the following statuses during their lifecycle:
Available statuses
| Status | Description |
|---|---|
OPEN | Newly created payment, awaiting confirmation |
FINISHED | Payment successfully completed with the exact amount |
PARTIALLY_FILLED | Payment received for less than the specified amount |
OVER_FILLED | Payment received for more than the specified amount |
EXPIRED | Payment expired without confirmation within the validity period |
LATE_PAYMENT | Payment confirmed after the validity period |
FAILED | Error occurred during processing |
Status flow
Status transitions
- Creation: every payment starts in
OPEN - Successful confirmation: transitions to
FINISHEDwhen the exact amount is received - Partial confirmation: transitions to
PARTIALLY_FILLEDif the amount is less than expected - Overpayment: transitions to
OVER_FILLEDif the amount is greater than expected - Expiration: transitions to
EXPIREDif no confirmation is received within the validity period - Late payment: transitions to
LATE_PAYMENTif confirmation arrives after expiration - Error: transitions to
FAILEDif a processing error occurs
5. Decimal format
SP Cuvex handles all monetary amounts as strings to guarantee precision in financial operations:
- Format: decimal point (
.) as separator, no thousands separators - Valid examples:
"1234.56","0.000001","1000000" - Decimals per token: depends on the token. For example, USDC and USDT allow up to 6 decimals. Other tokens may support up to 18 decimals.
Important: This is the only format accepted in requests and returned in responses.
6. Real-time confirmation
SP Cuvex provides a webhook to receive payment notifications in real time.
See the Webhook section for implementation details.
Tip: in addition to the webhook, you can use the payment retrieval endpoint as a fallback.