http://localhost:3000/api
Production: Update to your deployed backend URL
Currently uses no authentication. In production, implement:
- JWT Bearer tokens
- OAuth 2.0
- API keys with rate limiting
Endpoint: GET /api/health
Description: Check if the backend is running
Response:
{
"status": "ok",
"timestamp": "2025-12-26T10:30:00.000Z"
}Endpoint: GET /api/billing/address
Description: Retrieve complete billing address and card data
Headers:
Content-Type: application/json
Authorization: Bearer {token} (optional, implement in production)
Response (200 OK):
{
"success": true,
"data": {
"card_number": "4532-1111-2222-3333",
"expiry_date": "12/25",
"cvv": "***",
"address": {
"apt_unit": "Suite 100",
"address_line_1": "123 Main Street",
"address_line_2": "Building A",
"street": "Main Street",
"city": "San Francisco",
"state_province": "CA",
"country": "United States",
"postal_code": "94105"
}
},
"timestamp": "2025-12-26T10:30:00.000Z"
}Error Response (500):
{
"success": false,
"error": "Internal server error"
}cURL Example:
curl -X GET http://localhost:3000/api/billing/address \
-H "Content-Type: application/json"Endpoint: POST /api/billing/export-encrypted-csv
Description: Encrypt and export selected billing fields as CSV
Headers:
Content-Type: application/json
Request Body:
{
"password": "SecurePassword123",
"fields": [
"apt_unit",
"address_line_1",
"address_line_2",
"street",
"city",
"state_province",
"country",
"postal_code",
"card_number",
"expiry_date"
]
}Supported Fields:
apt_unit- Apartment/Unit numberaddress_line_1- Primary address lineaddress_line_2- Secondary address linestreet- Street namecity- City namestate_province- State or Provincecountry- Country namepostal_code- Postal/Zip codecard_number- Card number (last 4 or masked)expiry_date- Card expiry datecvv- NOT EXPORTED for security
Response (200 OK):
{
"success": true,
"encrypted": "{\"salt\":\"...\",\"iv\":\"...\",\"tag\":\"...\",\"ciphertext\":\"...\",\"algorithm\":\"aes-256-gcm\",\"iterations\":100000}",
"metadata": {
"algorithm": "aes-256-gcm",
"iterations": 100000
},
"timestamp": "2025-12-26T10:30:00.000Z",
"instructions": "Save this payload and provide your password to decrypt"
}Error Response (400):
{
"success": false,
"error": "Password must be at least 8 characters"
}Error Response (400):
{
"success": false,
"error": "At least one field must be selected for export"
}Error Response (500):
{
"success": false,
"error": "Failed to encrypt CSV data"
}cURL Example:
curl -X POST http://localhost:3000/api/billing/export-encrypted-csv \
-H "Content-Type: application/json" \
-d '{
"password": "SecurePassword123",
"fields": ["address_line_1", "city", "state_province", "postal_code"]
}'JavaScript Example:
const response = await fetch('http://localhost:3000/api/billing/export-encrypted-csv', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
password: 'SecurePassword123',
fields: ['address_line_1', 'city', 'state_province', 'postal_code']
})
});
const result = await response.json();
console.log(result);Endpoint: POST /api/billing/decrypt-csv
Description: Decrypt a previously exported encrypted CSV file
Headers:
Content-Type: application/json
Request Body:
{
"password": "SecurePassword123",
"payload": "{\"salt\":\"...\",\"iv\":\"...\",\"tag\":\"...\",\"ciphertext\":\"...\",\"algorithm\":\"aes-256-gcm\",\"iterations\":100000}"
}Response (200 OK):
{
"success": true,
"data": "apt_unit,address_line_1,address_line_2\nSuite 100,123 Main Street,Building A",
"timestamp": "2025-12-26T10:30:00.000Z"
}Error Response (400):
{
"success": false,
"error": "Decryption failed - invalid password or corrupted data"
}cURL Example:
curl -X POST http://localhost:3000/api/billing/decrypt-csv \
-H "Content-Type: application/json" \
-d '{
"password": "SecurePassword123",
"payload": "{...encrypted payload...}"
}'The encrypted payload is a JSON object containing:
{
"salt": "base64-encoded-salt",
"iv": "base64-encoded-initialization-vector",
"tag": "base64-encoded-authentication-tag",
"ciphertext": "base64-encoded-encrypted-data",
"algorithm": "aes-256-gcm",
"iterations": 100000
}Field Descriptions:
salt: Random 32-byte value for PBKDF2 key derivationiv: Random 16-byte initialization vector for GCM modetag: 16-byte authentication tag for integrity verificationciphertext: Encrypted CSV dataalgorithm: Encryption algorithm (aes-256-gcm)iterations: PBKDF2 iterations for key derivation
- Generate random 32-byte salt
- Derive 256-bit key from password using PBKDF2 (100,000 iterations, SHA-256)
- Generate random 16-byte IV
- Encrypt CSV data using AES-256-GCM
- Extract authentication tag
- Base64 encode all components
- Return as JSON payload
- Parse JSON payload
- Base64 decode components
- Derive key from password using stored salt
- Decrypt ciphertext using AES-256-GCM
- Verify authentication tag
- Return decrypted CSV data
All endpoints follow standard HTTP status codes:
| Code | Meaning |
|---|---|
| 200 | Success |
| 400 | Bad Request (validation error) |
| 401 | Unauthorized (missing/invalid auth) |
| 403 | Forbidden (insufficient permissions) |
| 500 | Internal Server Error |
Error Response Format:
{
"success": false,
"error": "Description of what went wrong"
}Implement rate limiting on production:
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // 100 requests per window
});
app.use('/api/', limiter);By default, CORS is enabled for localhost. Update backend/server.js:
const allowedOrigins = [
'https://your-portal.com',
'https://card-issuer.com'
];
app.use(cors({
origin: (origin, callback) => {
if (!origin || allowedOrigins.includes(origin)) {
callback(null, true);
} else {
callback(new Error('CORS not allowed'));
}
}
}));- Import collection or create requests manually
- Set base URL:
http://localhost:3000
- GET
/api/health- Verify server is running - GET
/api/billing/address- Get billing data - POST
/api/billing/export-encrypted-csv- Export encrypted CSV - POST
/api/billing/decrypt-csv- Decrypt and verify
- PBKDF2 Iterations: 100,000 (takes ~100ms on typical hardware)
- Encryption: <5ms for typical CSV data
- Network: Add 50-200ms depending on connection
- Total Request Time: 150-300ms typical
- Cache billing data if unchanged
- Use compression for large payloads
- Implement CDN for frontend assets
- Use connection pooling for database
- Always use HTTPS in production
- Validate all input on server side
- Log security events (exports, errors)
- Implement authentication (JWT recommended)
- Use environment variables for secrets
- Rotate encryption keys periodically
- Monitor for abuse with rate limiting
- Audit access with comprehensive logging
Future versions may support webhooks for audit logging:
// Example: POST to external audit service
const auditWebhook = async (event) => {
await fetch('https://audit-service.com/log', {
method: 'POST',
body: JSON.stringify(event)
});
};Last Updated: December 2025
Version: 1.0.0 API