On Vercel, add PAYSTACK_SECRET_KEY to environment variables in Project Settings and scope it to Production only. Use test keys for Preview and Development. On Railway, add variables in the service Settings tab. On Render, use the Environment section in your service dashboard. All three platforms encrypt variables at rest and inject them at runtime.
Storing Paystack keys correctly on your deployment platform is just as important as keeping them out of your source code. A key that is properly stored in a .env file locally can still be misconfigured on the platform, leading to test keys in production (payments silently fail) or live keys in preview environments (test clicks charge real money).
Each platform has its own variable scoping model, encryption behavior, and gotchas. This guide covers Vercel, Railway, and Render because they are the most commonly used platforms by developers building Paystack integrations in Africa.
For the fundamentals of environment variable management, see storing Paystack keys in environment variables properly.
Vercel is the most popular platform for Next.js deployments, and Next.js is one of the most common frameworks for Paystack integrations. Vercel has a powerful but sometimes confusing environment variable system.
| Variable Name | Value | Environments |
|---|---|---|
| PAYSTACK_SECRET_KEY | sk_live_xxxx | Production only |
| PAYSTACK_SECRET_KEY | sk_test_xxxx | Preview, Development |
| NEXT_PUBLIC_PAYSTACK_KEY | pk_live_xxxx | Production only |
| NEXT_PUBLIC_PAYSTACK_KEY | pk_test_xxxx | Preview, Development |
You can set the same variable name with different values for different environments. Vercel resolves the correct value based on which environment the deployment targets.
vercel dev locally, Vercel pulls the Development-scoped variables. Make sure Development uses test keys.After adding variables, trigger a new deployment and check your server logs. Add a temporary startup log (remove it after verification):
// pages/api/health.js (temporary, remove after verification)
module.exports = function handler(req, res) {
var keyPrefix = (process.env.PAYSTACK_SECRET_KEY || '').substring(0, 8);
console.log('Paystack key prefix: ' + keyPrefix);
res.json({ status: 'ok', keyPrefix: keyPrefix });
};
This logs only the prefix (sk_test_ or sk_live_), not the full key. Verify the prefix matches what you expect for each environment, then remove the endpoint.
Get weekly developer tips
Join 25,000+ developers. Practical guides, job tips, and new content — straight to your inbox.
No spam. Unsubscribe anytime.
Railway makes environment variable management straightforward. Variables are set per service and are available at runtime.
PAYSTACK_SECRET_KEY = sk_live_xxxxxxxxxxxxxxxxxxxx
PAYSTACK_PUBLIC_KEY = pk_live_xxxxxxxxxxxxxxxxxxxx
${{service.VARIABLE}} syntax. Useful if multiple services need the same Paystack keys.Because Railway does not have build-time variable embedding like Vercel, you need to pass the public key to the client through an API route or a server component:
// pages/api/config.js
module.exports = function handler(req, res) {
res.json({
paystackPublicKey: process.env.PAYSTACK_PUBLIC_KEY,
});
};
Or set the variable as a build argument in your Dockerfile or railway.toml so it is available during the Next.js build step.
Render provides a clean interface for managing environment variables per service.
PAYSTACK_SECRET_KEY = sk_live_xxxxxxxxxxxxxxxxxxxx
PAYSTACK_PUBLIC_KEY = pk_live_xxxxxxxxxxxxxxxxxxxx
If you deploy with Docker on Render, environment variables are injected at runtime, not during the build. Do not use ARG to pass Paystack keys during the build step, as build arguments can be cached in image layers.
# Dockerfile
# WRONG: build arg cached in image layer
ARG PAYSTACK_SECRET_KEY
# RIGHT: read from environment at runtime
# (just use process.env.PAYSTACK_SECRET_KEY in your code)
Many Paystack integrations involve multiple services: a web server, a webhook handler, a background worker, and maybe a cron job. Each service that interacts with the Paystack API needs the secret key.
The cleanest approach varies by platform:
Regardless of platform, keep the variable names consistent across all services. Use PAYSTACK_SECRET_KEY everywhere, not PAYSTACK_KEY in one service and PS_SECRET in another. Consistency prevents confusion during debugging and key rotation.
When you rotate Paystack keys (because of a leak, a team change, or a security policy), you need to update the keys on your deployment platform and redeploy.
The window between rotating the key on Paystack and deploying the new key is a period of downtime. Paystack invalidates the old key immediately upon rotation. Plan your rotation during low-traffic hours to minimize the impact. For zero-downtime strategies, see rotating Paystack secret keys without downtime.
Before going live with any platform, verify these items:
For the complete security guide, see Paystack security, keys and PCI compliance.
KES 2,999
The definitive guide to building payment systems with Paystack — from your first transaction to production-grade payment infrastructure across Africa. 9 modules, 47 lessons. Free preview available.
Start Paystack Course