Create Order API
Lock in a quote and create a payment order. This API converts a quote into an executable payment order with guaranteed pricing.
Endpoint
POST /v1/order/createAuthentication
This endpoint requires API key authentication:
Authorization: Bearer YOUR_API_KEYRequest Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
checkoutId | string | ✅ | Checkout session identifier |
quoteId | string | ✅ | Quote identifier from Get Quote API |
userAddress | string | ✅ | User's wallet address |
recipientAddress | string | ❌ | Custom recipient address (defaults to merchant address) |
metadata | object | ❌ | Additional order metadata |
Example Request
{
"checkoutId": "checkout_1759231185333_abc123",
"quoteId": "quote_1759231185333_def456",
"userAddress": "0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8e8",
"recipientAddress": "0x8ba1f109551bD432803012645Hac136c22C501e5",
"metadata": {
"customerNote": "Express delivery requested",
"referralCode": "FRIEND20"
}
}Response Format
Success Response
{
"success": true,
"data": {
"orderId": "order_1759231185333_ghi789",
"checkoutId": "checkout_1759231185333_abc123",
"quoteId": "quote_1759231185333_def456",
"status": "pending_payment",
"paymentAmount": "100.50",
"settlementAmount": "100.00",
"paymentToken": {
"address": "0x7F5c764cBc14f9669B88837ca1490cCa17c31607",
"decimals": 6,
"symbol": "USDC.e",
"chainId": 10
},
"settlementToken": {
"address": "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
"decimals": 6,
"symbol": "USDC",
"chainId": 137
},
"userAddress": "0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8e8",
"recipientAddress": "0x8ba1f109551bD432803012645Hac136c22C501e5",
"constraints": {
"maxSlippage": "0.5%",
"minOutputAmount": "99.50",
"deadline": 1759234785
},
"fees": {
"total": {
"amount": "0.50",
"amountUsd": "0.50",
"percentage": "0.5%"
},
"breakdown": {
"networkFee": "0.20",
"bridgeFee": "0.15",
"platformFee": "0.15"
}
},
"estimatedTime": 420,
"createdAt": 1759231185,
"expiresAt": 1759234785,
"metadata": {
"customerNote": "Express delivery requested",
"referralCode": "FRIEND20"
}
},
"timestamp": "2024-01-01T00:00:00Z"
}Response Fields
| Field | Type | Description |
|---|---|---|
orderId | string | Unique order identifier |
status | string | Order status (pending_payment, expired, completed, failed) |
paymentAmount | string | Amount user needs to pay |
settlementAmount | string | Amount merchant will receive |
constraints | object | Payment constraints and limits |
fees | object | Detailed fee breakdown |
estimatedTime | number | Estimated completion time in seconds |
expiresAt | number | Order expiration timestamp |
Order Status Values
| Status | Description |
|---|---|
pending_payment | Waiting for user to initiate payment |
processing | Payment is being processed |
bridging | Cross-chain transfer in progress |
settling | Final settlement in progress |
completed | Order successfully completed |
failed | Order failed (may be retryable) |
expired | Order expired without payment |
cancelled | Order cancelled by user or merchant |
Error Responses
Quote Expired
{
"success": false,
"error": {
"code": "QUOTE_EXPIRED",
"message": "Quote has expired, please request a new quote",
"details": {
"quoteId": "quote_1759231185333_def456",
"expiredAt": 1759231485,
"currentTime": 1759231500
}
},
"timestamp": "2024-01-01T00:00:00Z"
}Invalid Checkout
{
"success": false,
"error": {
"code": "INVALID_CHECKOUT",
"message": "Checkout session not found or expired",
"details": {
"checkoutId": "checkout_1759231185333_abc123"
}
},
"timestamp": "2024-01-01T00:00:00Z"
}Insufficient Balance
{
"success": false,
"error": {
"code": "INSUFFICIENT_BALANCE",
"message": "User has insufficient balance for this payment",
"details": {
"required": "100.50",
"available": "50.25",
"token": "USDC.e",
"chainId": 10
}
},
"timestamp": "2024-01-01T00:00:00Z"
}Code Examples
JavaScript/TypeScript
import { CyberPaySDK } from '@cyberpay/sdk';
const sdk = new CyberPaySDK({
apiKey: 'YOUR_API_KEY',
environment: 'production'
});
async function createOrder() {
try {
const order = await sdk.order.create({
checkoutId: 'checkout_1759231185333_abc123',
quoteId: 'quote_1759231185333_def456',
userAddress: '0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8e8',
metadata: {
customerNote: 'Express delivery requested'
}
});
console.log('Order created:', order);
return order;
} catch (error) {
console.error('Error creating order:', error);
if (error.code === 'QUOTE_EXPIRED') {
// Get a new quote and retry
const newQuote = await sdk.quote.get({...});
return createOrder(newQuote.quoteId);
}
throw error;
}
}cURL
curl -X POST https://api.cyberpay.org/v1/order/create \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"checkoutId": "checkout_1759231185333_abc123",
"quoteId": "quote_1759231185333_def456",
"userAddress": "0x742d35Cc6634C0532925a3b8D4C9db96C4b4d8e8",
"metadata": {
"customerNote": "Express delivery requested"
}
}'Python
import requests
def create_order(checkout_id, quote_id, user_address):
url = "https://api.cyberpay.org/v1/order/create"
headers = {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json"
}
data = {
"checkoutId": checkout_id,
"quoteId": quote_id,
"userAddress": user_address,
"metadata": {
"customerNote": "Express delivery requested"
}
}
response = requests.post(url, headers=headers, json=data)
if response.status_code == 200:
return response.json()
else:
error = response.json()
if error.get('error', {}).get('code') == 'QUOTE_EXPIRED':
# Handle expired quote
print("Quote expired, need to get new quote")
raise Exception(f"API Error: {error}")Integration Patterns
Basic Order Creation
// 1. Create checkout
const checkout = await sdk.checkout.create({...});
// 2. Get quote
const quote = await sdk.quote.get({
checkoutId: checkout.checkoutId,
paymentToken: selectedToken,
amount: checkout.amount
});
// 3. Create order
const order = await sdk.order.create({
checkoutId: checkout.checkoutId,
quoteId: quote.quoteId,
userAddress: userWalletAddress
});
// 4. Proceed to payment
console.log('Order ready for payment:', order.orderId);Error Handling with Retry Logic
async function createOrderWithRetry(checkoutId, quoteId, userAddress, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await sdk.order.create({
checkoutId,
quoteId,
userAddress
});
} catch (error) {
if (error.code === 'QUOTE_EXPIRED' && attempt < maxRetries) {
console.log(`Quote expired, getting new quote (attempt ${attempt})`);
// Get fresh quote
const newQuote = await sdk.quote.get({
checkoutId,
paymentToken: originalPaymentToken,
amount: originalAmount
});
quoteId = newQuote.quoteId;
continue;
}
throw error;
}
}
}Order Status Monitoring
async function monitorOrder(orderId) {
const maxAttempts = 60; // 5 minutes with 5-second intervals
let attempts = 0;
while (attempts < maxAttempts) {
const status = await sdk.order.getStatus(orderId);
console.log(`Order ${orderId} status: ${status.status}`);
if (['completed', 'failed', 'expired', 'cancelled'].includes(status.status)) {
return status;
}
// Wait 5 seconds before next check
await new Promise(resolve => setTimeout(resolve, 5000));
attempts++;
}
throw new Error('Order monitoring timeout');
}Webhook Integration
Set up webhooks to receive order status updates:
// Webhook handler
app.post('/webhooks/cyberpay/orders', (req, res) => {
const signature = req.headers['x-cyberpay-signature'];
const payload = req.body;
// Verify webhook signature
if (!sdk.webhooks.verify(payload, signature)) {
return res.status(401).send('Invalid signature');
}
const { event, data } = payload;
switch (event) {
case 'order.created':
console.log('Order created:', data.orderId);
break;
case 'order.payment_received':
console.log('Payment received for order:', data.orderId);
// Update order status in your database
break;
case 'order.completed':
console.log('Order completed:', data.orderId);
// Fulfill the order, send confirmation email
break;
case 'order.failed':
console.log('Order failed:', data.orderId, data.failureReason);
// Handle failed order, possibly retry or refund
break;
}
res.status(200).send('OK');
});Best Practices
Quote Management
- Always check quote expiration before creating orders
- Implement automatic quote refresh for better UX
- Cache quotes temporarily to reduce API calls
- Handle quote expiration gracefully with retry logic
Order Validation
- Validate user balance before creating orders
- Check token allowances for ERC-20 payments
- Verify user address format and network compatibility
- Implement proper error handling for all failure scenarios
Security
- Validate all webhook signatures
- Store sensitive metadata securely
- Use HTTPS for all API communications
- Implement proper API key management
Performance
- Use appropriate timeout values for order creation
- Implement exponential backoff for retries
- Cache frequently accessed data
- Monitor API response times
Rate Limits
- Standard: 100 requests per minute
- Premium: 1000 requests per minute
- Enterprise: Custom limits available
Next Steps
After creating an order:
- Execute Payment - Process the cross-chain transaction
- Query Status - Monitor payment progress
- Webhook Setup - Configure real-time notifications
Support
- 📧 Email: support@cyberpay.org
- 💬 Telegram: @cyberpay_support
- 📖 Documentation: docs.cyberpay.org
