Authentication
Learn how to authenticate your API requests with SerixPay. We support two authentication methods: API Keys and OAuth 2.0 Client Credentials.
API Keys
Simple authentication using static API keys. Best for quick integration.
pk_live_* / pk_test_*OAuth 2.0 (Recommended)
Industry-standard OAuth 2.0 Client Credentials flow. Similar to Safaricom M-PESA API.
ck_live_* / ck_test_*OAuth 2.0 Client Credentials
The OAuth 2.0 Client Credentials flow is the recommended way to authenticate. It uses short-lived access tokens that expire after 1 hour, providing better security. This pattern is similar to how Safaricom's M-PESA API works.
Step 1: Get Consumer Credentials
Create an OAuth client from your dashboard to get your consumer_key and consumer_secret.
Consumer Keyck_test_DXatcpzyI4dM...Consumer Secretcs_TkdodC6iCjhg...Step 2: Generate Access Token
Exchange your consumer credentials for an access token. Create a Basic Auth header by Base64 encoding consumer_key:consumer_secret:
How Basic Auth Works
- Concatenate your consumer key and secret with a colon:
consumer_key:consumer_secret - Base64 encode the concatenated string
- Add the encoded string to the Authorization header:
Basic <encoded_string>
cURL
# Base64 encode consumer_key:consumer_secretCONSUMER_KEY="ck_test_DXatcpzyI4dM..."CONSUMER_SECRET="cs_TkdodC6iCjhg..."CREDENTIALS=$(echo -n "$CONSUMER_KEY:$CONSUMER_SECRET" | base64)# Request access tokencurl -X POST https://api.serixpay.com/api/v1/auth/token \ -H "Authorization: Basic $CREDENTIALS" \ -H "Content-Type: application/json" \ -d '{"grant_type": "client_credentials"}'Node.js
const consumerKey = 'ck_test_DXatcpzyI4dM...';const consumerSecret = 'cs_TkdodC6iCjhg...';// Create Base64 encoded credentialsconst credentials = Buffer.from(`${consumerKey}:${consumerSecret}`).toString('base64');const response = await fetch('https://api.serixpay.com/api/v1/auth/token', { method: 'POST', headers: { 'Authorization': `Basic ${credentials}`, 'Content-Type': 'application/json', }, body: JSON.stringify({ grant_type: 'client_credentials' }),});const { access_token, expires_in } = await response.json();console.log('Access Token:', access_token);console.log('Expires in:', expires_in, 'seconds');Python
import base64import requestsconsumer_key = 'ck_test_DXatcpzyI4dM...'consumer_secret = 'cs_TkdodC6iCjhg...'# Create Base64 encoded credentialscredentials = base64.b64encode(f'{consumer_key}:{consumer_secret}'.encode()).decode()response = requests.post( 'https://api.serixpay.com/api/v1/auth/token', headers={ 'Authorization': f'Basic {credentials}', 'Content-Type': 'application/json', }, json={'grant_type': 'client_credentials'})data = response.json()access_token = data['access_token']print(f'Access Token: {access_token}')Response:
{ "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "Bearer", "expires_in": 3600}Step 3: Use Access Token
Use the access token in the Authorization header for all API requests:
curl -X POST https://api.serixpay.com/api/v1/payments/charge \ -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." \ -H "Content-Type: application/json" \ -d '{ "amount": 100, "currency": "USD", "reference": "ORDER-001", "customer": { "email": "customer@example.com", "firstName": "John", "lastName": "Doe" }, "card": { "number": "4242424242424242", "expiry": "12/26", "cvv": "123" } }'Token Expiration
API Keys (Simple Method)
For simpler integrations, you can use static API keys directly in the Authorization header. You can create and manage API keys from your dashboard.
Header Format
Authorization: Bearer pk_live_your_api_key_hereTest Keys
pk_test_*- • Use for development and testing
- • No real payments are processed
- • Use sandbox phone numbers and test cards
- • Unlimited test transactions
Live Keys
pk_live_*- • Use for production only
- • Real payments are processed
- • Use real customer phone numbers
- • Standard transaction fees apply
Example Request
curl -X POST https://api.serixpay.com/api/v1/init-payment \ -H "Authorization: Bearer pk_test_abc123xyz" \ -H "Content-Type: application/json" \ -d '{ "phoneNumber": "254712345678", "amount": 100, "orderId": "ORDER-001" }'Security Best Practices
Never Expose API Keys
Don't: Client-side API calls
Never call the SerixPay API directly from browser JavaScript, mobile apps, or any client-side code.
Do: Server-side API calls
Make all API calls from your backend server where the API key can be stored securely as an environment variable.
Environment Variables
Store your credentials securely in environment variables:
# .env file (never commit this to git)# OAuth 2.0 Credentials (Recommended)SERIXPAY_CONSUMER_KEY=ck_test_your_consumer_keySERIXPAY_CONSUMER_SECRET=cs_your_consumer_secret# OR API Key (Simple method)SERIXPAY_API_KEY=pk_test_your_api_key_here# Webhook verificationSERIXPAY_WEBHOOK_SECRET=whsec_your_webhook_secretAccess in your code:
// OAuth credentialsconst consumerKey = process.env.SERIXPAY_CONSUMER_KEY;const consumerSecret = process.env.SERIXPAY_CONSUMER_SECRET;// OR API keyconst apiKey = process.env.SERIXPAY_API_KEY;Authentication Errors
Common authentication error responses:
{ "success": false, "error": "Invalid API key provided", "code": "INVALID_API_KEY"}{ "success": false, "error": "API key has been revoked", "code": "API_KEY_REVOKED"}Webhook Signature Verification
Verify webhook signatures to ensure requests come from SerixPay:
const crypto = require('crypto');function verifyWebhookSignature(payload, signature, secret) { const expectedSignature = crypto .createHmac('sha256', secret) .update(JSON.stringify(payload)) .digest('hex'); return crypto.timingSafeEqual( Buffer.from(signature), Buffer.from(expectedSignature) );}// In your webhook handlerapp.post('/webhook', (req, res) => { const signature = req.headers['x-serixpay-signature']; if (!verifyWebhookSignature(req.body, signature, process.env.WEBHOOK_SECRET)) { return res.status(401).json({ error: 'Invalid signature' }); } // Process webhook...});