Staging Environments and Separate Paystack Accounts
Use Paystack test mode for staging — your test API keys (sk_test_...) are free, unlimited, and fully isolated from live transactions. Configure your staging deployment with test API keys in environment variables. Register a separate webhook URL pointing at your staging server in the Paystack dashboard. Keep staging and production subaccounts, plans, and split codes completely separate — they are not shared between test and live modes.
Environment Configuration for Staging
# .env.staging — never commit this
PAYSTACK_SECRET_KEY=sk_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
PAYSTACK_PUBLIC_KEY=pk_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
NODE_ENV=staging
DATABASE_URL=postgresql://user:pass@staging-db:5432/myapp_staging
# .env.production — never commit this
PAYSTACK_SECRET_KEY=sk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
PAYSTACK_PUBLIC_KEY=pk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
NODE_ENV=production
DATABASE_URL=postgresql://user:pass@prod-db:5432/myapp
In your code, validate the environment at startup:
// startup validation
var secretKey = process.env.PAYSTACK_SECRET_KEY;
if (!secretKey) throw new Error('PAYSTACK_SECRET_KEY is not set');
if (process.env.NODE_ENV === 'production' && !secretKey.startsWith('sk_live_')) {
throw new Error('Production environment is using a test key — deployment blocked');
}
if (process.env.NODE_ENV === 'staging' && secretKey.startsWith('sk_live_')) {
throw new Error('Staging environment is using a live key — configuration error');
}
Staging Webhook Configuration
In the Paystack dashboard:
- Go to Settings → API Keys & Webhooks
- In Test mode, set Test Webhook URL to your staging webhook endpoint:
https://staging.yourapp.com/webhook/paystack - In Live mode, set Live Webhook URL to your production webhook:
https://yourapp.com/webhook/paystack
Use the same webhook handler code for both — the validation logic (HMAC check) and event processing are identical. The only difference is which secret key is used for the HMAC check (test key in staging, live key in production).
For local development where your staging URL is not publicly accessible, use ngrok:
ngrok http 3000
# Set the ngrok URL as temporary Test Webhook URL in Paystack dashboard
# Update it each time ngrok restarts (random URL)
Learn More
This guide is part of the Paystack testing guide.
Key Takeaways
- ✓Paystack test mode is your staging environment — no separate Paystack account needed unless you want full team isolation.
- ✓Register a separate webhook URL for test mode in the Paystack dashboard: Settings → API Keys & Webhooks → Test Webhook URL.
- ✓Store environment variables separately: .env.production (live keys) vs .env.staging (test keys) — never mix them.
- ✓Subaccounts, plans, and customers created in test mode are invisible in live mode and vice versa — recreate them in each mode.
- ✓When your staging environment receives a webhook, verify the x-paystack-signature matches your test secret key — use the same validation code as production.
- ✓Protect staging with HTTP basic auth to prevent public access and accidental test transactions from real users.
Frequently Asked Questions
- Do I need a separate Paystack account for staging?
- No — Paystack test mode on your existing account is sufficient for staging. Test and live are fully isolated within the same Paystack account. You would only need a separate Paystack account if you wanted completely separate dashboard access control (e.g., staging team should never see live transactions at all).
- Can I accidentally send real money in staging?
- No — as long as your staging environment uses sk_test_ and pk_test_ keys. Test keys can only process test cards. Real card numbers will be rejected. The guard at startup (checking key prefix) provides an extra layer of protection.
- How do I test webhooks in staging if my server is on a private network?
- Use a tunneling tool: ngrok (free tier works), Cloudflare Tunnel, or localtunnel. These expose your local server over a public HTTPS URL that Paystack can reach. For permanent staging environments (e.g., a Vercel preview deployment), register that deployment URL directly in the Paystack dashboard.
- Should staging use a copy of the production database or a separate database?
- Always use a completely separate staging database — never connect staging to production data. Staging payment tests write to the database; if that database were production, test records would mix with real customer records. The staging database can be seeded with anonymised production data snapshots, but it must remain isolated.
Ready to build real-world apps?
Join the McTaba Labs full-stack marathon (4 months full-time · 6 months part-time). Learn M-Pesa, USSD, and WhatsApp engineering while shipping 8 production apps.
Apply to the McTaba Marathon