Paystack Test Mode: Complete Guide
Paystack test mode is activated by using your test API keys (sk_test_... and pk_test_...) instead of live keys. In test mode: no real money moves, test cards are accepted, webhooks still fire to your registered URL, and all API endpoints work the same as live. To switch environments, swap the API key in your backend — no other code change needed.
Test Mode vs Live Mode: What Changes
| Feature | Test Mode | Live Mode |
|---|---|---|
| API key prefix | sk_test_ / pk_test_ | sk_live_ / pk_live_ |
| Real money | No | Yes |
| Test cards accepted | Yes | No |
| Real cards accepted | No | Yes |
| Webhooks fire | Yes (to registered URL) | Yes |
| Transaction data | Isolated from live | Isolated from test |
| Subaccounts / plans | Test-only, won't carry to live | Live-only |
| Settlements | No real settlement | Settles to your bank |
Receiving Test Webhooks Locally
Paystack webhooks fire to your registered URL — even in test mode. To receive them during local development, expose your local server with a tunneling tool:
# Using ngrok
ngrok http 3000
# Copy the HTTPS URL: https://abc123.ngrok.io
# Register it in Paystack dashboard:
# Settings → API Keys & Webhooks → Test Webhook URL
# Set to: https://abc123.ngrok.io/webhook
Alternatively, use the Paystack test dashboard's webhook simulator to send test events manually without a running server — useful for unit testing webhook handlers.
Switching from Test to Live
When you are ready to go live:
- Replace
sk_test_...withsk_live_...in your backend environment variables - Replace
pk_test_...withpk_live_...in your frontend configuration - Update your webhook URL in the Paystack dashboard to your production URL (Settings → Live webhook URL)
- Re-create any subaccounts, plans, or split codes you created in test mode — they do not carry over
- Test one small live transaction manually before announcing go-live
Common mistake: updating only the backend key. If your frontend still sends pk_test_... while the backend uses sk_live_..., transactions will be created in test mode and verification against the live API will fail.
Learn More
This guide is part of the Paystack testing guide.
Key Takeaways
- ✓Test mode is controlled by which API key you use — sk_test_... means test mode, sk_live_... means live mode.
- ✓Test transactions, subaccounts, plans, and customers are separate from live — they do not carry over when you go live.
- ✓Webhooks fire in test mode to your registered webhook URL — your local server needs to be publicly accessible (use ngrok or similar).
- ✓The Paystack dashboard has a separate transaction history for test vs live — toggle the environment switcher in the dashboard.
- ✓Never use a live secret key in a development or staging environment — accidental live charges happen this way.
- ✓When going live, you must switch both the secret key (backend) and public key (frontend) — missing either causes mixed-mode errors.
Frequently Asked Questions
- Can I use the same webhook URL for test and live mode?
- Paystack lets you register separate webhook URLs for test and live mode. Use different URLs — point test webhooks at your staging server and live webhooks at your production server. This prevents test events from being processed by your production system.
- Do test transactions count toward my Paystack transaction limits?
- No. Test transactions are completely separate from live transactions and do not count toward any live usage limits, fee calculations, or settlement totals. Test as much as you need without affecting your live account.
- Why do I see "Invalid key" errors after switching to live mode?
- Usually caused by using a test public key with a live secret key or vice versa. Both frontend (public key) and backend (secret key) must use the same mode. Also check that environment variables were actually reloaded — some frameworks cache env vars at startup.
- How do I test recurring subscriptions in test mode?
- Paystack test mode simulates subscription billing — you can create plans, subscribe customers with test cards, and receive subscription.create, invoice.update, and charge.success events. Billing intervals are not compressed in test mode though — you cannot fast-forward a monthly subscription to see the second charge without using the webhook simulator.
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