Skip to main content

Authentication Overview

JPay Africa API supports multiple authentication methods to suit different use cases:

Authentication Methods​

The recommended method for third-party applications and integrations.

Use Case: Server-to-server API calls from your backend application

How It Works:

  1. Send your App Key and App Secret to obtain JWT tokens
  2. Use the access token to make API requests
  3. Refresh your access token when it expires

Advantages:

  • Secure and stateless
  • JWT-based with expiration
  • Supports refresh tokens
  • Ideal for automation and server-side applications

Learn more: App Token Authentication

2. Manual Token Refresh​

Manually refresh your access token when needed.

Use Case: Handle token expiration in your application

How It Works:

  1. Monitor access token expiration time
  2. Send refresh token to /auth/refresh endpoint
  3. Receive new access and refresh tokens
  4. Update your stored tokens

Advantages:

  • Fine-grained control over token refresh
  • Proactive token management
  • Handles long-running processes

Learn more: Token Refresh

Token Lifecycle​

Access Tokens​

  • Expiration: 15 minutes
  • Use: Included in Authorization header for API requests
  • Format: Bearer token in JWT format

Refresh Tokens​

  • Expiration: 7 days
  • Use: Obtain new access tokens
  • Format: JWT token

Token Refresh Flow​

When your access token expires:

1. Send refresh token to /auth/refresh endpoint
2. Receive new access and refresh tokens
3. Update your stored tokens
4. Continue making API requests

Using Tokens​

Setting Up Authorization Header​

All API requests must include the access token in the Authorization header:

Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...

Example Request​

curl -X GET https://sandbox.api.jpay.africa/api/v1/collections/checkouts \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json"

Security Best Practices​

For App Keys and Secrets​

  • 🔐 Store credentials in environment variables, never in code
  • 🔐 Never expose App Secret in client-side applications
  • 🔐 Regenerate credentials if compromised
  • 🔐 Use HTTPS for all API communication
  • 🔐 Implement credential rotation periodically
  • 🔐 Configure IP whitelisting for production apps to restrict access to known servers

For Access Tokens​

  • 🔐 Store securely in your backend
  • 🔐 Don't log or expose tokens in error messages
  • 🔐 Include in Authorization header for all requests
  • 🔐 Handle token expiration gracefully
  • 🔐 Refresh tokens before expiration when possible

For Webhook Security​

  • ✅ Validate webhook signatures
  • ✅ Verify HTTPS certificates
  • ✅ Implement webhook secret validation
  • ✅ Retry failed webhooks

Token Expiration Handling​

Automatic Refresh​

Implement automatic token refresh in your application:

import requests
from datetime import datetime, timedelta

class JPayClient:
def __init__(self, app_key, app_secret):
self.app_key = app_key
self.app_secret = app_secret
self.access_token = None
self.refresh_token = None
self.expires_at = None

def get_tokens(self):
response = requests.post(
'https://sandbox.api.jpay.africa/api/v1/auth/app/token',
json={
'app_key': self.app_key,
'app_secret': self.app_secret
}
)
data = response.json()
self.access_token = data['access']
self.refresh_token = data['refresh']
self.expires_at = datetime.now() + timedelta(minutes=14)

def refresh_access_token(self):
response = requests.post(
'https://sandbox.api.jpay.africa/api/v1/auth/refresh',
json={'refresh': self.refresh_token}
)
data = response.json()
self.access_token = data['access']
self.expires_at = datetime.now() + timedelta(minutes=14)

def ensure_valid_token(self):
if not self.access_token:
self.get_tokens()
elif datetime.now() >= self.expires_at:
self.refresh_access_token()

def make_request(self, method, endpoint, **kwargs):
self.ensure_valid_token()
headers = {'Authorization': f'Bearer {self.access_token}'}
headers.update(kwargs.get('headers', {}))
kwargs['headers'] = headers
return requests.request(method, f'https://sandbox.api.jpay.africa/api/v1{endpoint}', **kwargs)

Common Authentication Issues​

401 Unauthorized​

Causes:

  • Invalid or expired token
  • Incorrect App Key/Secret
  • Malformed Authorization header

Solution:

# Get a new token
curl -X POST https://sandbox.api.jpay.africa/api/v1/auth/app/token \
-H "Content-Type: application/json" \
-d '{
"app_key": "your_app_key",
"app_secret": "your_app_secret"
}'

403 Forbidden​

Causes:

  • Merchant profile not approved
  • App doesn't have required product
  • Account is suspended
  • IP address not whitelisted (when IP restrictions are configured)

Solution:

  • Contact support or check your merchant dashboard
  • If using IP whitelisting, add your server's IP address to the allowed list in app settings

400 Bad Request​

Causes:

  • Malformed credentials
  • Missing required fields

Solution: Verify your request format and credentials

Next Steps​