OOPPay API Documentation
OOPPay provides a simple, secure USDT-TRC20 payment solution. Integrate crypto payments into your application with our REST API in just a few minutes.
Quick Integration
Complete integration in 3 steps with real-time webhook notifications
Secure & Reliable
HMAC signature verification, 3-block confirmation, under 30 seconds
Low Fees
Only 0.5% transaction fee with network buffer
API Overview
https://api.ooppay.io/api/v1Authentication
OOPPay API uses API keys for authentication. You can manage your API keys in the merchant dashboard.
API Key Format
All API keys start with mk_MERCHANT_followed by a 32-character random string.
Authorization: Bearer mk_MERCHANT_your_api_key_hereSecurity Notice
Keep your API keys secure and never expose them in client-side code. All API calls must be made over HTTPS.
Order Management
Create Payment Order
Create a new payment order. The system generates a unique payment address for each order.
Request
POST /api/v1/orders
Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
{
"merchant_order_id": "ORDER_20250122_001",
"amount": "10.00",
"callback_url": "https://your-site.com/webhook",
"expire_minutes": 30
}Response
{
"order_id": "550e8400-e29b-41d4-a716-446655440000",
"pay_address": "TN3W4H6rK2ce4vX9YnFQHwKENnHjoxb3m9",
"pay_amount": "11.500000",
"order_amount": "10.000000",
"buffer_amount": "1.500000",
"qr_code_url": "https://api.ooppay.io/qr/550e8400-e29b-41d4-a716-446655440000",
"expire_at": 1737123456
}Request Parameters
merchant_order_idYour order ID to associate with business ordersamountOrder amount in USDT (string format)callback_urlWithout this, you'll need to poll the order status API
expire_minutesOrder expiration time in minutes (default: 30)Query Order Status
Query the current status of an order. We recommend using webhooks as the primary method for payment notifications, with queries as a backup.
GET /api/v1/orders/550e8400-e29b-41d4-a716-446655440000
Authorization: Bearer mk_MERCHANT_your_api_key_hereWebhook Notifications
When payment status changes, we send webhook notifications to your specified callback_url. This is the recommended way to receive payment status updates.
Per-Order Webhook URLs
We use the callback_url from each order request. If no callback_url is provided, no webhook will be sent - you'll need to poll the order status API instead.
Webhook Format
POST https://your-site.com/webhook
Content-Type: application/json
X-Signature: 5d41402abc4b2a76b9719d911017c592
X-Timestamp: 1737123456
{
"order_id": "550e8400-e29b-41d4-a716-446655440000",
"merchant_order_id": "ORDER_20250122_001",
"status": "paid",
"order_amount": "10.000000",
"paid_amount": "11.500000",
"net_amount": "9.950000",
"fee_amount": "0.050000",
"tx_hash": "7c2bb22f6d3c8c9b4fe8d3b4f5e6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4",
"confirmations": 3,
"paid_at": "2025-01-22T10:32:15Z"
}Signature Verification
To ensure webhook security, we sign requests using HMAC-SHA256. You must verify the signature to ensure the request comes from OOPPay.
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, timestamp, secret) {
const { order_id, merchant_order_id, status } = payload;
// Build signature data
const data = order_id + merchant_order_id + status + timestamp;
// Calculate expected signature
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(data)
.digest('hex');
return signature === expectedSignature;
}
// Handle Webhook
app.post('/webhook', express.json(), (req, res) => {
const signature = req.headers['x-signature'];
const timestamp = req.headers['x-timestamp'];
if (!verifyWebhookSignature(req.body, signature, timestamp, WEBHOOK_SECRET)) {
return res.status(400).send('Invalid signature');
}
if (req.body.status === 'paid') {
// Handle successful payment
console.log(`Order ${req.body.order_id} paid successfully`);
deliverProduct(req.body.merchant_order_id, req.body.net_amount);
}
res.status(200).send('OK');
});Best Practices
- • Always verify webhook signatures
- • Implement idempotent processing to avoid duplicates
- • Return HTTP 200 status to acknowledge receipt
- • Set appropriate timeout (recommend 5 seconds)
Error Handling
OOPPay API uses standard HTTP status codes to indicate request success or failure.
HTTP Status Codes
200Request successful400Bad request parameters401Invalid API key404Resource not found429Rate limit exceeded500Internal server errorError Response Format
{
"error": {
"code": "invalid_request",
"message": "Amount parameter must be positive",
"details": {
"field": "amount",
"value": "-10.00"
}
}
}Complete Integration Example
Here's a complete Node.js Express server example showing how to integrate OOPPay payment functionality.
const express = require('express');
const axios = require('axios');
const crypto = require('crypto');
const app = express();
app.use(express.json());
// Configuration
const CONFIG = {
apiKey: 'YOUR_API_KEY',
apiUrl: 'https://api.ooppay.io/api/v1',
webhookSecret: 'YOUR_WEBHOOK_SECRET'
};
// Create payment order
app.post('/create-payment', async (req, res) => {
try {
const { orderId, amount } = req.body;
const response = await axios.post(`${CONFIG.apiUrl}/orders`, {
merchant_order_id: orderId,
amount: amount.toString(),
callback_url: 'https://your-domain.com/webhook',
expire_minutes: 30
}, {
headers: {
'Authorization': `Bearer ${CONFIG.apiKey}`,
'Content-Type': 'application/json'
}
});
res.json({
success: true,
data: response.data
});
} catch (error) {
res.status(500).json({
success: false,
error: error.message
});
}
});
// Handle payment callback
app.post('/webhook', (req, res) => {
const signature = req.headers['x-signature'];
const timestamp = req.headers['x-timestamp'];
// Verify signature
if (!verifyWebhookSignature(req.body, signature, timestamp, CONFIG.webhookSecret)) {
return res.status(400).send('Invalid signature');
}
// Handle successful payment
if (req.body.status === 'paid') {
console.log(`Payment successful for order ${req.body.order_id}`);
console.log(`Net amount received: ${req.body.net_amount} USDT`);
// Execute your business logic here
deliverProduct(req.body.merchant_order_id, req.body.net_amount);
}
res.status(200).send('OK');
});
function verifyWebhookSignature(payload, signature, timestamp, secret) {
const { order_id, merchant_order_id, status } = payload;
const data = order_id + merchant_order_id + status + timestamp;
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(data)
.digest('hex');
return signature === expectedSignature;
}
function deliverProduct(orderId, amount) {
// Implement your product delivery logic
console.log(`Delivering product for order ${orderId}, amount: ${amount} USDT`);
}
app.listen(3000, () => {
console.log('Server running on port 3000');
});1. Install Dependencies
npm install express axios crypto2. Start Server
node server.js