Payxit Developer Documentation
Use Payxit to manage Nigerian payment gateways through a single API.
1) Overview
Payxit lets merchants manage multiple Nigerian payment gateways with a single API. Merchants generate Payxit API keys in the dashboard, then use those keys to create payment sessions for their customers. Customers are redirected to a Payxit-hosted public payment page and then routed to the selected gateway’s checkout flow (Flutterwave, Paystack, Opay, PalmPay, KongaPay, Moniepoint).
2) Base URLs
- Production API:
https://api.payxit.co/v1 - Public pay page:
https://payxit.co/pay/{token}
3) Authentication (Public Developer Access)
Payxit payment processing endpoints require a Payxit API public key in the request header.
- Header:
x-payxit-key - Alternate:
x-api-key
POST /v1/payxit/public/payments HTTP/1.1
Host: api.payxit.co
Content-Type: application/json
x-payxit-key: pk_live_xxxxxxxxxxxxxxxxx
4) Payment Processing Flow
- Merchant creates a payment session using Payxit’s public API.
- Payxit returns a token and a public payment page redirect URL.
- Merchant redirects the customer to the Payxit payment page.
- Customer clicks “Proceed with Payment” to open gateway checkout.
- Gateway confirms payment via webhook callbacks.
- Payxit records the transaction and updates status.
5) Public Developer Endpoints
5.1 Health Check Public
GET /health
{ "status": "ok" }
5.2 List Supported Gateways Public
GET /v1/payxit/public/gateways
{ "gateways": [] }
5.3 Pricing Public
GET /v1/payxit/public/pricing
{ "pricing": [] }
5.4 Create Payment Session Auth
POST /v1/payxit/public/payments
Headers: x-payxit-key
{
"name": "Ada Nwosu",
"email": "ada@example.com",
"phone": "+2348012345678",
"amount": 25000,
"currency": "NGN"
}
{
"token": "ab12cd34ef56...",
"redirectUrl": "https://payxit.co/pay/ab12cd34ef56...",
"session": {
"id": "uuid",
"status": "created",
"amount": 25000,
"currency": "NGN",
"customerName": "Ada Nwosu",
"customerEmail": "ada@example.com",
"customerPhone": "+2348012345678",
"gateway": "flutterwave"
}
}
5.5 Get Payment Session Public
GET /v1/payxit/public/payments/:token
{
"session": {
"id": "uuid",
"status": "created",
"amount": 25000,
"currency": "NGN",
"customerName": "Ada Nwosu",
"customerEmail": "ada@example.com",
"customerPhone": "+2348012345678",
"gateway": "flutterwave",
"checkoutUrl": null
}
}
5.6 Initiate Payment Session Public
POST /v1/payxit/public/payments/:token/initiate
This is invoked by the Payxit payment page when a customer proceeds to the gateway checkout.
{
"session": {
"id": "uuid",
"status": "initiated",
"gateway": "flutterwave",
"checkoutUrl": "https://gateway.example/checkout/xyz"
}
}
5.7 Webhooks Gateway
POST /v1/webhooks/:gateway
Raw body is required. Payxit validates signatures and updates transactions based on gateway payloads.
6) Error Responses
{ "message": "Description of the error." }
- 400 — invalid or missing fields
- 401 — invalid API key
- 404 — payment session not found
- 409 — payment already initiated
- 502 — gateway checkout URL not returned
7) Example Integration
curl -X POST "https://api.payxit.co/v1/payxit/public/payments" \
-H "Content-Type: application/json" \
-H "x-payxit-key: pk_live_xxxxxxxxxxxxx" \
-d '{
"name": "Ada Nwosu",
"email": "ada@example.com",
"phone": "+2348012345678",
"amount": 25000,
"currency": "NGN"
}'
Redirect the customer to the returned redirectUrl, which
will look like:
https://payxit.co/pay/{token}
8) React Checkout (Payment.jsx)
Use the component below to collect customer details and redirect to
the Payxit checkout page. It matches docs/Payment.jsx.
import React, { useState } from 'react';
import axios from 'axios';
const Payment = () => {
const [formData, setFormData] = useState({
name: '',
email: '',
phone: '',
amount: '',
currency: 'NGN'
});
const [apiKey, setApiKey] = useState('');
const [loading, setLoading] = useState(false);
const [error, setError] = useState('');
const handleChange = (e) => {
const { name, value } = e.target;
setFormData((prev) => ({ ...prev, [name]: value }));
};
const handleApiKeyChange = (e) => {
setApiKey(e.target.value);
};
const handleSubmit = async (e) => {
e.preventDefault();
if (!apiKey) {
setError('Please enter your Payxit API key.');
return;
}
setLoading(true);
setError('');
try {
const response = await axios.post('/v1/payxit/public/payments', formData, {
headers: {
'x-payxit-key': apiKey,
'Content-Type': 'application/json'
}
});
const { redirectUrl } = response.data;
window.location.href = redirectUrl;
} catch (err) {
setError(err.response?.data?.message || 'Failed to create payment session. Please try again.');
console.error(err);
} finally {
setLoading(false);
}
};
return (
<div className="max-w-md mx-auto mt-10 p-6 bg-white rounded-lg shadow-md">
<h2 className="text-2xl font-bold mb-6 text-center">Payment Form</h2>
{error && <p className="text-red-500 mb-4">{error}</p>}
<form onSubmit={handleSubmit}>
<div className="mb-4">
<label className="block text-gray-700">Payxit API Key (pk_live_ or pk_sandbox_)</label>
<input
type="text"
value={apiKey}
onChange={handleApiKeyChange}
required
placeholder="Enter your Payxit public key"
className="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
<div className="mb-4">
<label className="block text-gray-700">Name</label>
<input
type="text"
name="name"
value={formData.name}
onChange={handleChange}
required
className="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
<div className="mb-4">
<label className="block text-gray-700">Email</label>
<input
type="email"
name="email"
value={formData.email}
onChange={handleChange}
required
className="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
<div className="mb-4">
<label className="block text-gray-700">Phone (e.g., +2348012345678)</label>
<input
type="tel"
name="phone"
value={formData.phone}
onChange={handleChange}
className="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
<div className="mb-4">
<label className="block text-gray-700">Amount</label>
<input
type="number"
name="amount"
value={formData.amount}
onChange={handleChange}
required
min="0"
step="0.01"
className="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
/>
</div>
<div className="mb-4">
<label className="block text-gray-700">Currency</label>
<select
name="currency"
value={formData.currency}
onChange={handleChange}
className="w-full px-3 py-2 border rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value="NGN">NGN</option>
<option value="USD">USD</option>
<option value="EUR">EUR</option>
<option value="GBP">GBP</option>
</select>
</div>
<button
type="submit"
disabled={loading}
className="w-full bg-blue-500 text-white py-2 rounded-lg hover:bg-blue-600 disabled:opacity-50"
>
{loading ? 'Processing...' : 'Submit Payment'}
</button>
</form>
</div>
);
};
export default Payment;
9) Vanilla JS Checkout (HTML + JS)
If you are not using React, use this HTML form with a script that calls the Payxit public API and redirects to the checkout URL.
<form id="payxit-form">
<label>Payxit API Key (pk_live_ or pk_sandbox_)</label>
<input type="text" id="apiKey" required />
<label>Name</label>
<input type="text" id="name" required />
<label>Email</label>
<input type="email" id="email" required />
<label>Phone (e.g., +2348012345678)</label>
<input type="tel" id="phone" />
<label>Amount</label>
<input type="number" id="amount" min="0" step="0.01" required />
<label>Currency</label>
<select id="currency">
<option value="NGN">NGN</option>
<option value="USD">USD</option>
<option value="EUR">EUR</option>
<option value="GBP">GBP</option>
</select>
<button type="submit">Submit Payment</button>
</form>
<script>
const form = document.getElementById('payxit-form');
form.addEventListener('submit', async (event) => {
event.preventDefault();
const apiKey = document.getElementById('apiKey').value.trim();
if (!apiKey) {
alert('Please enter your Payxit API key.');
return;
}
const payload = {
name: document.getElementById('name').value.trim(),
email: document.getElementById('email').value.trim(),
phone: document.getElementById('phone').value.trim(),
amount: Number(document.getElementById('amount').value),
currency: document.getElementById('currency').value
};
try {
const response = await fetch('/v1/payxit/public/payments', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-payxit-key': apiKey
},
body: JSON.stringify(payload)
});
if (!response.ok) {
const errorBody = await response.json();
throw new Error(errorBody.message || 'Failed to create payment session.');
}
const data = await response.json();
window.location.href = data.redirectUrl;
} catch (error) {
alert(error.message || 'Failed to create payment session.');
}
});
</script>
10) Security Notes
- Keep Payxit API keys secret.
- Use HTTPS in production.
- Rotate keys if exposed.
- Use gateway-specific webhook signatures.
11) Environment Notes
- Payxit supports Live and Sandbox environments.
- Keys and webhook URLs are managed per environment.
- Use the corresponding public key for each environment.