Skip to main content

Security Best Practices

This guide covers security best practices for integrating the ZenPays SDK into your application.

API Key Security​

Environment Variables​

Always store API keys in environment variables:

// ✅ Good - using environment variables
const zenpays = new ZenPays({
apiKey: process.env.ZENPAYS_API_KEY!,
})

// ❌ Bad - hardcoded API key
const zenpays = new ZenPays({
apiKey: 'zp_live_abc123...',
})

Network Security​

IP Whitelisting​

Restrict API access to known IP addresses:

// Add your server IPs
await zenpays.merchants.addIPToWhitelist('203.0.113.50', 'Production Server')
await zenpays.merchants.addIPToWhitelist('203.0.113.51', 'Backup Server')

TLS/HTTPS​

The SDK always uses HTTPS for API communication. Never disable TLS verification in production:

// The SDK enforces HTTPS by default
const zenpays = new ZenPays({
apiKey: process.env.ZENPAYS_API_KEY!,
// baseUrl defaults to https://api.zenpays.com
})

Authentication Security​

Two-Factor Authentication​

Enable 2FA for all team members with API access:

// Setup 2FA
const setup = await zenpays.security.setup2FA()

// Store backup codes securely
console.log('Backup codes:', setup.backupCodes)

// Verify to complete setup
await zenpays.security.verify2FA({ code: '123456' })

Session Management​

For user-facing applications, implement proper session handling:

// Use short-lived sessions
const session = await authenticate(user)

// Invalidate sessions on logout
await zenpays.security.revokeSession(sessionId)

Webhook Security​

Signature Verification​

Always verify webhook signatures:

import { verifyWebhookSignature } from '@zenxdigitalholdings/zenpays'

app.post('/webhooks/zenpays', (req, res) => {
const signature = req.headers['x-zenpays-signature']
const webhookSecret = process.env.ZENPAYS_WEBHOOK_SECRET!

const isValid = verifyWebhookSignature(
JSON.stringify(req.body),
signature,
webhookSecret
)

if (!isValid) {
return res.status(401).send('Invalid signature')
}

// Process the webhook
handleWebhook(req.body)
res.status(200).send('OK')
})

Replay Attack Prevention​

Check webhook timestamps to prevent replay attacks:

function handleWebhook(payload: WebhookPayload) {
const timestamp = new Date(payload.timestamp)
const now = new Date()
const fiveMinutes = 5 * 60 * 1000

if (now.getTime() - timestamp.getTime() > fiveMinutes) {
throw new Error('Webhook too old - possible replay attack')
}

// Process the webhook...
}

Data Security​

PCI Compliance​

Never handle raw card data on your servers. Use the checkout flow:

// ✅ Good - using checkout link
const intent = await zenpays.payments.createPaymentIntent({
amount: 5000,
currency: 'USD',
})

// Redirect customer to secure checkout
const checkoutUrl = await zenpays.checkout.createCheckoutLink(intent.id)

Sensitive Data Handling​

Never log sensitive information:

// ✅ Good - logging safe fields only
console.log(`Payment ${payment.id} - Amount: ${payment.amount}`)

// ❌ Bad - logging sensitive data
console.log('Payment details:', JSON.stringify(payment))

Error Handling​

Don't Expose Internal Errors​

Show generic messages to users:

try {
await zenpays.payments.createPaymentIntent(data)
}
catch (error) {
// Log detailed error for debugging
console.error('Payment error:', error)

// Show generic message to user
throw new Error('Payment processing failed. Please try again.')
}

Security Monitoring​

Monitor Security Events​

Regularly review security events:

const events = await zenpays.security.listSecurityEvents({
from: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000), // Last 7 days
type: ['login_failed', 'api_key_used', 'suspicious_activity'],
})

events.data.forEach((event) => {
console.log(`${event.type} at ${event.createdAt} from ${event.ipAddress}`)
})

Set Up Alerts​

Configure webhooks for security events:

await zenpays.merchants.createWebhook({
url: 'https://your-app.com/security-alerts',
events: [
'security.suspicious_activity',
'security.api_key_revoked',
'security.login_failed',
],
})

Checklist​

Before going to production:

  • API keys stored in environment variables
  • API keys have minimal required scopes
  • IP whitelisting enabled
  • Webhook signature verification implemented
  • 2FA enabled for all team members
  • Security event monitoring configured
  • No sensitive data in logs
  • Error messages don't expose internal details

Next Steps​