Authentication
Paybin API uses a comprehensive authentication system to ensure secure and reliable communication between your application and our services. This guide covers all aspects of authentication, from basic API key usage to advanced security features.
API Keys
Paybin API uses a dual-key authentication system for enhanced security:
Public Key
- Used in the request body for identification
- Helps track and associate requests with your account
- Not sensitive information, can be shared
Secret Key
- Used in the
X-Api-Key
header for authentication - Never share or expose this key
- Required for all API requests
Example Usage
curl --location 'https://sandbox.paybin.io/v1/merchant/balance' \
--header 'X-Api-Key: YOUR_SECRET_KEY' \
--header 'Content-Type: application/json' \
--data '{
"PublicKey": "YOUR_PUBLIC_KEY"
}'
Hash Verification
For sensitive operations like withdrawals, Paybin requires hash verification to ensure request integrity and prevent tampering.
How Hash Verification Works
- Create a hash string by concatenating specific fields
- Generate MD5 hash of the concatenated string
- Include the hash in your request
- Paybin verifies the hash to ensure data integrity
Hash Generation Formula
// For withdrawal requests
const hashString = Symbol + Amount + Address + MerchantTransactionId + SecretKey;
const hash = CryptoJS.MD5(hashString).toString();
Example Implementation
const CryptoJS = require('crypto-js');
function generateWithdrawHash(data, secretKey) {
const hashString = data.Symbol + data.Amount + data.Address + data.MerchantTransactionId + secretKey;
return CryptoJS.MD5(hashString).toString();
}
// Usage
const withdrawData = {
Symbol: "ETH",
Amount: 0.123,
Address: "0x883d6769e513bc63e757172cdbd5b5eef0806161",
MerchantTransactionId: "WITHDRAW_001"
};
const hash = generateWithdrawHash(withdrawData, "YOUR_SECRET_KEY");
Hash Requirements by Endpoint
Endpoint | Required Fields for Hash |
---|---|
/v1/withdraw/add | Symbol + Amount + Address + MerchantTransactionId |
/v1/verify/start | Symbol + NetworkId + Address + ReferenceId |
/v1/verify/confirmAmount | Symbol + NetworkId + Amount + ReferenceId |
Security Best Practices
๐ API Key Management
- Store keys securely: Use environment variables or secure key management systems
- Rotate keys regularly: Change your API keys periodically
- Use different keys: Separate keys for development and production
- Monitor usage: Regularly check API usage logs for suspicious activity
๐ก๏ธ Request Security
- Use HTTPS: Always make requests over HTTPS
- Validate responses: Verify response signatures when available
- Implement timeouts: Set appropriate request timeouts
- Handle errors gracefully: Don't expose sensitive information in error messages
๐ Code Examples
Environment Variables (Recommended)
# .env file
PAYBIN_PUBLIC_KEY=your_public_key_here
PAYBIN_SECRET_KEY=your_secret_key_here
PAYBIN_API_URL=https://sandbox.paybin.io
// Node.js example
require('dotenv').config();
const config = {
publicKey: process.env.PAYBIN_PUBLIC_KEY,
secretKey: process.env.PAYBIN_SECRET_KEY,
apiUrl: process.env.PAYBIN_API_URL
};
Secure Key Storage
// C# example with Azure Key Vault
using Azure.Security.KeyVault.Secrets;
public class PaybinConfig
{
private readonly SecretClient _secretClient;
public PaybinConfig(string keyVaultUrl)
{
_secretClient = new SecretClient(new Uri(keyVaultUrl), new DefaultAzureCredential());
}
public async Task<string> GetSecretKeyAsync()
{
var secret = await _secretClient.GetSecretAsync("paybin-secret-key");
return secret.Value.Value;
}
}
Rate Limiting
Paybin API implements rate limiting to ensure fair usage and prevent abuse:
Rate Limits
- Standard Plan: 100 requests per minute
- Premium Plan: 1000 requests per minute
- Enterprise Plan: Custom limits
Rate Limit Headers
API responses include rate limit information in headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1640995200
Handling Rate Limits
async function makeApiRequest(url, data, config) {
try {
const response = await axios.post(url, data, config);
return response.data;
} catch (error) {
if (error.response?.status === 429) {
// Rate limit exceeded
const resetTime = error.response.headers['x-ratelimit-reset'];
const waitTime = (resetTime * 1000) - Date.now();
console.log(`Rate limit exceeded. Waiting ${waitTime}ms...`);
await new Promise(resolve => setTimeout(resolve, waitTime));
// Retry the request
return makeApiRequest(url, data, config);
}
throw error;
}
}
Best Practices for Rate Limiting
- Implement exponential backoff: Gradually increase wait time between retries
- Cache responses: Store frequently requested data locally
- Batch requests: Combine multiple operations when possible
- Monitor usage: Track your API usage to stay within limits
Error Handling
Authentication Errors
Error Code | Description | Solution |
---|---|---|
Z503 | Invalid API key | Check your secret key and ensure it's correct |
Z401 | Missing API key | Add the X-Api-Key header to your request |
Z403 | Insufficient permissions | Contact support to verify your account permissions |
Hash Verification Errors
Error Code | Description | Solution |
---|---|---|
Z400 | Invalid hash | Verify your hash generation logic |
Z402 | Missing hash | Include the hash field in your request |
Example Error Handling
async function handleApiError(error) {
if (error.response) {
const { code, message } = error.response.data;
switch (code) {
case 401:
console.error('Authentication failed. Check your API keys.');
break;
case 429:
console.error('Rate limit exceeded. Implement backoff strategy.');
break;
case 400:
if (message === 'Z400') {
console.error('Invalid hash. Check your hash generation.');
}
break;
default:
console.error(`API Error: ${message}`);
}
}
}
Testing Authentication
Sandbox Environment
Always test your authentication implementation in the sandbox environment:
# Sandbox URL
https://sandbox.paybin.io
Test Your Setup
# Test authentication with balance endpoint
curl --location 'https://sandbox.paybin.io/v1/merchant/balance' \
--header 'X-Api-Key: YOUR_SECRET_KEY' \
--header 'Content-Type: application/json' \
--data '{
"PublicKey": "YOUR_PUBLIC_KEY"
}'
Expected Response
{
"apiVersion": "1.0.0.0",
"data": {
"balances": [
{
"symbol": "ETH",
"balance": 0.0
}
]
},
"code": 200,
"message": "OK"
}
If you receive a Z503
error, double-check your API keys and ensure you're using the correct environment URL.