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/v1
Authentication
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_here
Security 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_id
Your order ID to associate with business ordersamount
Order amount in USDT (string format)callback_url
Without this, you'll need to poll the order status API
expire_minutes
Order 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_here
Webhook 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
200
Request successful400
Bad request parameters401
Invalid API key404
Resource not found429
Rate limit exceeded500
Internal 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 crypto
2. Start Server
node server.js