Go Live
Everything you need to do before accepting real payments.
Go Live Checklist
Before you start accepting real payments, complete this checklist to ensure a smooth launch.
Pre-Launch Checklist
Account Setup
- Complete business verification - Submit required documents in the Dashboard
- Add bank account for payouts - Set up where you'll receive funds
- Set up team members - Invite team with appropriate permissions
- Configure notification settings - Set up email alerts for important events
API Integration
- Switch to live API keys - Replace
sk_test_withsk_live_ - Update base URL - Use
api.paygate.com.ghinstead of sandbox - Verify webhook endpoints - Ensure production URLs are configured
- Test with real transaction - Make a small real payment
Security
- Secure API keys - Never expose keys in client-side code
- Implement webhook signature verification - Verify all webhook signatures
- Enable HTTPS - All endpoints must use HTTPS
- Set up monitoring - Monitor for errors and unusual activity
Error Handling
- Handle all error types - Test error scenarios
- Implement retry logic - For transient failures
- Set up alerting - Get notified of failures
- Create user-friendly error messages - Map error codes to helpful messages
Step-by-Step Guide
Complete Business Verification
Before you can accept live payments, verify your business:
- Go to Settings > Business in your Dashboard
- Upload required documents:
- Business registration certificate
- Tax identification number (TIN)
- ID of business owner
- Bank statement or utility bill
- Wait for verification (usually 1-2 business days)
You can continue development in test mode while verification is pending.
Switch to Live API Keys
Replace your test keys with live keys:
// Before (Test)
const paygate = new PayGate('sk_test_...')
// After (Live)
const paygate = new PayGate(process.env.PAYGATE_SECRET_KEY)
// Where PAYGATE_SECRET_KEY is sk_live_...Important: Use environment variables, never hardcode keys:
# .env.production
PAYGATE_SECRET_KEY=sk_live_...
PAYGATE_WEBHOOK_SECRET=whsec_...Update Webhook Endpoints
Create production webhook endpoints:
- Go to Settings > Webhooks
- Add your production endpoint URL
- Select events to receive
- Copy the new webhook secret
- Update your server configuration
// Use production webhook secret
const endpointSecret = process.env.PAYGATE_WEBHOOK_SECRETVerify Webhook Signatures
Always verify signatures in production:
app.post('/webhooks', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-paygate-signature']
let event
try {
event = Webhook.constructEvent(
req.body,
signature,
process.env.PAYGATE_WEBHOOK_SECRET
)
} catch (err) {
// Log the error for debugging
console.error('Webhook signature verification failed:', err.message)
return res.status(400).send('Invalid signature')
}
// Process the event
handleWebhookEvent(event)
res.json({ received: true })
})Never skip signature verification in production. This prevents spoofed webhooks.
Test with a Real Transaction
Make a small real payment to verify everything works:
- Use your live API key
- Use a real phone number
- Process a small amount (e.g., GHS 1.00)
- Verify:
- Payment prompt is received
- Authorization works
- Webhook is delivered
- Funds appear in your dashboard
// Test with minimum amount
const payment = await paygate.payments.create({
amount: 100, // GHS 1.00 - minimum amount
currency: 'GHS',
payment_method: 'mobile_money',
phone: 'YOUR_REAL_PHONE',
description: 'Integration test'
})Set Up Monitoring
Monitor your integration for issues:
// Log all API errors
paygate.on('error', (error) => {
logger.error('PayGate API Error', {
type: error.type,
code: error.code,
message: error.message,
requestId: error.requestId
})
// Alert on critical errors
if (error.type === 'api_error') {
alertOps('PayGate API Error', error)
}
})
// Track webhook delivery
app.post('/webhooks', async (req, res) => {
const event = Webhook.constructEvent(...)
try {
await handleWebhookEvent(event)
logger.info('Webhook processed', { eventId: event.id, type: event.type })
} catch (error) {
logger.error('Webhook processing failed', {
eventId: event.id,
type: event.type,
error: error.message
})
}
res.json({ received: true })
})Security Best Practices
Protect API Keys
// DON'T: Hardcode keys
const paygate = new PayGate('sk_live_abc123...')
// DON'T: Use keys in client-side code
// <script>const key = 'sk_live_...'</script>
// DO: Use environment variables
const paygate = new PayGate(process.env.PAYGATE_SECRET_KEY)
// DO: Keep keys out of version control
// .gitignore
// .env
// .env.local
// .env.productionWebhook Security
// Always verify signatures
const event = Webhook.constructEvent(payload, signature, secret)
// Use HTTPS endpoints only
// PayGate won't deliver to HTTP in live mode
// Return 200 quickly
app.post('/webhooks', (req, res) => {
res.json({ received: true }) // Acknowledge immediately
processEventAsync(event) // Process in background
})Data Security
// Don't log sensitive data
console.log(payment) // DON'T log full payment objects
console.log({
id: payment.id,
status: payment.status,
amount: payment.amount
}) // DO: log only what you need
// Mask phone numbers in logs
const maskedPhone = phone.replace(/(\d{3})\d{4}(\d{3})/, '$1****$2')Error Handling
Handle All Error Types
try {
const payment = await paygate.payments.create(params)
} catch (error) {
if (error instanceof PayGateError) {
switch (error.type) {
case 'authentication_error':
// Check API key
logger.error('Authentication failed')
throw new Error('Payment service configuration error')
case 'invalid_request_error':
// Validation failed
throw new Error(getUserFriendlyMessage(error.code))
case 'payment_error':
// Payment-specific error
throw new Error(getPaymentErrorMessage(error.code))
case 'rate_limit_error':
// Too many requests
await sleep(60000)
return retry()
case 'api_error':
// Server error
logger.error('PayGate server error', { error })
throw new Error('Payment service temporarily unavailable')
}
}
// Network or unknown error
logger.error('Unknown payment error', { error })
throw new Error('Unable to process payment. Please try again.')
}User-Friendly Error Messages
const errorMessages = {
// Payment errors
'insufficient_funds': 'Your mobile money balance is too low. Please top up and try again.',
'phone_unreachable': 'We couldn\'t reach your phone. Make sure it\'s on and has network.',
'timeout': 'The payment timed out. Please try again.',
'transaction_declined': 'The payment was declined. Please check your PIN and try again.',
'daily_limit_exceeded': 'You\'ve reached your daily limit. Try again tomorrow.',
// Validation errors
'invalid_phone': 'Please enter a valid Ghana phone number.',
'amount_too_small': 'The minimum payment amount is GHS 1.00.',
'amount_too_large': 'The amount exceeds the maximum allowed.',
// Generic
'default': 'Something went wrong. Please try again or contact support.'
}
function getUserFriendlyMessage(code) {
return errorMessages[code] || errorMessages.default
}Monitoring & Alerts
What to Monitor
| Metric | Alert Threshold |
|---|---|
| Payment success rate | Below 95% |
| Average response time | Above 5 seconds |
| Webhook delivery rate | Below 99% |
| Error rate | Above 1% |
Example Monitoring Setup
import { metrics } from './monitoring'
// Track payment outcomes
async function createPayment(params) {
const start = Date.now()
try {
const payment = await paygate.payments.create(params)
metrics.increment('payments.created')
metrics.timing('payments.latency', Date.now() - start)
return payment
} catch (error) {
metrics.increment('payments.failed', { code: error.code })
throw error
}
}
// Track webhook processing
app.post('/webhooks', async (req, res) => {
metrics.increment('webhooks.received')
try {
const event = Webhook.constructEvent(...)
await processEvent(event)
metrics.increment('webhooks.processed')
} catch (error) {
metrics.increment('webhooks.failed')
}
res.json({ received: true })
})Post-Launch
First Week
- Monitor error rates closely
- Check webhook delivery in Dashboard
- Verify payouts are processing
- Review customer feedback
Ongoing
- Review API logs weekly
- Update SDKs regularly
- Monitor for new features
- Keep webhook endpoints healthy
Support
If you encounter issues:
- Check the API Status Page for outages
- Review your Dashboard for error details
- Search our Documentation for solutions
- Contact Support at support@paygate.com.gh
Congratulations! Once you've completed this checklist, you're ready to accept real payments. Welcome to PayGate!