Integrate PAYHIIVE using your token for checkout, webhooks, and payments. Get your token from Dashboard → Tokens.
Welcome to the PAYHIIVE API documentation. This guide will help you integrate PAYHIIVE payment gateway into your applications.
Important: Your token is only shown once when generated. Copy and store it securely. If you lose it, generate a new token from Dashboard → Tokens.
Note: Use a Sandbox token for testing and a Live token for production. Never expose your token in client-side code (browser, mobile apps). Always call the API from your backend server.
Before integrating, test your token using the test feature on the Tokens page or by making a test API call.
Integrate PAYHIIVE seamlessly with your application using our official SDKs and plugins. These tools are designed to make integration easier and faster.
We provide official libraries for Node.js, Python, and PHP. Install one of them, then run the command below in your terminal.
Click "Copy" next to the command, paste in your terminal, and press Enter. Click "View Docs" to see full documentation.
Official Node.js library for the PAYHIIVE API.
npm install payhiive-node
Official Python library for the PAYHIIVE API.
pip install payhiive-python
Official PHP library for the PAYHIIVE API.
composer require payhiive/payhiive-php
Official Node.js library for the PAYHIIVE API
npm install payhiive-node
const { Payhiive } = require('payhiive-node');
// Initialize the client with your token
const client = new Payhiive({ apiKey: 'your_token_here' });
// Create a payment intent (recommended)
const payment = await client.payments.create({
amount: 50000, // Amount in UGX
description: 'Order #12345',
callbackUrl: 'https://yoursite.com/webhooks/payhiive'
});
// Redirect customer to the checkout URL
console.log(payment.checkout_url);
payments.create()payments.retrieve(id)payments.list()payments.getStatus(id)paymentLinks.create()paymentLinks.createWithAmounts()paymentLinks.list()paymentLinks.delete(id)checkout.create()checkout.retrieve(id)checkout.isPaid(id)const link = await client.paymentLinks.create({
amount: 100000,
currency: 'UGX',
description: 'Membership Fee'
});
console.log(link.data.payment_link);
const session = await client.checkout.create({
amount: 75000,
currency: 'UGX',
successUrl: 'https://site.com/success',
cancelUrl: 'https://site.com/cancel'
});
MTN_MOMO_UGA
AIRTEL_OAPI_UGA
Download SDK
Get the complete package
Official Python library for the PAYHIIVE API
pip install payhiive-python
from payhiive import Payhiive
# Initialize the client with your token
client = Payhiive(api_key="your_token_here")
# Create a payment intent (recommended)
payment = client.payments.create(
amount=50000, # Amount in UGX
description="Order #12345",
callback_url="https://yoursite.com/webhooks/payhiive"
)
# Redirect customer to the checkout URL
print(payment["checkout_url"])
payments.create() - Create payment intentpayments.retrieve(id) - Get paymentpayments.list() - List paymentspayments.get_status(id) - Get statuspayment_links.create() - Create linkpayment_links.create_with_amounts() - Multi-amountpayment_links.list() - List linkspayment_links.delete(id) - Delete linkcheckout.create() - Create sessioncheckout.retrieve(id) - Get sessioncheckout.is_paid(id) - Check paidlink = client.payment_links.create(
amount=100000,
currency="UGX",
description="Membership Fee"
)
print(link["data"]["payment_link"])
session = client.checkout.create(
amount=75000,
currency="UGX",
success_url="https://site.com/success",
cancel_url="https://site.com/cancel"
)
MTN_MOMO_UGA
AIRTEL_OAPI_UGA
Download SDK
Get the complete package
Official PHP library for the PAYHIIVE API
composer require payhiive/payhiive-php
<?php
use Payhiive\Payhiive;
// Initialize the client with your token
$client = new Payhiive('your_token_here');
// Create a payment intent (recommended)
$payment = $client->payments->create(
50000, // Amount in UGX
'Order #12345',
'https://yoursite.com/webhooks/payhiive'
);
// Redirect customer to the checkout URL
header('Location: ' . $payment['checkout_url']);
$client->payments->create()$client->payments->retrieve($id)$client->payments->list()$client->payments->getStatus($id)$client->paymentLinks->create()$client->paymentLinks->createWithAmounts()$client->paymentLinks->list()$client->paymentLinks->delete($id)$client->checkout->create()$client->checkout->retrieve($id)$client->checkout->isPaid($id)$link = $client->paymentLinks->create([
'amount' => 100000,
'currency' => 'UGX',
'description' => 'Membership Fee'
]);
echo $link['data']['payment_link'];
$session = $client->checkout->create([
'amount' => 75000,
'currency' => 'UGX',
'success_url' => 'https://site.com/success',
'cancel_url' => 'https://site.com/cancel'
]);
MTN_MOMO_UGA
AIRTEL_OAPI_UGA
Download SDK
Get the complete package
Accept mobile money payments on your WordPress site with our official plugin.
All API requests require your token. Get it from Dashboard → Tokens. Your token starts with sk_ — it is the only key you need.
| Header | Description | Required |
|---|---|---|
Authorization |
Bearer sk_your_token — your token from Dashboard → Tokens. |
Required |
Content-Type |
Should be application/json |
Required |
Use your token in the Authorization header when making any API call:
curl -X POST https://payhiive.com/api/v1/payments \
-H "Authorization: Bearer sk_your_token" \
-H "Content-Type: application/json" \
-d '{
"amount": 10000,
"currency": "UGX",
"phone_number": "256700000000",
"provider": "MTN_MOMO_UGA",
"description": "Payment for order #123"
}'
Security: Never expose your token in client-side code. Keep it only on your server.
PAYHIIVE charges platform fees on transactions. Fees are added on top of the amount you want to collect, so you receive the exact amount you requested.
For transactions made through the API:
For transactions made through payment links:
If you want to collect 10,000 UGX via API:
If you want to collect 10,000 UGX via Payment Link:
For withdrawals/payouts made through the API:
If you withdraw 10,000 UGX:
Note: Fees are added on top of the transaction amount. If you want to collect 10,000 UGX, the customer will pay 10,000 UGX plus the platform fee, and you will receive the full 10,000 UGX in your account.
The base URL for all API requests:
https://payhiive.com/api/v1
Important: Always use HTTPS in production. Replace 127.0.0.1:8001 with your actual domain when going live.
Create a new payment transaction.
| Parameter | Type | Description | Required |
|---|---|---|---|
amount |
integer | Amount in UGX (e.g., 10000 = 10,000 UGX) | Required |
currency |
string | Currency code (UGX) | Required |
phone_number |
string | Customer mobile money phone number (e.g., 256700000000) | Required |
provider |
string | Mobile money provider: MTN_MOMO_UGA or AIRTEL_OAPI_UGA |
Required |
description |
string | Payment description | Optional |
metadata |
object | Additional metadata (key-value pairs) | Optional |
POST https://payhiive.com/api/v1/payments
Headers:
Authorization: Bearer sk_your_token
Content-Type: application/json
Body:
{
"amount": 10000,
"currency": "UGX",
"phone_number": "256700000000",
"provider": "MTN_MOMO_UGA",
"description": "Payment for order #123",
"metadata": {
"order_id": "123",
"product_id": "456"
}
}
{
"success": true,
"data": {
"id": 123,
"transaction_id": "TXN-ABC123XYZ",
"deposit_id": "DEP-123456789",
"amount": 10000,
"currency": "UGX",
"status": "pending",
"provider": "payment_provider",
"message": "Payment request sent successfully",
"created_at": "2025-12-10T12:00:00Z"
}
}
{
"success": false,
"message": "Provider MTN_MOMO_UGA is not enabled. Please contact support to enable this provider.",
"error_code": "PROVIDER_NOT_ENABLED"
}
Note: The transaction status will be pending initially. It will be updated to completed or failed via webhook or when you check the status. The net_amount and fee are calculated and will be reflected in your account balance once the transaction is completed.
| Status | Description |
|---|---|
pending |
Payment request sent, waiting for customer to approve |
processing |
Customer has approved, payment is being processed |
completed |
Payment successfully completed and funds credited |
failed |
Payment failed (customer declined, insufficient funds, etc.) |
cancelled |
Payment was cancelled |
Retrieve the current status and details of a specific payment transaction.
{
"success": true,
"data": {
"id": 123,
"transaction_id": "TXN-ABC123XYZ",
"reference": "b6a677d8-8a3d-4d2d-9de5-d439510d7c62",
"amount": 10000,
"currency": "UGX",
"status": "completed",
"redirect_url": "https://your-website.com/success",
"created_at": "2025-12-10T12:00:00Z",
"updated_at": "2025-12-10T12:05:00Z"
}
}
The transaction reference is a unique identifier (UUID format) that is returned in the response when you create a payment or retrieve payment status. This reference can be used for tracking, reconciliation, and webhook verification.
To get the transaction reference:
POST /payments, the reference is included in the response.GET /payments/{transaction_id}, the reference field is included in the response data.https://payhiive.com/customer/dashboard/recent-transactions.Note: The transaction reference is different from the transaction_id. The reference is typically a UUID format (e.g., b6a677d8-8a3d-4d2d-9de5-d439510d7c62) and is used for provider-specific tracking, while the transaction_id is the internal transaction identifier used when calling the API with your token.
This guide will walk you through integrating transaction reference tracking into your application system.
https://payhiive.com/customer/loginPAYHIIVE_TOKEN=sk_your_token
API_BASE_URL=https://payhiive.com/api/v1
When creating a payment, make a POST request to the payments endpoint:
POST https://payhiive.com/api/v1/payments
Headers:
Authorization: Bearer sk_your_token
Content-Type: application/json
Body:
{
"amount": 10000,
"currency": "UGX",
"phone_number": "256700000000",
"provider": "MTN_MOMO_UGA",
"description": "Payment for order #123"
}
The response will include a transaction_id:
{
"success": true,
"data": {
"id": 123,
"transaction_id": "TXN-ABC123XYZ",
"amount": 10000,
"currency": "UGX",
"status": "pending",
"created_at": "2025-12-10T12:00:00Z"
}
}
After creating a payment, use the transaction_id to retrieve the full transaction details, including the reference:
GET https://payhiive.com/api/v1/payments/{transaction_id}
Headers:
Authorization: Bearer sk_your_token
Content-Type: application/json
The response will include the reference field:
{
"success": true,
"data": {
"id": 123,
"transaction_id": "TXN-ABC123XYZ",
"reference": "b6a677d8-8a3d-4d2d-9de5-d439510d7c62",
"amount": 10000,
"currency": "UGX",
"status": "completed",
"created_at": "2025-12-10T12:00:00Z",
"updated_at": "2025-12-10T12:05:00Z"
}
}
Save both the transaction_id and reference in your database for future reference and reconciliation:
// Example: Store transaction in your database
INSERT INTO orders (
order_id,
payment_transaction_id,
payment_reference,
amount,
status,
created_at
) VALUES (
'ORDER-12345',
'TXN-ABC123XYZ',
'b6a677d8-8a3d-4d2d-9de5-d439510d7c62',
10000,
'pending',
NOW()
);
You can verify payment status by checking the transaction using either the transaction_id or by querying your database using the stored reference:
// Check status via API
GET https://payhiive.com/api/v1/payments/TXN-ABC123XYZ
// Or query your database
SELECT * FROM orders
WHERE payment_reference = 'b6a677d8-8a3d-4d2d-9de5-d439510d7c62';
<?php
// Configuration
$apiBaseUrl = 'https://payhiive.com/api/v1';
$token = 'sk_your_token';
// Step 1: Create Payment
function createPayment($amount, $phoneNumber, $provider, $description) {
global $apiBaseUrl, $token;
$data = [
'amount' => $amount,
'currency' => 'UGX',
'phone_number' => $phoneNumber,
'provider' => $provider,
'description' => $description
];
$ch = curl_init($apiBaseUrl . '/payments');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $token,
'Content-Type: application/json'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return json_decode($response, true);
}
// Step 2: Get Transaction Reference
function getTransactionReference($transactionId) {
global $apiBaseUrl, $token;
$ch = curl_init($apiBaseUrl . '/payments/' . $transactionId);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $token,
'Content-Type: application/json'
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
if ($data['success'] && isset($data['data']['reference'])) {
return $data['data']['reference'];
}
return null;
}
// Usage Example
$payment = createPayment(10000, '256700000000', 'MTN_MOMO_UGA', 'Order #12345');
if ($payment['success']) {
$transactionId = $payment['data']['transaction_id'];
// Get the transaction reference
$reference = getTransactionReference($transactionId);
// Store in your database
// INSERT INTO orders (order_id, transaction_id, reference, status)
// VALUES ('ORDER-12345', $transactionId, $reference, 'pending');
echo "Transaction ID: " . $transactionId . "\n";
echo "Reference: " . $reference . "\n";
}
?>
// Configuration
const API_BASE_URL = 'https://payhiive.com/api/v1';
const TOKEN = 'sk_your_token';
// Step 1: Create Payment
async function createPayment(amount, phoneNumber, provider, description) {
const response = await fetch(`${API_BASE_URL}/payments`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${TOKEN}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: amount,
currency: 'UGX',
phone_number: phoneNumber,
provider: provider,
description: description
})
});
return await response.json();
}
// Step 2: Get Transaction Reference
async function getTransactionReference(transactionId) {
const response = await fetch(`${API_BASE_URL}/payments/${transactionId}`, {
method: 'GET',
headers: {
'Authorization': `Bearer ${TOKEN}`,
'Content-Type': 'application/json'
}
});
const data = await response.json();
if (data.success && data.data.reference) {
return data.data.reference;
}
return null;
}
// Usage Example
async function processPayment() {
const payment = await createPayment(
10000,
'256700000000',
'MTN_MOMO_UGA',
'Order #12345'
);
if (payment.success) {
const transactionId = payment.data.transaction_id;
const reference = await getTransactionReference(transactionId);
// Store in your database
// await db.query(
// 'INSERT INTO orders (order_id, transaction_id, reference, status) VALUES (?, ?, ?, ?)',
// ['ORDER-12345', transactionId, reference, 'pending']
// );
console.log('Transaction ID:', transactionId);
console.log('Reference:', reference);
}
}
processPayment();
You can also verify the transaction reference by viewing it in your merchant dashboard:
https://payhiive.com/customer/loginb6a677d8-8a3d-4d2d-9de5-d439510d7c62)Best Practices:
transaction_id and reference in your databasereference for reconciliation with payment provider recordstransaction_id for status checks and when calling the API (with your token)Retrieve a list of all your payments. Supports pagination and filtering.
Create a refund for a payment.
| Parameter | Type | Description | Required |
|---|---|---|---|
payment_id |
string | ID of the payment to refund | Required |
amount |
integer | Refund amount in cents (optional, defaults to full amount) | Optional |
reason |
string | Reason for refund | Optional |
PAYHIIVE provides hosted checkout pages that you can redirect your customers to for secure payment processing. Authenticate with your token (Dashboard → Tokens) when creating payment intents. This is the easiest way to accept payments without handling sensitive payment data yourself.
To create a payment intent, make a POST request to the payments endpoint with the payment details.
Create a new payment intent and get a secure checkout URL to redirect your customer to.
Note: Currency is fixed to UGX for payment intents. The amount should be provided as a decimal number (e.g., 50000.00 for 50,000 UGX).
| Parameter | Type | Description | Required |
|---|---|---|---|
amount |
decimal | Payment amount (e.g., 50000.00 for 50,000 UGX) | Required |
description |
string | Payment description (max 500 characters) | Optional |
callback_url |
string | Webhook URL to receive payment status updates | Optional |
POST https://payhiive.com/api/v1/payments
Headers:
Authorization: Bearer sk_your_token
Content-Type: application/json
Body:
{
"amount": 50000.00,
"description": "Payment for Order #12345",
"callback_url": "https://yoursite.com/webhooks/payment-status"
}
{
"reference": "PHV_MPDJWT5TLC",
"checkout_url": "https://payhiive.com/checkout/PHV_MPDJWT5TLC"
}
After creating a payment intent, redirect your customer to the checkout_url provided in the response.
Important: Always use the checkout_url from the response. Never construct the URL manually or allow the frontend to modify the amount or payment details.
// Create payment intent
const response = await fetch('https://payhiive.com/api/v1/payments', {
method: 'POST',
headers: {
'Authorization': 'Bearer sk_your_token',
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: 50000.00, // Amount as decimal (50,000 UGX)
description: 'Payment for Order #12345',
callback_url: 'https://yoursite.com/webhooks/payment-status'
})
});
const data = await response.json();
if (data.reference && data.checkout_url) {
// Redirect customer to secure checkout page
window.location.href = data.checkout_url;
} else {
console.error('Failed to create payment intent:', data);
}
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://payhiive.com/api/v1/payments');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'amount' => 50000.00, // Amount as decimal (50,000 UGX)
'description' => 'Payment for Order #12345',
'callback_url' => 'https://yoursite.com/webhooks/payment-status'
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer sk_your_token',
'Content-Type: application/json'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$data = json_decode($response, true);
if ($httpCode === 201 && isset($data['checkout_url'])) {
// Redirect customer to secure checkout page
header('Location: ' . $data['checkout_url']);
exit;
} else {
// Handle error
echo 'Payment failed: ' . ($data['message'] ?? 'Unknown error');
}
?>
After redirecting your customer to the checkout page, you can check the payment status using the status endpoint.
Check the status of a payment intent using the reference returned when creating the payment.
GET https://payhiive.com/checkout/PHV_MPDJWT5TLC/status
Headers:
Accept: application/json
{
"success": true,
"data": {
"reference": "PHV_MPDJWT5TLC",
"status": "paid",
"transaction_status": "completed",
"transaction_id": "TXN-ABCDEFGHIJKL",
"is_paid": true,
"is_completed": true
}
}
Automatic Payment Provider Check: The status endpoint automatically queries the payment provider's API directly if the payment is still pending. This ensures you get real-time status updates even if webhooks are delayed.
| Status | Description |
|---|---|
pending |
Payment intent created, waiting for customer to pay |
paid |
Payment successfully completed |
failed |
Payment failed |
expired |
Payment intent expired (default: 24 hours) |
Best Practice: Always verify the payment status on your server using the reference and status endpoint, rather than relying solely on the redirect. This ensures the payment was actually completed.
PAYHIIVE provides a secure hosted checkout page for payment intents. This is the recommended way to accept payments as it ensures merchants never control payment amounts, currency, or recipient information on the frontend. All payment data is stored server-side and fetched from the database using a secure, unguessable reference.
Copy these code snippets and replace with your token. That's it!
https://payhiive.com/checkout/PHV_MPDJWT5TLC
This is an example. Replace PHV_MPDJWT5TLC with the actual reference from the response
// Step 1: Replace with your token from Dashboard → Tokens
const API_BASE_URL = 'https://payhiive.com/api/v1';
const TOKEN = 'sk_your_token'; // Your token from Dashboard → Tokens
// Step 2: Function to create payment and redirect to checkout
async function redirectToPayHiveCheckout(amount, description) {
try {
// Create payment intent via API
const response = await fetch(`${API_BASE_URL}/payments`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${TOKEN}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: amount, // e.g., 50000.00 for 50,000 UGX
description: description, // e.g., "Order #12345"
callback_url: 'https://yoursite.com/webhooks/payment' // Optional: for webhooks
})
});
const data = await response.json();
// Step 3: Redirect customer to checkout page
if (data.checkout_url) {
window.location.href = data.checkout_url; // ← This redirects to PayHive checkout
return { success: true, reference: data.reference };
} else {
throw new Error(data.message || 'Failed to create payment');
}
} catch (error) {
console.error('Payment error:', error);
alert('Payment failed: ' + error.message);
return { success: false, error: error.message };
}
}
// Step 4: Use it in your "Pay Now" button
document.getElementById('pay-button').addEventListener('click', async () => {
await redirectToPayHiveCheckout(50000.00, 'Payment for Order #12345');
// Customer will be automatically redirected to checkout page
});
// Notes:
// - Replace API_BASE_URL with your PayHive instance URL
// - Get your token from: Dashboard → Tokens
// - The checkout_url from the response is the redirect destination
// - Amount is in smallest currency unit (50000.00 = 50,000 UGX)
// - Always call this from your backend in production (keep token secure)
<?php
// Step 1: Replace with your token from Dashboard → Tokens
$API_BASE_URL = 'https://payhiive.com/api/v1';
$TOKEN = 'sk_your_token'; // Your token from Dashboard → Tokens
// Step 2: Function to create payment and redirect to checkout
function redirectToPayHiveCheckout($amount, $description) {
global $API_BASE_URL, $TOKEN;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $API_BASE_URL . '/payments');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $TOKEN,
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'amount' => $amount, // e.g., 50000.00 for 50,000 UGX
'description' => $description, // e.g., "Order #12345"
'callback_url' => 'https://yoursite.com/webhooks/payment' // Optional
]));
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$data = json_decode($response, true);
// Step 3: Redirect customer to checkout page
if ($httpCode === 201 && isset($data['checkout_url'])) {
header('Location: ' . $data['checkout_url']); // ← This redirects to PayHive checkout
exit;
} else {
die('Payment failed: ' . ($data['message'] ?? 'Unknown error'));
}
}
// Step 4: Use it when customer clicks "Pay Now"
if (isset($_POST['pay_now'])) {
redirectToPayHiveCheckout(50000.00, 'Payment for Order #12345');
// Customer will be automatically redirected to checkout page
}
// Notes:
// - Replace $API_BASE_URL with your PayHive instance URL
// - Get your token from: Dashboard → Tokens
// - The checkout_url from the response is the redirect destination
// - Amount is in smallest currency unit (50000.00 = 50,000 UGX)
// - Always keep token on server, never expose in frontend
import requests
from flask import redirect # or: from django.shortcuts import redirect
# Step 1: Replace with your token from Dashboard → Tokens
API_BASE_URL = 'https://payhiive.com/api/v1'
TOKEN = 'sk_your_token' # Your token from Dashboard → Tokens
# Step 2: Function to create payment and redirect to checkout
def redirect_to_payhive_checkout(amount, description):
url = f'{API_BASE_URL}/payments'
headers = {
'Authorization': f'Bearer {TOKEN}',
'Content-Type': 'application/json'
}
data = {
'amount': amount, # e.g., 50000.00 for 50,000 UGX
'description': description, # e.g., "Order #12345"
'callback_url': 'https://yoursite.com/webhooks/payment' # Optional
}
response = requests.post(url, json=data, headers=headers)
result = response.json()
# Step 3: Redirect customer to checkout page
if response.status_code == 201 and 'checkout_url' in result:
return redirect(result['checkout_url']) # ← This redirects to PayHive checkout
else:
return {'error': result.get('message', 'Payment failed')}
# Step 4: Use it in your route/view
@app.route('/pay', methods=['POST']) # Flask example
def pay():
return redirect_to_payhive_checkout(50000.00, 'Payment for Order #12345')
# Customer will be automatically redirected to checkout page
# Notes:
# - Replace API_BASE_URL with your PayHive instance URL
# - Get your token from: Dashboard → Tokens
# - The checkout_url from the response is the redirect destination
# - Amount is in smallest currency unit (50000.00 = 50,000 UGX)
# - Keep your token on server, never expose in frontend
# - Install requests: pip install requests
That's it! Just copy the code, replace your token, and redirect to checkout_url. The checkout page handles everything else.
Security Features:
Follow these simple steps to integrate the hosted checkout page into your application:
Make a POST request to /api/v1/payments with the payment amount and description.
POST https://payhiive.com/api/v1/payments
Headers:
Authorization: Bearer sk_your_token
Content-Type: application/json
Body:
{
"amount": 50000.00,
"description": "Payment for Order #12345"
}
The API will return a response with a checkout_url:
{
"reference": "PHV_MPDJWT5TLC",
"checkout_url": "https://payhiive.com/checkout/PHV_MPDJWT5TLC"
}
Redirect your customer to the checkout_url from the response. The customer will see a secure checkout page where they can complete the payment.
Important: Always redirect to the checkout_url provided in the response. Never construct the URL manually or trust frontend data.
After the customer completes payment, you can:
callback_url, you'll receive a POST request when payment status changesreferenceTo create a payment intent, make a POST request to the payments endpoint. This will create a payment intent and return a checkout URL.
Create a new payment intent and get a secure checkout URL to redirect your customer to.
| Parameter | Type | Description | Required |
|---|---|---|---|
amount |
decimal | Payment amount (e.g., 50000.00 for 50,000 UGX) | Required |
description |
string | Payment description (max 500 characters) | Optional |
callback_url |
string | Webhook URL to receive payment status updates | Optional |
Note: Currency is fixed to UGX for payment intents. The amount should be provided as a decimal number (e.g., 50000.00 for 50,000 UGX).
POST https://payhiive.com/api/v1/payments
Headers:
Authorization: Bearer sk_your_token
Content-Type: application/json
Body:
{
"amount": 50000.00,
"description": "Payment for Order #12345",
"callback_url": "https://yoursite.com/webhooks/payment-status"
}
{
"reference": "PHV_MPDJWT5TLC",
"checkout_url": "https://payhiive.com/checkout/PHV_MPDJWT5TLC"
}
After creating a payment intent, you'll receive a checkout_url in the response. Redirect your customer to this URL to complete the payment.
Important: Always use the checkout_url from the response. Never construct the URL manually or allow the frontend to modify the amount or payment details.
When customers visit the checkout URL, they will see:
Note: This example shows frontend code, but in production, you should make the API call from your backend server to keep your token secure.
// Step 1: Create payment intent (call from your backend)
async function createPaymentIntent(amount, description) {
try {
const response = await fetch('https://payhiive.com/api/v1/payments', {
method: 'POST',
headers: {
'Authorization': 'Bearer sk_your_token', // ⚠️ Keep token on backend!
'Content-Type': 'application/json'
},
body: JSON.stringify({
amount: amount,
description: description,
callback_url: 'https://yoursite.com/webhooks/payment-status' // Optional
})
});
const data = await response.json();
// Step 2: Check if payment intent was created successfully
if (data.reference && data.checkout_url) {
// Step 3: Redirect customer to checkout page
window.location.href = data.checkout_url;
return { success: true, reference: data.reference };
} else {
console.error('Failed to create payment intent:', data);
return { success: false, error: data.message || 'Unknown error' };
}
} catch (error) {
console.error('Error creating payment intent:', error);
return { success: false, error: error.message };
}
}
// Usage example:
// When customer clicks "Pay Now" button
document.getElementById('pay-button').addEventListener('click', async () => {
const result = await createPaymentIntent(50000.00, 'Payment for Order #12345');
if (!result.success) {
alert('Failed to create payment: ' + result.error);
}
// Customer will be automatically redirected to checkout page
});
<?php
/**
* Step 1: Create Payment Intent
* This should be called from your backend server (e.g., when customer clicks "Pay Now")
*/
function createPaymentIntent($amount, $description, $callbackUrl = null) {
$baseUrl = 'https://payhiive.com/api/v1';
$token = 'sk_your_token'; // ⚠️ Keep token secure on your server!
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $baseUrl . '/payments');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
$payload = [
'amount' => $amount,
'description' => $description
];
if ($callbackUrl) {
$payload['callback_url'] = $callbackUrl;
}
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $token,
'Content-Type: application/json'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$data = json_decode($response, true);
// Step 2: Check response and get checkout URL
if ($httpCode === 201 && isset($data['checkout_url'])) {
return [
'success' => true,
'reference' => $data['reference'],
'checkout_url' => $data['checkout_url']
];
} else {
return [
'success' => false,
'error' => $data['message'] ?? 'Unknown error'
];
}
}
// Example: Laravel Controller
class PaymentController extends Controller {
public function initiateCheckout(Request $request) {
// Validate request
$request->validate([
'amount' => 'required|numeric|min:0.01',
'description' => 'nullable|string|max:500'
]);
// Step 1: Create payment intent
$result = createPaymentIntent(
$request->amount,
$request->description ?? 'Payment',
route('webhooks.payment-status') // Your webhook URL
);
// Step 2: Check if successful
if ($result['success']) {
// Step 3: Redirect customer to checkout page
return redirect($result['checkout_url']);
} else {
// Handle error
return back()->withErrors(['error' => $result['error']]);
}
}
}
// Example: Plain PHP (when customer clicks "Pay Now")
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['amount'])) {
$result = createPaymentIntent(
floatval($_POST['amount']),
$_POST['description'] ?? 'Payment'
);
if ($result['success']) {
// Step 3: Redirect customer to checkout
header('Location: ' . $result['checkout_url']);
exit;
} else {
// Show error to user
die('Payment failed: ' . $result['error']);
}
}
?>
import requests
from flask import redirect, request, jsonify # For Flask
# from django.shortcuts import redirect # For Django
def create_payment_intent(amount, description, callback_url=None):
"""
Step 1: Create a payment intent via API
Returns: dict with 'success', 'checkout_url', and 'reference'
"""
url = 'https://payhiive.com/api/v1/payments'
headers = {
'Authorization': 'Bearer sk_your_token', # ⚠️ Keep token on backend!
'Content-Type': 'application/json'
}
data = {
'amount': amount,
'description': description
}
if callback_url:
data['callback_url'] = callback_url
try:
response = requests.post(url, json=data, headers=headers)
result = response.json()
# Step 2: Check if payment intent was created
if response.status_code == 201 and 'checkout_url' in result:
return {
'success': True,
'checkout_url': result['checkout_url'],
'reference': result['reference']
}
else:
return {
'success': False,
'error': result.get('message', 'Unknown error')
}
except Exception as e:
return {
'success': False,
'error': str(e)
}
# Flask Example
@app.route('/checkout/initiate', methods=['POST'])
def initiate_checkout():
amount = request.json.get('amount')
description = request.json.get('description', 'Payment')
# Step 1: Create payment intent
result = create_payment_intent(
amount=amount,
description=description,
callback_url='https://yoursite.com/webhooks/payment-status'
)
if result['success']:
# Step 2: Redirect customer to checkout page
return redirect(result['checkout_url'])
else:
return jsonify({'error': result['error']}), 400
# Django Example
from django.shortcuts import redirect
from django.http import JsonResponse
def initiate_checkout(request):
if request.method == 'POST':
amount = request.POST.get('amount')
description = request.POST.get('description', 'Payment')
# Step 1: Create payment intent
result = create_payment_intent(
amount=float(amount),
description=description,
callback_url='https://yoursite.com/webhooks/payment-status'
)
if result['success']:
# Step 2: Redirect customer to checkout page
return redirect(result['checkout_url'])
else:
return JsonResponse({'error': result['error']}, status=400)
The checkout URL that you receive from the API follows this format:
https://payhiive.com/checkout/{reference}
Where {reference} is the unguessable payment reference in the format PHV_xxxxx (e.g., PHV_MPDJWT5TLC).
Here are real examples of checkout URLs you'll receive:
// Example 1: Your actual checkout URL (from your system)
https://payhiive.com/checkout/PHV_MPDJWT5TLC
// Example 2: Another example format
https://payhiive.com/checkout/PHV_DZ4LGW3QM0
// Example 3: Production example (when app_url is set in database)
https://payhiive.com/checkout/PHV_MPDJWT5TLC
When you receive the checkout_url from the response, simply redirect your customer to that URL:
// JavaScript/React
window.location.href = data.checkout_url;
// PHP
header('Location: ' . $data['checkout_url']);
exit;
// Python (Flask)
return redirect(result['checkout_url'])
// Python (Django)
return redirect(result['checkout_url'])
Important: Always use the checkout_url from the response. Do not construct the URL manually. The reference is generated server-side and is cryptographically secure. The format is always https://payhiive.com/checkout/PHV_MPDJWT5TLC where PHV_MPDJWT5TLC is a unique reference (PHV_ + 10 characters).
| Component | Description | Example |
|---|---|---|
Base URL |
Your PayHive instance URL | https://payhiive.com |
/checkout/ |
Checkout route prefix | /checkout/ |
Reference |
Unique payment intent reference (PHV_ + 10 characters) | PHV_MPDJWT5TLC |
POST /api/v1/payments with amount and descriptioncheckout_url (e.g., https://payhiive.com/checkout/PHV_MPDJWT5TLC)checkout_urlcallback_url (if provided) with payment status| Status | Description |
|---|---|
pending |
Payment intent created, waiting for customer to complete payment |
paid |
Payment successfully completed |
failed |
Payment failed (customer declined, insufficient funds, etc.) |
expired |
Payment intent expired (default: 24 hours after creation) |
If you provided a callback_url when creating the payment intent, you will receive a POST request to that URL when the payment status changes.
POST https://yoursite.com/webhooks/payment-status
Content-Type: application/json
{
"reference": "PHV_MPDJWT5TLC",
"status": "paid",
"transaction_id": "TXN-ABCDEFGHIJKL",
"amount": 50000.00,
"currency": "UGX",
"net_amount": 48500.00,
"timestamp": "2025-01-25T12:00:00Z"
}
paid - Payment successfully completedfailed - Payment failedAlways verify that the webhook request is legitimate by:
After redirecting your customer to the checkout page, you can check the payment status in several ways:
Poll the status endpoint to check if payment has been completed. The system automatically checks the payment provider directly if the webhook hasn't arrived yet.
GET https://payhiive.com/checkout/PHV_MPDJWT5TLC/status
Headers:
Accept: application/json
{
"success": true,
"data": {
"reference": "PHV_MPDJWT5TLC",
"status": "paid",
"transaction_status": "completed",
"transaction_id": "TXN-ABCDEFGHIJKL",
"is_paid": true,
"is_completed": true
}
}
Automatic Payment Provider Check: The status endpoint automatically queries the payment provider's API directly if the payment is still pending. This ensures you get real-time status updates even if webhooks are delayed. The system uses the same reliable method as payment links.
// Poll payment status every 2 seconds
function checkPaymentStatus(reference) {
return fetch(`https://payhiive.com/checkout/${reference}/status`, {
method: 'GET',
headers: {
'Accept': 'application/json',
'X-Requested-With': 'XMLHttpRequest'
},
cache: 'no-cache'
})
.then(response => response.json())
.then(data => {
if (data.success && data.data) {
// Check if payment is completed
if (data.data.status === 'paid' ||
data.data.transaction_status === 'completed' ||
data.data.is_paid === true ||
data.data.is_completed === true) {
return { completed: true, status: data.data };
}
// Check if payment failed
if (data.data.status === 'failed' ||
data.data.transaction_status === 'failed') {
return { completed: true, failed: true, status: data.data };
}
// Still pending
return { completed: false, status: data.data };
}
return { completed: false, error: 'Invalid response' };
});
}
// Usage: Poll every 2 seconds until completed
let pollCount = 0;
const maxPolls = 60; // 2 minutes
const pollInterval = setInterval(async () => {
pollCount++;
if (pollCount > maxPolls) {
clearInterval(pollInterval);
console.log('Polling timeout');
return;
}
const result = await checkPaymentStatus('PHV_MPDJWT5TLC');
if (result.completed) {
clearInterval(pollInterval);
if (result.failed) {
console.log('Payment failed');
} else {
console.log('Payment completed!', result.status);
// Update your UI or redirect
}
}
}, 2000); // Check every 2 seconds
If you provided a callback_url, you'll receive a POST request when the payment status changes. This is the most reliable method for server-side applications.
Best Practice: Use webhooks for server-side status updates, and polling for client-side real-time updates. The status endpoint automatically checks the payment provider directly, so you'll get updates even if webhooks are delayed.
The system uses multiple methods to ensure reliable payment status detection:
Reliability: The system uses the same proven status detection method as payment links, which includes direct payment provider API checks. This ensures payments are detected even if webhooks are delayed or missed.
You can test the checkout page by visiting:
https://payhiive.com/test-checkout
This will create a test payment intent and redirect you to the checkout page.
If you encounter issues with the checkout page, here are common problems and solutions:
If you receive the error message "PayHive checkout endpoint not found. Please contact support to verify your API configuration." when creating a payment intent:
POST /api/v1/paymentsAuthorization: Bearer header is correct and your token is activecheckout.payment-intent.show existsAPP_URL is correctly configured in your .env fileSolution: Check the response. The checkout_url should be in the format: https://payhiive.com/checkout/PHV_MPDJWT5TLC. If the URL is missing or incorrect, check your Laravel logs at storage/logs/laravel.log for route generation errors.
// Example of correct response:
{
"reference": "PHV_MPDJWT5TLC",
"checkout_url": "https://payhiive.com/checkout/PHV_MPDJWT5TLC"
}
// If you receive an error instead, check:
// 1. API authentication headers
// 2. API endpoint URL (should be /api/v1/payments)
// 3. Server logs for detailed error messages
If customers see the error message "PayHive payment service is temporarily unavailable. Please try again in a few moments or contact support.", this usually indicates:
payment_intents table existsstorage/logs/laravel.log for detailed error messagesSolution: Verify your payment provider integration settings and check server logs. The checkout page will still load even if payment providers are disabled, but payment processing will fail.
If you get a 404 error when accessing the checkout URL:
PHV_MPDJWT5TLC or similar PHV_ format)If customers see an "expired" message:
expires_at fieldIf the checkout page loads but shows no mobile money options:
enabled_providers field contains MTN_MOMO_UGA and/or AIRTEL_OAPI_UGAIf payment submission fails:
If you're not receiving webhook notifications:
callback_url is publicly accessible (not localhost)Best Practice: Always verify payment completion via webhook or by checking the payment intent status server-side. Never rely solely on the customer being redirected to a success page.
Webhooks let you receive real-time notifications about payment and account events. When you create a payment or payment intent with your token, you can pass a callback_url; we will POST to that URL when the payment status changes.
| Event | Description |
|---|---|
payment.succeeded |
Triggered when a payment is successfully completed |
payment.failed |
Triggered when a payment fails |
payment.refunded |
Triggered when a payment is refunded |
payment.pending |
Triggered when a payment is pending |
All errors follow a consistent format:
{
"success": false,
"error": {
"code": "invalid_request",
"message": "The request is missing required parameters",
"details": {
"field": "amount",
"reason": "Amount must be greater than 0"
}
}
}
| Error Code | HTTP Status | Description | Solution |
|---|---|---|---|
PROVIDER_NOT_CONFIGURED |
503 | Payment provider not configured | Contact support to configure payment provider |
PROVIDER_NOT_ENABLED |
400 | Requested provider (MTN/Airtel) is not enabled | Contact support to enable the provider or use a different provider |
FEE_EXCEEDS_AMOUNT |
400 | Total fees exceed transaction amount | Increase the transaction amount or adjust fee settings |
AUTH_FAILED |
401 | Invalid or missing token | Check that your Authorization: Bearer token is correct |
INVALID_REQUEST |
400 | Invalid request parameters | Check required fields: amount, currency, phone_number, provider |
NOT_FOUND |
404 | Transaction not found | Verify the transaction_id is correct |
Possible causes:
Solution: Verify your token is correct and active in Dashboard → Tokens.
Possible causes:
Solution: Use the correct provider name: MTN_MOMO_UGA or AIRTEL_OAPI_UGA. Contact support if the provider needs to be enabled.
Possible causes:
Solution: Wait for the customer to approve. Check payment status periodically. Payments typically complete within a few minutes.
Format: Phone numbers must be in international format without the + sign:
256700000000 (Uganda MTN)+256700000000 or 0700000000API requests are rate-limited to ensure fair usage:
Rate limit information is included in response headers:
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1639123200
You can use the same token (from Dashboard → Tokens at https://payhiive.com/customer/tokens) to collect payments without redirecting customers to the hosted checkout page. This is useful when you want to keep users on your own website or app and collect the phone number and network yourself.
Two ways to accept payments with your token:
POST /api/v1/payments with amount, description, callback_url → get checkout_url and redirect the customer to our secure page.POST /api/v1/payments/direct with amount, currency, phone_number, provider, description → we send the mobile money prompt to the customer's phone; they never leave your site.Tokens generated from the customer dashboard work for both flows. Use the same Authorization: Bearer header.
Initiate a mobile money payment directly. You collect the customer's phone number and network (MTN or Airtel) on your form; we send the payment request to their phone. No redirect to the checkout page.
| Parameter | Type | Description | Required |
|---|---|---|---|
amount |
integer | Amount in UGX (e.g., 10000 = 10,000 UGX) | Required |
currency |
string | Currency code (UGX) | Required |
phone_number |
string | Customer mobile money number (e.g., 256700000000) | Required |
provider |
string | MTN_MOMO_UGA or AIRTEL_OAPI_UGA |
Required |
description |
string | Payment description | Optional |
metadata |
object | Additional metadata (e.g. order_id) | Optional |
POST https://payhiive.com/api/v1/payments/direct
Headers:
Authorization: Bearer sk_your_token
Content-Type: application/json
Body:
{
"amount": 10000,
"currency": "UGX",
"phone_number": "256700000000",
"provider": "MTN_MOMO_UGA",
"description": "Payment for order #123"
}
{
"success": true,
"data": {
"id": 123,
"transaction_id": "TXN-ABC123XYZ",
"amount": 10000,
"currency": "UGX",
"status": "pending",
"message": "Payment request sent successfully",
"created_at": "2025-12-10T12:00:00Z"
}
}
Reference (UUID): Use transaction_id for status checks. The reference (UUID format, e.g. b6a677d8-8a3d-4d2d-9de5-d439510d7c62) is returned when you call GET /api/v1/payments/{transaction_id}; store it for reconciliation and provider tracking.
React (JavaScript)
const API_BASE = 'https://payhiive.com/api/v1';
const TOKEN = 'sk_your_token';
async function createDirectPayment(amount, currency, phoneNumber, provider, description) {
const res = await fetch(`${API_BASE}/payments/direct`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
amount,
currency: currency || 'UGX',
phone_number: phoneNumber,
provider: provider || 'MTN_MOMO_UGA',
description: description || '',
}),
});
const data = await res.json();
if (!data.success) throw new Error(data.message || 'Payment failed');
return data.data; // { transaction_id, status, ... }
}
async function getPaymentStatus(transactionId) {
const res = await fetch(`${API_BASE}/payments/${transactionId}`, {
headers: { 'Authorization': `Bearer ${TOKEN}` },
});
const data = await res.json();
if (!data.success) throw new Error(data.message || 'Failed to get status');
return data.data; // includes reference (UUID) for reconciliation
}
// Usage: collect phone on your form, then:
const payment = await createDirectPayment(10000, 'UGX', '256700000000', 'MTN_MOMO_UGA', 'Order #123');
const txId = payment.transaction_id; // store for status polling
const status = await getPaymentStatus(txId);
const referenceUuid = status.reference; // UUID, e.g. b6a677d8-8a3d-4d2d-9de5-d439510d7c62
Python
import requests
API_BASE = 'https://payhiive.com/api/v1'
TOKEN = 'sk_your_token'
HEADERS = {'Authorization': f'Bearer {TOKEN}', 'Content-Type': 'application/json'}
def create_direct_payment(amount, phone_number, provider='MTN_MOMO_UGA', description=''):
r = requests.post(f'{API_BASE}/payments/direct', json={
'amount': amount,
'currency': 'UGX',
'phone_number': phone_number,
'provider': provider,
'description': description,
}, headers=HEADERS)
data = r.json()
if not data.get('success'):
raise Exception(data.get('message', 'Payment failed'))
return data['data'] # transaction_id, status, ...
def get_payment_status(transaction_id):
r = requests.get(f'{API_BASE}/payments/{transaction_id}', headers=HEADERS)
data = r.json()
if not data.get('success'):
raise Exception(data.get('message', 'Failed to get status'))
return data['data'] # includes reference (UUID)
# Usage
payment = create_direct_payment(10000, '256700000000', 'MTN_MOMO_UGA', 'Order #123')
tx_id = payment['transaction_id'] # store for status / reconciliation
status = get_payment_status(tx_id)
reference_uuid = status.get('reference') # UUID, e.g. b6a677d8-8a3d-4d2d-9de5-d439510d7c62
PHP (Laravel)
use Illuminate\Support\Facades\Http;
$apiBase = 'https://payhiive.com/api/v1';
$token = 'sk_your_token';
function createDirectPayment($amount, $phoneNumber, $provider = 'MTN_MOMO_UGA', $description = '') {
global $apiBase, $token;
$res = Http::withHeaders([
'Authorization' => 'Bearer ' . $token,
'Content-Type' => 'application/json',
])->post("{$apiBase}/payments/direct", [
'amount' => $amount,
'currency' => 'UGX',
'phone_number' => $phoneNumber,
'provider' => $provider,
'description' => $description,
]);
$data = $res->json();
if (!($data['success'] ?? false)) {
throw new \Exception($data['message'] ?? 'Payment failed');
}
return $data['data']; // transaction_id, status, ...
}
function getPaymentStatus($transactionId) {
global $apiBase, $token;
$res = Http::withHeaders([
'Authorization' => 'Bearer ' . $token,
])->get("{$apiBase}/payments/{$transactionId}");
$data = $res->json();
if (!($data['success'] ?? false)) {
throw new \Exception($data['message'] ?? 'Failed to get status');
}
return $data['data']; // includes reference (UUID)
}
// Usage (e.g. in a controller)
$payment = createDirectPayment(10000, '256700000000', 'MTN_MOMO_UGA', 'Order #123');
$txId = $payment['transaction_id']; // store for status / reconciliation
$status = getPaymentStatus($txId);
$referenceUuid = $status['reference'] ?? null; // UUID, e.g. b6a677d8-8a3d-4d2d-9de5-d439510d7c62
The customer will receive a mobile money prompt on their phone. Track status via webhook or GET /api/v1/payments/{transaction_id}.
Same token everywhere. The token you create at https://payhiive.com/customer/tokens works for both hosted checkout and direct payments. Use it in your websites and apps with the headers above.
Here are complete integration examples for different platforms and languages:
<?php
// Configuration
$baseUrl = 'https://payhiive.com/api/v1';
$token = 'sk_your_token';
// Create payment
function createPayment($amount, $phoneNumber, $provider, $description = '') {
global $baseUrl, $token;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $baseUrl . '/payments');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
'amount' => $amount,
'currency' => 'UGX',
'phone_number' => $phoneNumber,
'provider' => $provider, // 'MTN_MOMO_UGA' or 'AIRTEL_OAPI_UGA'
'description' => $description
]));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . $token,
'Content-Type: application/json'
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode === 200 || $httpCode === 201) {
return json_decode($response, true);
}
return ['success' => false, 'error' => json_decode($response, true)];
}
// Usage
$result = createPayment(10000, '256700000000', 'MTN_MOMO_UGA', 'Order #123');
if ($result['success']) {
echo "Payment created: " . $result['data']['transaction_id'];
echo "\nNet amount: " . ($result['data']['net_amount'] ?? 'N/A') . " UGX";
echo "\nFee: " . ($result['data']['fee'] ?? 'N/A') . " UGX";
} else {
echo "Error: " . ($result['error']['message'] ?? $result['message'] ?? 'Unknown error');
}
?>
// Install: npm install axios
import axios from 'axios';
const API_BASE_URL = 'https://payhiive.com/api/v1';
const TOKEN = 'sk_your_token';
// Create payment function
async function createPayment(amount, phoneNumber, provider, description = '') {
try {
const response = await axios.post(
`${API_BASE_URL}/payments`,
{
amount: amount,
currency: 'UGX',
phone_number: phoneNumber,
provider: provider, // 'MTN_MOMO_UGA' or 'AIRTEL_OAPI_UGA'
description: description
},
{
headers: {
'Authorization': `Bearer ${TOKEN}`,
'Content-Type': 'application/json'
}
}
);
return response.data;
} catch (error) {
console.error('Payment error:', error.response?.data || error.message);
throw error;
}
}
// React Component Example
function PaymentButton() {
const handlePayment = async () => {
try {
const result = await createPayment(
10000,
'256700000000',
'MTN_MOMO_UGA',
'Order #123'
);
if (result.success) {
console.log('Payment created:', result.data.transaction_id);
console.log('Net amount:', result.data.net_amount, 'UGX');
console.log('Fee:', result.data.fee, 'UGX');
alert('Payment initiated successfully!');
}
} catch (error) {
alert('Payment failed: ' + (error.response?.data?.error?.message || error.message));
}
};
return (
<button onClick={handlePayment}>
Pay 10,000 UGX
</button>
);
}
export default PaymentButton;
# Install: pip install requests
import requests
import json
# Configuration
API_BASE_URL = 'https://payhiive.com/api/v1'
TOKEN = 'sk_your_token'
def create_payment(amount, phone_number, provider, description=''):
"""
Create a mobile money payment
Args:
amount: Amount in UGX
phone_number: Customer phone number (e.g., '256700000000')
provider: 'MTN_MOMO_UGA' or 'AIRTEL_OAPI_UGA'
description: Payment description
Returns:
dict: API response
"""
url = f'{API_BASE_URL}/payments'
headers = {
'Authorization': f'Bearer {TOKEN}',
'Content-Type': 'application/json'
}
data = {
'amount': amount,
'currency': 'UGX',
'phone_number': phone_number,
'provider': provider,
'description': description
}
try:
response = requests.post(url, json=data, headers=headers)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f'Error: {e}')
if hasattr(e.response, 'json'):
return e.response.json()
return {'success': False, 'error': {'message': str(e)}}
# Usage example
if __name__ == '__main__':
result = create_payment(
amount=10000,
phone_number='256700000000',
provider='MTN_MOMO_UGA',
description='Order #123'
)
if result.get('success'):
print(f"Payment created: {result['data']['transaction_id']}")
print(f"Net amount: {result['data'].get('net_amount', 'N/A')} UGX")
print(f"Fee: {result['data'].get('fee', 'N/A')} UGX")
else:
print(f"Error: {result.get('error', {}).get('message', result.get('message', 'Unknown error'))}")
Security Note: Never expose your token in client-side code (React, browser JavaScript). Always make API calls from your backend server (PHP, Python, Node.js server) to keep your token secure.
If you have any questions or need assistance with the API, please contact our support team: