Create Payment Intent
Creates a new payment intent and returns a redirect URL to the hosted checkout page.
Endpoint
POST /api/intents
Authentication: Required (API Key)
Description
This endpoint is used to create a payment intent for processing payments through the hosted checkout page. A payment intent serves as the foundation for a transaction, specifying details such as the amount and currency required for payment processing.
Hosted Checkout Flow
Once a payment intent is created, you receive a redirect_url to the hosted checkout page. This URL can be used to redirect users to the checkout page, enabling customers to complete the payment process. Our checkout page manages different multi-step flows and 3DS redirection flows, ensuring a smooth user experience.
Request
Headers
| Header | Type | Required | Description |
|---|---|---|---|
Authorization | string | Yes | Bearer token with your API key |
Content-Type | string | Yes | Must be application/json |
Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
amount | integer | Yes | Amount in minor units (cents). E.g., 1000 = $10.00 |
currency | string | Yes | ISO 4217 currency code (e.g., USD, ZAR, EUR) |
reference_id | string | Yes | Your unique transaction reference |
purchaser_id | string (min 3 chars) | Yes | Your unique customer identifier |
return_url | string (HTTPS URI) | Yes | URL to redirect customer after payment |
allow_remember_credentials | boolean | Yes | Whether payment credentials can be saved |
request_unscheduled_mit | boolean | No | Request permission for future auto-payments (default: false) |
require_unscheduled_mit | boolean | No | Require MIT capability (default: false) |
capture_mode | string | No | immediate or prefer_delay (default: immediate) |
purchaser_info | object | No | Customer details (email, phone, country, locale) |
payment_method_filter | object | No | Filter which payment methods to show |
split | object | No | Payment split configuration for multiple beneficiaries |
future_payments | object | No | Configuration for future recurring payments, e.g. mandate instalments. When provided, amount is the initial (pro-rata) payment and future_payments defines the recurring schedule. Required for DebiCheck mandate signing. |
Purchaser Info Object
| Field | Type | Required | Description |
|---|---|---|---|
email | string | No | Customer email address |
phone | string | No | Customer phone number |
country | string | No | ISO country code (e.g., ZA) |
locale | string | No | Locale code (e.g., en-ZA) |
Payment Method Filter Object
| Field | Type | Required | Description |
|---|---|---|---|
filter_type | string | Yes | allow (whitelist) or block (blacklist) |
payment_methods | array | Yes | List of payment method codes |
Split Object
| Field | Type | Required | Description |
|---|---|---|---|
split_type | string | Yes | Currently only AMOUNT supported |
splits | array (min 2) | Yes | List of beneficiary splits |
description | string | No | Optional split description |
See Split Payouts Guide for details.
Future Payments Object
| Field | Type | Required | Description |
|---|---|---|---|
type | string | No | Type of future payments. Only "instalment" is supported. Defaults to "instalment". |
frequency | string | Yes | How often payments should occur. One of: "weekly", "monthly". |
count | integer | Yes | Number of future payments, excluding the initial payment. Minimum: 1. |
amount | integer | Yes | Default amount per future payment in minor units (e.g. cents). |
currency | string | Yes | ISO 4217 currency code for future payments (e.g. "ZAR"). |
constraints | object | Yes | Scheduling and limit constraints. See below. |
Future Payment Constraints Object
| Field | Type | Required | Description |
|---|---|---|---|
billing_start_date | string | Yes | Date (YYYY-MM-DD) from which billing starts. Must be at least 5 days from today. Actual collection happens on collection_day. If your desired collection day has already passed in the current cycle, move the date to the next cycle. |
collection_day | integer | Yes | Day on which payments are collected. For "weekly": 1–7 (1 = Monday). For "monthly": 1–31. Use 31 to target the last day of the month. |
max_amount | integer | No | Maximum amount per individual future payment in minor units. Must be at least future_payments.amount to allow variable collection amounts. |
See Mandates for how to manage a mandate after it has been signed.
return_url must be a secure HTTPS URL and publicly accessible (not localhost for production).- 0 decimals: JPY (Japanese Yen), UGX (Ugandan Shilling)
- 3 decimals: OMR (Omani Rial), KWD (Kuwaiti Dinar), BHD (Bahraini Dinar), JOD (Jordanian Dinar)
Example Request
curl -X POST https://api.njiapay.com/api/intents \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"amount": 10000,
"currency": "ZAR",
"reference_id": "order_12345",
"purchaser_id": "customer_abc",
"return_url": "https://yoursite.com/payment/callback",
"allow_remember_credentials": true,
"request_unscheduled_mit": false,
"purchaser_info": {
"email": "customer@example.com",
"phone": "+27123456789",
"country": "ZA",
"locale": "en-ZA"
}
}'
const response = await fetch("https://api.njiapay.com/api/intents", {
method: "POST",
headers: {
Authorization: `Bearer ${YOUR_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
amount: 10000,
currency: "ZAR",
reference_id: "order_12345",
purchaser_id: "customer_abc",
return_url: "https://yoursite.com/payment/callback",
allow_remember_credentials: true,
purchaser_info: {
email: "customer@example.com",
phone: "+27123456789",
country: "ZA",
},
}),
});
const data = await response.json();
console.log("Redirect URL:", data.redirect_url);
import requests
response = requests.post(
'https://api.njiapay.com/api/intents',
headers={
'Authorization': f'Bearer {YOUR_API_KEY}',
'Content-Type': 'application/json'
},
json={
'amount': 10000,
'currency': 'ZAR',
'reference_id': 'order_12345',
'purchaser_id': 'customer_abc',
'return_url': 'https://yoursite.com/payment/callback',
'allow_remember_credentials': True,
'purchaser_info': {
'email': 'customer@example.com',
'phone': '+27123456789',
'country': 'ZA'
}
}
)
data = response.json()
print('Redirect URL:', data['redirect_url'])
Response
Success Response (201 Created)
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"token": "eyJ0eXAiOiJKV1QiLCJhbGc...",
"redirect_url": "https://pay.njiapay.com/pay/550e8400-e29b-41d4-a716-446655440000?token=eyJ0eXAi..."
}
| Field | Type | Description |
|---|---|---|
id | string (UUID) | Unique payment intent identifier |
token | string | Intent authentication token (for iauth parameter) |
redirect_url | string | URL to redirect customer to checkout page |
Error Responses
401 Unauthorized
{
"detail": "Invalid or missing API key"
}
Causes:
- Missing Authorization header
- Invalid API key
- Using sandbox key with production URL (or vice versa)
422 Validation Error
{
"detail": [
{
"loc": ["body", "amount"],
"msg": "ensure this value is greater than or equal to 0",
"type": "value_error"
}
]
}
Common validation errors:
- Negative amount
- Invalid currency code
- Missing required fields
- Invalid return_url format
- Split amounts don't sum to total amount
Important Notes
Allow Remember Credentials
The allow_remember_credentials parameter must be set to true if you plan to:
- Allow 1-click payments
- Enable unscheduled Merchant-Initiated Transactions (MIT)
- Use auto-payment attempts
If you intend to use auto-payments, ensure the original payment intent is successfully completed and meets all prerequisites.
See Auto Payments Guide for details.
Split Payouts
If you want to split the payment between multiple parties, use the split field:
- Minimum 2 beneficiaries required
- Sum of splits must equal total amount
- No duplicate beneficiaries
- All beneficiaries must have same currency as intent
Before using splits, create beneficiaries using the /api/merchants/{merchant_id}/beneficiaries endpoint.
See Split Payouts Guide for complete details.
Next Steps
After creating a payment intent:
- Redirect the customer to the
redirect_url - Set up webhook listener to receive payment status updates
- Handle return_url callback when customer returns to your site