Cryptofuse Integration Guide
This guide provides practical examples and best practices for integrating with the Cryptofuse API.
Table of Contents
- Authentication
- Payment Flow
- Webhook Integration
- Withdrawal Flow
- Common Integration Patterns
- Testing with Testnet
Authentication
Getting Started
- Obtain your OAuth2 credentials (client_id and client_secret)
- Request an access token
- Use the token in all API requests
# Get access token
curl -X POST https://api.cryptofuse.com/o/token/ \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET&scope=read write"
# Response
{
"access_token": "your_access_token",
"token_type": "Bearer",
"expires_in": 36000,
"scope": "read write"
}
# Use token in requests
curl -H "Authorization: Bearer your_access_token" \
https://api.cryptofuse.com/currencies/
Payment Flow
Step 1: Check Available Currencies
# Get currencies with limits
GET /currencies/?full=true&min_max=true&include_usd=true
# Response shows available payment options
{
"currencies": [
{
"currency": "USDTTRC20",
"name": "Tether USD",
"token": "usdt",
"blockchain": "trx",
"min_amount": "10.00000000",
"max_amount": "100000.00000000",
"min_amount_usd": "10.00",
"max_amount_usd": "100000.00"
}
]
}
Step 2: Check Exchange Rates (Optional)
# Convert 100 USD to USDT
GET /rates/?amount=100¤cy_from=USD¤cy_to=USDTTRC20&full=true
# Response with fee details
{
"currency_from": "USD",
"currency_to": "USDTTRC20",
"amount": 100.0,
"estimated_amount": 99.0, # After 1% fee
"rate": 0.99,
"fee_percentage": 1.0,
"fee_amount": 1.0,
"timestamp": "2024-12-27T10:00:00Z"
}
Step 3: Create Payment
POST /payments/
{
"amount": 100.00,
"currency": "USDTTRC20",
"price_currency": "USD",
"callback_url": "https://your-site.com/cryptofuse-webhook",
"order_id": "order_12345",
"order_description": "Premium subscription payment",
"is_fixed_rate": true,
"is_fee_paid_by_user": false,
"expiry_minutes": 30
}
# Response
{
"transaction_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "waiting",
"blockchain_address": "TXYZabc123...",
"amount_usd": "100.00",
"amount_crypto": "100.00000000",
"blockchain": "TRX",
"token": "USDT",
"currency": "USDTTRC20",
"expiry_time": "2024-12-27T10:30:00Z",
"created_at": "2024-12-27T10:00:00Z"
}
Step 4: Display Payment Information
Show to your customer:
- Payment address:
TXYZabc123... - Amount to pay:
100.00000000 USDT (TRC20) - Time remaining: 30 minutes
- QR code with the address
Step 5: Monitor Payment Status
# Check status periodically or wait for webhook
POST /payments/status/
{
"transaction_id": "550e8400-e29b-41d4-a716-446655440000"
}
Webhook Integration
Webhook Flow for Payments
Your system will receive webhooks at different stages of the payment:
1. Payment Created (initial state)
No webhook sent - you already have the response from payment creation.
2. Payment Received - "confirming" status
{
"transaction_id": "550e8400-e29b-41d4-a716-446655440000",
"event": "payment_status_update",
"status": "confirming",
"timestamp": "2024-12-27T10:05:00Z",
"data": {
"transaction_id": "550e8400-e29b-41d4-a456-426614174000",
"status": "confirming",
"amount_usd": "100.00",
"amount_crypto": "100.00000000",
"blockchain": "TRX",
"token": "USDT",
"currency": "USDTTRC20",
"address": "TXYZabc123...",
"transaction_hash": "0xabc123...",
"confirmations": 1,
"payment_history": [
{
"deposit_id": "dep_123",
"amount": "100.00000000",
"transaction_hash": "0xabc123...",
"confirmations": 1,
"timestamp": "2024-12-27T10:05:00Z"
}
],
"total_paid_amount": "100.00000000"
}
}
3. Payment Completed - "completed" status
{
"transaction_id": "550e8400-e29b-41d4-a456-426614174000",
"event": "payment_status_update",
"status": "completed",
"timestamp": "2024-12-27T10:10:00Z",
"data": {
"transaction_id": "550e8400-e29b-41d4-a456-426614174000",
"status": "completed",
"amount_usd": "100.00",
"amount_crypto": "100.00000000",
"payment_type": "full",
"final_usd_value": 99.50, // Actual USD value after conversion
"transaction_hash": "0xabc123...",
"confirmations": 20,
"payment_history": [
{
"deposit_id": "dep_123",
"amount": "100.00000000",
"transaction_hash": "0xabc123...",
"confirmations": 20,
"timestamp": "2024-12-27T10:05:00Z"
}
],
"total_paid_amount": "100.00000000"
}
}
Special Cases
Overpayment:
{
"status": "completed",
"payment_type": "overpayment",
"total_paid_amount": "150.00000000",
"overpayment_amount": "50.00000000",
"overpayment_usd_value": "49.75",
"amount_limited": true, // If amount was capped
"rejected_amount": "30.00000000" // If some overpayment was rejected
}
Partial Payment:
{
"status": "partially_paid",
"payment_type": "partial",
"total_paid_amount": "50.00000000"
}
Expired:
{
"status": "expired",
"timestamp": "2024-12-27T10:30:00Z"
}
Webhook Verification
// PHP example
$webhook_secret = 'your_webhook_secret';
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'];
$payload = file_get_contents('php://input');
$expected_signature = hash_hmac('sha256', $payload, $webhook_secret);
if (!hash_equals($signature, $expected_signature)) {
http_response_code(401);
exit('Invalid signature');
}
// Process webhook
$data = json_decode($payload, true);
Withdrawal Flow
Step 1: Check Available Balance
GET /user/balances/
# Response shows your available funds
{
"account": {
"USDTTRC20": {
"amount": "1000.00000000",
"pending_amount": "0.00000000",
"currency": {
"currency": "USDTTRC20",
"blockchain": "TRX",
"token": "USDT"
}
}
}
}
Step 2: Validate Withdrawal Address
POST /withdrawal/validate-address/
{
"address": "TXYZabc123...",
"currency": "USDTTRC20"
}
# Response
{
"is_valid": true,
"address": "TXYZabc123...",
"blockchain": "TRX",
"currency": "USDTTRC20"
}
Step 3: Estimate Withdrawal (with fees)
POST /withdrawal/estimate/
{
"amount": 100.00,
"currency": "USDTTRC20",
"address": "TXYZabc123..." // Optional for better fee accuracy
}
# Response
{
"withdrawal_id": null,
"status": "estimate",
"amount": "98.50000000", // User receives after fees
"requested_amount": "100.00000000",
"fee": "1.50000000", // Total fee in crypto
"platform_fee": "1.00000000", // 1% platform fee
"network_fee": "0.50000000", // Network fee
"blockchain": "TRX",
"token": "USDT",
"currency": "USDTTRC20"
}
Step 4: Create Withdrawal
POST /withdrawal/
{
"amount": 100.00,
"currency": "USDTTRC20",
"address": "TXYZabc123...",
"callback_url": "https://your-site.com/withdrawal-webhook"
}
# Response
{
"withdrawal_id": "660e8400-e29b-12d3-a456-426614174000",
"status": "pending",
"amount": "98.50000000",
"requested_amount": "100.00000000",
"fee": "1.50", // Total fee in USD
"address": "TXYZabc123...",
"created_at": "2024-12-27T11:00:00Z"
}
Step 5: Monitor Withdrawal Status
Webhook for "processing":
{
"withdrawal_id": "660e8400-e29b-12d3-a456-426614174000",
"event": "withdrawal_status_update",
"status": "processing",
"timestamp": "2024-12-27T11:05:00Z",
"data": {
"withdrawal_id": "660e8400-e29b-12d3-a456-426614174000",
"status": "processing",
"amount": "98.50000000",
"currency": "USDTTRC20"
}
}
Webhook for "completed":
{
"withdrawal_id": "660e8400-e29b-12d3-a456-426614174000",
"event": "withdrawal_status_update",
"status": "completed",
"timestamp": "2024-12-27T11:10:00Z",
"data": {
"withdrawal_id": "660e8400-e29b-12d3-a456-426614174000",
"status": "completed",
"transaction_hash": "0xdef456...",
"confirmations": 20,
"completed_at": "2024-12-27T11:10:00Z"
}
}
Common Integration Patterns
1. E-commerce Integration
// Create payment when order is placed
async function createPayment(order) {
const payment = await cryptofuse.createPayment({
amount: order.total,
currency: 'USDTTRC20',
order_id: order.id,
callback_url: `${BASE_URL}/webhooks/cryptofuse`
});
// Save payment info
await db.savePaymentInfo(order.id, payment.transaction_id);
// Redirect to payment page
return {
payment_address: payment.blockchain_address,
amount: payment.amount_crypto,
expires_at: payment.expiry_time
};
}
// Handle webhook
async function handleWebhook(data) {
if (data.event === 'payment_status_update') {
const order = await db.getOrderByPaymentId(data.transaction_id);
switch (data.status) {
case 'confirming':
await db.updateOrderStatus(order.id, 'payment_received');
break;
case 'completed':
await db.updateOrderStatus(order.id, 'paid');
await fulfillOrder(order);
break;
case 'expired':
await db.updateOrderStatus(order.id, 'payment_expired');
break;
}
}
}
2. Subscription Service
# Check minimum amount before creating payment
def create_subscription_payment(plan_id, user_id):
plan = get_plan(plan_id)
# Check minimum amount
min_amount = cryptofuse.get_min_amount('USDTTRC20')
if plan.price < min_amount['min_amount']:
raise ValueError(f"Plan price below minimum: ${min_amount['min_amount']}")
# Create payment
payment = cryptofuse.create_payment(
amount=plan.price,
currency='USDTTRC20',
order_id=f'sub_{user_id}_{plan_id}',
order_description=f'{plan.name} subscription',
callback_url=WEBHOOK_URL
)
return payment
3. Handling Multiple Currencies
// Let user choose currency
async function getUserPaymentOptions(amount_usd) {
const currencies = await cryptofuse.getCurrencies({
full: true,
min_max: true,
include_usd: true
});
const options = [];
for (const currency of currencies) {
if (amount_usd >= parseFloat(currency.min_amount_usd)) {
// Get exchange rate
const rate = await cryptofuse.getRate({
amount: amount_usd,
currency_from: 'USD',
currency_to: currency.currency
});
options.push({
currency: currency.currency,
blockchain: currency.blockchain,
token: currency.token,
amount_crypto: rate.estimated_amount,
is_stable: currency.is_stable
});
}
}
return options;
}
Testing with Testnet
When USE_TESTNET=true, use these amounts to simulate different scenarios:
Payment Test Amounts (USD)
- 123.45 - Instant success (full payment)
- 234.56 - Success after 30 seconds
- 345.67 - Partial payment (50%)
- 456.78 - Overpayment (150%)
- 567.89 - Expired payment
- 678.90 - Failed payment
Example Test Flow
# 1. Create test payment that will succeed instantly
POST /payments/
{
"amount": 123.45,
"currency": "USDTTRC20",
"price_currency": "USD",
"callback_url": "https://webhook.site/your-unique-url"
}
# 2. You'll receive webhooks:
# - "confirming" immediately
# - "completed" after a few seconds
# 3. Test partial payment
POST /payments/
{
"amount": 345.67,
"currency": "USDTTRC20",
"price_currency": "USD"
}
# Receives 50% and completes as partial payment
Best Practices
1. Always Validate Webhooks
- Verify signature
- Check transaction_id exists in your system
- Validate status transitions
2. Handle All Payment Scenarios
- Full payments
- Partial payments (if accepting)
- Overpayments
- Expired payments
- Failed payments
3. Implement Idempotency
- Webhooks may be sent multiple times
- Use transaction_id as idempotency key
- Don't process the same status update twice
4. Error Handling
try {
const payment = await cryptofuse.createPayment(data);
} catch (error) {
if (error.code === 'invalid_currency') {
// Currency not available
} else if (error.code === 'invalid_request') {
// Check error.details for field errors
} else if (error.code === 'insufficient_balance') {
// For withdrawals
}
}
5. Monitor Expiry Times
- Payments expire after configured time (default 30 minutes)
- Show countdown to users
- Handle expired payments gracefully
6. Currency Precision
- Different currencies have different decimal places
- USDT typically uses 6 decimals
- BTC uses 8 decimals
- Always use the full precision in amounts
Troubleshooting
Common Issues
-
"Currency not supported"
- Check
/currencies/endpoint for available options - Ensure currency is enabled for your account
- Check
-
"Amount below minimum"
- Check
/payments/min-amount/?currency=XXX - Each currency has different minimums
- Check
-
Webhook not received
- Verify callback_url is accessible
- Check webhook signature validation
- Look for webhook logs in your tenant dashboard
-
Payment stuck in "confirming"
- Normal - waiting for blockchain confirmations
- Different blockchains require different confirmation counts
- Will auto-complete when confirmed
-
Overpayment handling
- System has limits on acceptable overpayment
- Excess may be rejected (see webhook data)
- Configure overpayment_threshold_usd in settings
Support
For additional help:
- API Status:
GET /status/ - Detailed API docs: See OpenAPI/Swagger documentation
- Integration support: Contact your account manager