API Keys
Generate, manage, and secure your PayNexus API keys. Learn the difference between public and secret keys, their scopes, and how they're tied to your payment accounts.
Overview
Every PayNexus account uses a pair of API keys for authentication. Keys are generated per payment account, so you can operate multiple businesses under one login with isolated credentials.
Public Key
Used for read-only operations only. Enforced as read-only at the middleware level. Safe to expose in client-side code (frontend, mobile apps). Cannot initiate payments or perform write operations.
Secret Key
Used for write operations — initiate STK Push payments, create payment links, manage invoices, and configure webhooks. Must be kept server-side only. Never expose in client-side code or version control.
Getting Your API Keys
Follow these steps to generate your API keys after creating a PayNexus account:
Register an Account
Sign up at paynexus.co.ke/register with your email and a secure password. Verify your email to activate your account.
Choose a Subscription Plan
Select the plan that fits your volume. The Developer plan is free and includes API access, webhooks, and payment links. No setup or monthly fees.
Add a Business
Navigate to Dashboard → Businesses and register your business details. You'll need your business name, registration number (optional), and contact information.
Add a Payment Account
Link your M-Pesa Till or Paybill number under Dashboard → Payment Accounts. Each payment account gets its own set of API keys. Payments are routed directly to the linked account.
Get Your API Keys
Once your payment account is verified, your API keys are generated automatically. Copy them from the dashboard. The public key starts with pk_ and the secret key starts with sk_.
API Key Structure
Each API key is a string prefixed to indicate its environment and type:
Public Key : pk_a1b2c3d4e5f6g7h8i9j0
Secret Key : sk_4eC39HqLyjWDarjtT1zdp7dc
Sandbox keys are used for testing and do not move real money. Calls are simulated.
Public Key : pk_z9y8x7w6v5u4t3s2r1q0
Secret Key : sk_8fG7hK2LmN3pQ4rS5tU6vW7xY8z
Live keys process real M-Pesa transactions. Only issued after business verification is complete.
Key Types & Capabilities
Understanding the difference between key types ensures you use them in the right context:
| Feature | Public Key (pk_) |
Secret Key (sk_) |
|---|---|---|
| Scope | Read-only | Read & Write |
| STK Push | — | ✓ Initiate payments |
| View Transactions | ✓ | ✓ |
| Create Payment Links | — | ✓ |
| Webhooks | — | ✓ Manage |
| Client-Side Safe | ✓ | ✗ Never expose |
| Middleware Enforcement | ✓ Blocked | — |
Payment Account Linking
Each API key is tied to a specific payment account. This ensures that every transaction is routed to the correct merchant.
Why Keys Are Account-Scoped
If you operate multiple businesses or manage clients' payments, each payment account (Till or Paybill) gets its own dedicated keypair. This prevents payment misrouting and simplifies reconciliation per account.
{
"payment_account_id": "pa_8fG7hK2L",
"business_name": "Acme Shop",
"till_number": "123456",
"public_key": "pk_a1b2...",
"secret_key": "sk_4eC3...",
"environment": "sandbox"
}
Usage Examples
Client-Side (Public Key Only)
Use the public key when you need to read data from the browser or mobile app:
// Reading transaction status from frontend
const response = await fetch('https://paynexus.co.ke/api/payments/PNXABC123', {
headers: {
'X-API-Key': 'pk_a1b2c3d4e5f6g7h8i9j0'
}
});
const data = await response.json();
console.log(data.status); // "completed"
The middleware automatically rejects any write attempts (STK Push, webhook creation, etc.) made with a public key. You'll receive a 403 Forbidden response.
Server-Side (Secret Key Required)
All write operations and sensitive reads must use the secret key from your backend:
// Server-side payment initiation
const response = await fetch('https://paynexus.co.ke/api/mpesa/payment/initiate', {
method: 'POST',
headers: {
'X-API-Key': 'sk_4eC39HqLyjWDarjtT1zdp7dc',
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: 100,
phone: '0746990866',
description: 'Order #12345'
})
});
const payment = await response.json();
console.log(payment.data.reference);
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => 'https://paynexus.co.ke/api/mpesa/payment/initiate',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'X-API-Key: sk_4eC39HqLyjWDarjtT1zdp7dc',
'Content-Type: application/json'
],
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode([
'amount' => 100,
'phone' => '0746990866',
'description' => 'Order #12345'
])
]);
$response = curl_exec($ch);
$payment = json_decode($response, true);
echo $payment['success'] ? $payment['data']['reference'] : 'Error: ' . $payment['error'];
import requests
response = requests.post(
'https://paynexus.co.ke/api/mpesa/payment/initiate',
headers={
'X-API-Key': 'sk_4eC39HqLyjWDarjtT1zdp7dc',
'Content-Type': 'application/json'
},
json={
'amount': 100,
'phone': '0746990866',
'description': 'Order #12345'
}
)
payment = response.json()
print(payment['data']['reference'])
Security Best Practices
Follow these guidelines to keep your API credentials and payment data secure:
Never commit keys to version control
Store secret keys in environment variables or a secrets manager. Use .env files that are gitignored.
Use separate keys for each environment
Test with sb_... sandbox keys and live with sk_... keys. Never use live keys in development.
Rotate keys periodically
Regenerate your secret key from the dashboard if you suspect a leak. Old keys can be revoked instantly.
Validate webhook signatures
Always verify the X-PayNexus-Signature header on incoming webhooks to confirm authenticity.
If your sk_ key is exposed, immediately regenerate it from the dashboard. Exposed secret keys can be used to initiate unauthorized payments and access sensitive transaction data.