Security
1. Protect Your API Keys
Never expose API keys in frontend code or public repositories!
# .env file (add to .gitignore)
ONECLICK_API_KEY = your_key_here
const apiKey = process . env . ONECLICK_API_KEY ;
2. Backend Only
Always call OCPay API from your backend, never from frontend:
// ❌ WRONG - Frontend
fetch ( "https://api.oneclickdz.com/v3/ocpay/createLink" , {
headers: { "X-Access-Token" : "YOUR_KEY" }, // Exposed to users!
});
// ✅ CORRECT - Backend
// Frontend calls YOUR API, your backend calls OneClick
fetch ( "/api/create-payment" , { method: "POST" });
function validateOrderData ( data ) {
if ( ! Number . isInteger ( data . amount )) {
throw new Error ( "Amount must be integer" );
}
if ( data . amount < 500 || data . amount > 500000 ) {
throw new Error ( "Amount must be between 500 and 500,000 DZD" );
}
if ( ! data . title || data . title . trim (). length === 0 ) {
throw new Error ( "Title is required" );
}
return data ;
}
4. Verify Before Fulfillment
Always verify payment status on backend before fulfilling orders!
async function fulfillOrder ( orderId ) {
const order = await db . orders . findOne ({ id: orderId });
// CRITICAL: Verify payment status
const response = await fetch (
`https://api.oneclickdz.com/v3/ocpay/checkPayment/ ${ order . paymentRef } ` ,
{
headers: { "X-Access-Token" : process . env . ONECLICK_API_KEY },
}
);
const data = await response . json ();
if ( data . data . status !== "CONFIRMED" ) {
throw new Error ( "Payment not confirmed" );
}
// Safe to fulfill
await processOrder ( order );
}
Error Handling
Handle API Errors
async function createPaymentSafe ( orderId , amount , title ) {
try {
const response = await fetch (
"https://api.oneclickdz.com/v3/ocpay/createLink" ,
{
method: "POST" ,
headers: {
"Content-Type" : "application/json" ,
"X-Access-Token" : process . env . ONECLICK_API_KEY ,
},
body: JSON . stringify ({
productInfo: { title , amount },
}),
}
);
if ( ! response . ok ) {
if ( response . status === 403 ) {
throw new Error ( "Merchant not validated" );
}
throw new Error ( "API request failed" );
}
const data = await response . json ();
if ( ! data . success ) {
throw new Error ( data . error ?. message || "Unknown error" );
}
return data . data ;
} catch ( error ) {
console . error ( "Payment creation failed:" , error );
throw error ;
}
}
Testing
Use Sandbox
Test with sandbox keys before production:
# Development
ONECLICK_API_KEY = sk_sandbox_abc123...
# Production
ONECLICK_API_KEY = sk_live_xyz789...
Test Scenarios
Test these cases:
✅ Successful payment
✅ Failed payment
✅ Expired payment link (20 min)
✅ Customer returns without paying
✅ API errors
Production Checklist
Before going live:
Security
Functionality
Testing
Monitoring
Common Mistakes
Avoid these:
❌ Hardcoding API keys
❌ Calling API from frontend
❌ Not saving paymentRef
❌ Fulfilling without verification
❌ No error handling
❌ Checking too frequently (respect rate limits)
❌ Not testing in sandbox first
Database Best Practices
Add indexes for performance:
-- Speed up pending order queries
CREATE INDEX idx_orders_pending
ON orders( status , payment_ref)
WHERE status = 'PENDING' ;
-- Speed up paymentRef lookups
CREATE INDEX idx_payment_ref ON orders(payment_ref);
Logging
Log important events:
// Log payment creation
console . log ( "[Payment] Created" , {
orderId ,
paymentRef ,
amount ,
timestamp: new Date (),
});
// Log status changes
console . log ( "[Payment] Status changed" , {
orderId ,
oldStatus: "PENDING" ,
newStatus: "PAID" ,
timestamp: new Date (),
});
Next Steps
API Reference Complete API documentation
Contact Support Get help from our team
Dashboard Monitor your payments
Security Guide Advanced security practices
You’re Ready! 🎉
You now have everything to accept payments with OCPay. Start with sandbox, test thoroughly, then go live!