Authentication
CryptoPay uses Bearer token authentication for all API requests. This guide covers how to obtain and use authentication tokens securely.
Getting Your API Key
1. Register an Account
First, create your merchant account:
curl -X POST /api/auth/register \
-H "Content-Type: application/json" \
-d '{
"username": "your-username",
"email": "your-email@example.com",
"password": "your-secure-password",
"shop_name": "Your Business Name"
}'
2. Login to Get Access Token
curl -X POST /api/auth/login \
-H "Content-Type: application/json" \
-d '{
"username": "your-username",
"password": "your-password"
}'
Response:
{
"access": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"refresh": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"user": {
"id": 123,
"username": "your-username",
"email": "your-email@example.com"
}
}
Using Authentication Tokens
Bearer Token Format
Include your access token in the Authorization header:
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
Example API Request
curl -X GET /api/payment-orders/ \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json"
JavaScript Example
const apiKey = process.env.CRYPTOPAY_API_KEY;
const response = await fetch('/api/payment-orders/', {
method: 'GET',
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
}
});
Token Management
Token Expiration
- Access tokens expire after 24 hours
- Refresh tokens expire after 30 days
- Use refresh tokens to get new access tokens without re-login
Refreshing Tokens
curl -X POST /api/auth/token/refresh/ \
-H "Content-Type: application/json" \
-d '{
"refresh": "your-refresh-token"
}'
Response:
{
"access": "new-access-token",
"refresh": "new-refresh-token"
}
Automatic Token Refresh
class CryptoPayClient {
constructor(accessToken, refreshToken) {
this.accessToken = accessToken;
this.refreshToken = refreshToken;
}
async makeRequest(url, options = {}) {
let response = await fetch(url, {
...options,
headers: {
'Authorization': `Bearer ${this.accessToken}`,
'Content-Type': 'application/json',
...options.headers
}
});
// If token expired, refresh and retry
if (response.status === 401) {
await this.refreshAccessToken();
response = await fetch(url, {
...options,
headers: {
'Authorization': `Bearer ${this.accessToken}`,
'Content-Type': 'application/json',
...options.headers
}
});
}
return response;
}
async refreshAccessToken() {
const response = await fetch('/api/auth/token/refresh/', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
refresh: this.refreshToken
})
});
if (response.ok) {
const data = await response.json();
this.accessToken = data.access;
this.refreshToken = data.refresh;
} else {
throw new Error('Failed to refresh token');
}
}
}
API Key Management
Creating API Keys
For production applications, create dedicated API keys:
- Login to your dashboard
- Go to Settings > API Keys
- Click Create New Key
- Set permissions and expiration
- Copy the key immediately (it won't be shown again)
API Key Permissions
You can create keys with specific permissions:
- Read Only: View payment orders and transactions
- Create Payments: Create new payment orders
- Manage Webhooks: Configure webhook endpoints
- Full Access: All operations
Key Rotation
Regularly rotate your API keys for security:
// Environment-based key management
const getApiKey = () => {
const env = process.env.NODE_ENV;
switch (env) {
case 'production':
return process.env.CRYPTOPAY_PROD_API_KEY;
case 'staging':
return process.env.CRYPTOPAY_STAGING_API_KEY;
default:
return process.env.CRYPTOPAY_DEV_API_KEY;
}
};
Security Best Practices
Secure Storage
✅ Do:
// Store in environment variables
const apiKey = process.env.CRYPTOPAY_API_KEY;
// Use secure key management services
const apiKey = await getSecretFromVault('cryptopay-api-key');
❌ Don't:
// Never hardcode keys
const apiKey = 'cp_live_abc123def456';
// Never commit keys to version control
const config = {
apiKey: 'cp_live_abc123def456' // This will be in git history!
};
Network Security
Always use HTTPS for API requests:
// ✅ Secure
const apiUrl = '';
// ❌ Insecure
const apiUrl = 'http://api.cryptopay.com';
Error Handling
Handle authentication errors gracefully:
async function makeAuthenticatedRequest(url, options) {
try {
const response = await fetch(url, {
...options,
headers: {
'Authorization': `Bearer ${apiKey}`,
...options.headers
}
});
if (response.status === 401) {
throw new Error('Authentication failed - check your API key');
} else if (response.status === 403) {
throw new Error('Insufficient permissions for this operation');
} else if (!response.ok) {
throw new Error(`API request failed: ${response.status}`);
}
return await response.json();
} catch (error) {
console.error('API request error:', error);
throw error;
}
}
Testing Authentication
Sandbox Environment
Use sandbox for testing without real money:
const config = {
apiUrl: process.env.NODE_ENV === 'production'
? ''
: 'https://sandbox-api.cryptopay.com',
apiKey: process.env.NODE_ENV === 'production'
? process.env.CRYPTOPAY_PROD_API_KEY
: process.env.CRYPTOPAY_SANDBOX_API_KEY
};
Verify Authentication
Test your authentication setup:
# Test API key validity
curl -X GET /api/auth/verify/ \
-H "Authorization: Bearer YOUR_API_KEY"
Success Response:
{
"valid": true,
"user": {
"id": 123,
"username": "your-username",
"permissions": ["read", "create_payments"]
},
"expires_at": "2024-01-02T12:00:00Z"
}
Common Authentication Errors
401 Unauthorized
Cause: Invalid or expired token Solution: Check your API key or refresh your token
{
"error": {
"code": "INVALID_TOKEN",
"message": "The provided token is invalid or expired"
}
}
403 Forbidden
Cause: Insufficient permissions Solution: Use an API key with appropriate permissions
{
"error": {
"code": "INSUFFICIENT_PERMISSIONS",
"message": "Your API key doesn't have permission for this operation"
}
}
429 Rate Limited
Cause: Too many requests Solution: Implement exponential backoff
{
"error": {
"code": "RATE_LIMITED",
"message": "Too many requests. Try again later."
},
"retry_after": 60
}
HTTP Client Examples
JavaScript with fetch()
const apiKey = process.env.CRYPTOPAY_API_KEY;
const apiUrl = process.env.NODE_ENV === 'production'
? ''
: 'https://sandbox-api.cryptopay.com';
// List payment orders
const response = await fetch(`${apiUrl}/api/payment-orders/`, {
headers: {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
}
});
const orders = await response.json();
Python with requests
import os
import requests
api_key = os.environ['CRYPTOPAY_API_KEY']
api_url = '' if os.environ.get('NODE_ENV') == 'production' else 'https://sandbox-api.cryptopay.com'
# List payment orders
response = requests.get(
f'{api_url}/api/payment-orders/',
headers={
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json'
}
)
orders = response.json()
Webhook Authentication
Webhooks use HMAC signatures instead of Bearer tokens:
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret) {
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(payload, 'utf8')
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature, 'hex'),
Buffer.from(expectedSignature, 'hex')
);
}
app.post('/webhooks/cryptopay', (req, res) => {
const signature = req.headers['x-webhook-signature'];
const payload = JSON.stringify(req.body);
if (!verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Process webhook...
res.status(200).send('OK');
});
Next Steps
- Payment Orders API - Create and manage payments
- Webhooks - Set up real-time notifications
- Security Guide - Security best practices
- Integration Examples - Code examples