Troubleshooting Guide
This guide covers common issues you might encounter when testing BITXpay APIs and how to resolve them.
Authentication Errors
Error: "Missing or invalid access token"
Error Response:
{
"error": "unauthorized",
"message": "Missing or invalid access token",
"code": 401
}Possible Causes:
- API key not provided in headers
- Incorrect header name
- Invalid API key format
Solutions:
✅ Check header name:
- For merchant APIs: Use
X-API-Key(notAuthorization) - For standard APIs: Use
Authorization: Bearer {token}
✅ Verify API key format:
Correct: btxm_live_xxxxxxxxxxxx or btxm_xxxxxxxxxxxx
Incorrect: Bearer btxm_live_xxxxxxxxxxxx (for X-API-Key header)✅ Ensure key is active:
- Log in to dashboard
- Check API Keys section
- Verify key status is "Active"
Error: "Invalid signature"
Error Response:
{
"error": "unauthorized",
"message": "Invalid signature",
"code": 401
}Possible Causes:
- Incorrect private key
- Wrong signature algorithm
- Message format mismatch
- Character encoding issues
Solutions:
✅ Verify message format:
// Correct format
const message = `${METHOD}${PATH}${TIMESTAMP}${BODY}`;
// Example
"POST/payment_links2026-01-31T17:53:56Z{\"payment_name\":\"Invoice #12345\",\"amount\":100.50,\"currency\":\"USDT\"}"✅ Check signature parameters:
- Algorithm: Ed25519 (EdDSA)
- Hash: None (built into Ed25519)
- Encoding: raw signature bytes, base64-encoded
- Key format: PKCS#8 PEM
✅ Validate private key format:
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIH...
(base64 encoded key)
-----END PRIVATE KEY-----(Ed25519 keys use PKCS#8 format with PRIVATE KEY header, not DSA PRIVATE KEY)
✅ Debug signature generation:
Add logging to see what's being signed:
console.log('Method:', method);
console.log('Path:', path);
console.log('Timestamp:', timestamp);
console.log('Body:', body);
console.log('Message:', message);
console.log('Signature:', signature.substring(0, 50) + '...');✅ Test with known values:
Use this test case to verify your signature generation:
// Test inputs
const method = 'POST';
const path = '/payment_links';
const timestamp = '2026-01-31T12:00:00Z';
const body = '{"payment_name":"Invoice #12345","amount":100.50,"currency":"USDT"}';
// Expected message
const expectedMessage = 'POST/payment_links2026-01-31T12:00:00Z{"payment_name":"Invoice #12345","amount":100.50,"currency":"USDT"}';
// Verify your message matches
console.assert(message === expectedMessage, 'Message format incorrect');Error: "Request timestamp is too old or invalid"
Error Response:
{
"error": "unauthorized",
"message": "Request timestamp is too old or invalid",
"code": 401
}Possible Causes:
- System clock out of sync
- Timestamp format incorrect
- Request took longer than 5 minutes
Solutions:
✅ Check timestamp format:
// Correct: ISO 8601 with Z suffix
const timestamp = new Date().toISOString(); // "2026-01-31T17:53:56.123Z"
// Also acceptable
const timestamp = "2026-01-31T17:53:56Z";
// Incorrect formats
"2026-01-31 17:53:56" // Wrong: missing T and Z
"1706721236" // Wrong: Unix timestamp not supported
"1706721236000" // Wrong: milliseconds not supported✅ Synchronize system clock:
macOS/Linux:
# Check current time
date -u
# Sync with NTP
sudo ntpdate -s time.apple.comWindows:
# Check time
Get-Date
# Sync with internet time
w32tm /resync✅ Generate fresh timestamp:
Ensure timestamp is generated immediately before signing:
// ✅ Correct - fresh timestamp
function makeRequest() {
const timestamp = new Date().toISOString();
const signature = generateSignature(method, path, timestamp, body);
// Make request immediately
}
// ❌ Wrong - stale timestamp
const timestamp = new Date().toISOString();
// ... do other work ...
setTimeout(() => {
const signature = generateSignature(method, path, timestamp, body);
// Timestamp might be too old
}, 10000);Request Errors
Error: "Validation failed"
Error Response:
{
"error": "invalid_request",
"message": "Validation failed",
"code": 400,
"details": [
{
"field": "order_amount",
"issue": "must be greater than 0"
}
]
}Solutions:
✅ Check required fields:
For Create Payment Link:
merchant_key✓order_currency✓order_amount✓payment_name✓payer_email✓success_url✓cancel_url✓
✅ Validate field formats:
// Currency: uppercase crypto currency code
order_currency: "USDT" // ✅
order_currency: "usdt" // ❌ (must be uppercase)
order_currency: "USD" // ❌ (fiat not supported, use USDT or USDC)
// Email: Valid email format
payer_email: "test@example.com" // ✅
payer_email: "test@example" // ❌
payer_email: "invalid-email" // ❌
// Amount: Positive number
order_amount: 10 // ✅
order_amount: 0 // ❌
order_amount: -5 // ❌
order_amount: "10" // ⚠️ (should be number, not string)
// URLs: Valid HTTP/HTTPS URLs
success_url: "https://example.com/success" // ✅
success_url: "example.com" // ❌ (missing protocol)
success_url: "ftp://example.com" // ❌ (must be HTTP/HTTPS)Error: "Payment link not found"
Error Response:
{
"error": "not_found",
"message": "Payment link not found",
"code": 404
}Solutions:
✅ Verify payment ID format:
// Correct: UUID format
"3d0a5e66-f5a5-432e-86e6-e9405a94fba6"
// Or payment reference format
"SDF-453672-PMT"✅ Check environment:
- Sandbox payment IDs only work in sandbox
- Production payment IDs only work in production
✅ Verify payment exists:
- Use List Payment Links endpoint to see all payments
- Check if payment was created successfully
Postman-Specific Issues
Pre-Request Script Not Running
Symptoms:
- Headers not populated
- No console logs
- Signature not generated
Solutions:
✅ Check script location:
- Script should be in Collection pre-request, not individual request
- Go to Collection → Pre-request Script tab
✅ Verify environment is selected:
- Check dropdown in top-right corner
- Ensure correct environment is active
✅ Check console for errors:
- Open Postman Console (View → Show Postman Console)
- Look for JavaScript errors
✅ Test forge library loading:
Add this at the start of your script:
console.log('Script started');
pm.sendRequest('https://cdn.jsdelivr.net/npm/node-forge@1.3.1/dist/forge.min.js', (err, res) => {
if (err) {
console.error('Failed to load forge:', err);
} else {
console.log('Forge loaded successfully');
}
});Environment Variables Not Set
Symptoms:
- Error: "Missing MERCHANT_API_KEY or MERCHANT_PRIVATE_KEY"
- Variables show as
Solutions:
✅ Check variable names (case-sensitive):
Correct: MERCHANT_API_KEY
Wrong: merchant_api_key, Merchant_Api_Key✅ Verify environment is selected:
- Click environment dropdown (top-right)
- Select your BITXpay environment
✅ Check variable scope:
- Variables should be in Environment, not Collection
- Click "Environments" in sidebar
- Select your environment
- Verify variables are listed
✅ Check variable values:
- Click eye icon next to environment dropdown
- Verify "Current Value" is populated
- If empty, click "Persist All" or manually set current values
Private Key Format Issues
Symptoms:
- Error: "Invalid key format"
- Signature generation fails
Solutions:
✅ Preserve newlines:
Option 1: Use \n for newlines
-----BEGIN PRIVATE KEY-----\nMC4CAQAwBQYDK2VwBCIEIH...\n-----END PRIVATE KEY-----Option 2: Use actual newlines
- In Postman, you can paste multi-line text directly
- The variable editor supports multi-line values
✅ Remove extra spaces:
// ❌ Wrong - extra spaces
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIH...
// ✅ Correct - no trailing spaces
-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIH...✅ Verify key markers:
Correct: -----BEGIN PRIVATE KEY----- (PKCS#8 format for Ed25519)
Wrong: -----BEGIN DSA PRIVATE KEY-----
Wrong: -----BEGIN RSA PRIVATE KEY-----Network Issues
Error: "Connection timeout"
Solutions:
✅ Check internet connection
✅ Verify base URL:
Sandbox: https://sandboxapi.bitxpay.com/api/v1
Production: https://api.bitxpay.com/api/v1✅ Check firewall/proxy settings:
- Ensure HTTPS traffic is allowed
- Configure proxy in Postman if needed (Settings → Proxy)
✅ Test API availability:
curl -I https://sandboxapi.bitxpay.com/api/v1/healthError: "SSL certificate problem"
Solutions:
✅ Update certificates:
- Update your operating system
- Update Postman/tool to latest version
✅ Temporary workaround (not recommended for production):
In Postman:
- Settings → General → SSL certificate verification → OFF
⚠️ Warning: Only disable SSL verification for testing in sandbox. Never in production.
Rate Limiting
Error: "Too many requests"
Error Response:
{
"error": "rate_limit_exceeded",
"message": "Too many requests",
"code": 429
}Rate Limits:
- Sandbox: 100 requests/minute
- Production: 1000 requests/minute
Solutions:
✅ Check rate limit headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1706721300✅ Implement retry logic:
async function makeRequestWithRetry(maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const response = await makeRequest();
return response;
} catch (error) {
if (error.code === 429) {
const resetTime = error.headers['X-RateLimit-Reset'];
const waitTime = (resetTime * 1000) - Date.now();
await new Promise(resolve => setTimeout(resolve, waitTime));
} else {
throw error;
}
}
}
}✅ Reduce request frequency:
- Add delays between requests
- Batch operations when possible
- Cache responses
Debugging Checklist
When encountering issues, go through this checklist:
1. Environment Setup
- [ ] Correct environment selected
- [ ] API key is valid and active
- [ ] Private key is in correct format
- [ ] Base URL is correct (sandbox vs production)
2. Request Format
- [ ] HTTP method is correct (POST, GET, PATCH)
- [ ] Endpoint path is correct
- [ ] Headers are properly set
- [ ] Body is valid JSON (for POST/PATCH)
3. Authentication
- [ ] Timestamp is in ISO 8601 format
- [ ] Timestamp is recent (within 5 minutes)
- [ ] Signature message format is correct
- [ ] Signature algorithm parameters are correct
4. Console Logs
- [ ] Check Postman Console for errors
- [ ] Verify signature generation logs
- [ ] Check for network errors
5. Response Analysis
- [ ] Read error message carefully
- [ ] Check error code
- [ ] Review error details array
Getting Help
If you're still experiencing issues:
1. Gather Information
Collect the following:
- Request method and endpoint
- Request headers (redact sensitive values)
- Request body (redact sensitive data)
- Response status code
- Response body
- Console logs (if using Postman)
2. Contact Support
Email: api-support@bitxpay.com
Include:
- Detailed description of the issue
- Steps to reproduce
- Information gathered above
- Your merchant ID (not API key)
3. Check Status Page
Check for any ongoing incidents or maintenance.
Next Steps
- Postman Setup - Complete Postman guide
- API Testing Tools - Try other tools
- Authentication Reference - Deep dive into auth
Support
- Email: api-support@bitxpay.com
- Documentation: https://docs.bitxpay.com/