Technical Support
For API integration help:
- Email: contact.coevs@gmail.com
- Response Time: 24–48 hours
- Hours: Monday–Friday, 9 AM–6 PM UTC
Include your Merchant ID and detailed error descriptions for faster resolution.
Contact SupportIntegrate LIBPAY payment gateway into your application with our comprehensive RESTful API. Accept payments from wallets, cards, and multiple payment methods with enterprise-grade security.
Get started in minutes with our simple REST API
Bank-grade security with HMAC signature verification
Works with any programming language or framework
LIBPAY API uses API keys to authenticate requests. You can obtain your credentials from your merchant dashboard.
LIBPAY API supports both sandbox (testing) and production environments. Always test in sandbox first before going live.
Use for: Development, testing, integration
X-Environment: sandbox
Credentials: Use test_* prefixed API keys
Use for: Live payments, real money
X-Environment: production
Credentials: Use production API keys (no prefix)
Credential | Header | Description | Location |
---|---|---|---|
Merchant ID |
X-Merchant-Key |
Your unique merchant identifier | Dashboard → Merchant → CONFIG |
API Key |
X-API-Key |
API authentication key | Dashboard → Merchant → CONFIG |
Client Secret |
- | Used for webhook signature verification | Dashboard → Merchant → CONFIG |
Production API Key | X-API-Key |
Production API key (no prefix) | Merchant Dashboard > API Config > Production Mode |
Production Merchant Key | X-Merchant-Key |
Production merchant identifier (no prefix) | Merchant Dashboard > API Config > Production Mode |
Get up and running with LIBPAY API in just a few steps:
/api/v1/initiate-payment
Try LIBPAY API endpoints directly in your browser
Create a new payment request and get a secure checkout URL for your customer. This endpoint works in both sandbox and production environments based on your X-Environment header.
/api/v1/initiate-payment
Header | Value | Required | Description |
---|---|---|---|
Content-Type |
application/json |
✅ | Request content type |
X-Environment |
sandbox | production |
✅ | API environment mode |
X-Merchant-Key |
{merchant_key} |
✅ | Your Merchant ID (sandbox: test_ prefix, production: no prefix) |
X-API-Key |
{api_key} |
✅ | Your API Key (sandbox: test_ prefix, production: no prefix) |
Parameter | Type | Required | Description |
---|---|---|---|
payment_amount |
number | ✅ | Payment amount (minimum 1.00) |
currency_code |
string | ✅ | 3-letter currency code (USD, EUR, etc.) |
ref_trx |
string | ✅ | Your unique transaction reference |
description |
string | ❌ | Payment description |
success_redirect |
string | ✅ | Success redirect URL |
failure_url |
string | ✅ | Failure redirect URL |
cancel_redirect |
string | ✅ | Cancel redirect URL |
ipn_url |
string | ✅ | Webhook notification URL (same URL for both environments) |
curl -X POST "https://app.libpay.app/api/v1/initiate-payment" \
-H "Content-Type: application/json" \
-H "X-Environment: {environment}" \
-H "X-Merchant-Key: {merchant_key}" \
-H "X-API-Key: {api_key}" \
-d '{"payment_amount": 250.00, "currency_code": "USD", "ref_trx": "ORDER_12345", "description": "Premium Subscription", "success_redirect": "https://yoursite.com/payment/success", "failure_url": "https://yoursite.com/payment/failed", "cancel_redirect": "https://yoursite.com/payment/cancelled", "ipn_url": "https://yoursite.com/api/webhooks/LIBPAY"}'
<?php
use App\Enums\EnvironmentMode;
use Illuminate\Support\Facades\Http;
class LIBPAYPaymentInitiator
{
private $environment;
private $merchantKey;
private $apiKey;
private $baseUrl = 'https://app.libpay.app/api/v1';
public function __construct(EnvironmentMode $environment, $merchantKey, $apiKey)
{
$this->environment = $environment;
$this->merchantKey = $merchantKey;
$this->apiKey = $apiKey;
}
// Factory methods for easy configuration
public static function sandbox($testMerchantKey, $testApiKey): self
{
return new self(EnvironmentMode::SANDBOX, $testMerchantKey, $testApiKey);
}
public static function production($merchantKey, $apiKey): self
{
return new self(EnvironmentMode::PRODUCTION, $merchantKey, $apiKey);
}
public function initiatePayment($paymentData)
{
try {
$response = Http::withHeaders([
'Content-Type' => 'application/json',
'X-Environment' => $this->environment->value,
'X-Merchant-Key' => $this->merchantKey,
'X-API-Key' => $this->apiKey,
])->post("{$this->baseUrl}/initiate-payment", $paymentData);
if ($response->successful()) {
$data = $response->json();
if ($data['success']) {
return ['success' => true, 'data' => $data];
}
return ['success' => false, 'status' => $data['status'], 'message' => $data['message'] ?? 'Payment initiation failed'];
}
return ['success' => false, 'error' => 'API request failed'];
} catch (Exception $e) {
return ['success' => false, 'error' => $e->getMessage()];
}
}
}
// Usage: Choose appropriate factory method based on your environment
$initiator = LIBPAYPaymentInitiator::sandbox('test_merchant_key', 'test_api_key'); // For testing
// $initiator = LIBPAYPaymentInitiator::production('merchant_key', 'api_key'); // For production
$paymentData = [
'payment_amount' => 250.00,
'currency_code' => 'USD',
'ref_trx' => 'ORDER_12345',
'description' => 'Premium Subscription',
'success_redirect' => 'https://yoursite.com/payment/success',
'failure_url' => 'https://yoursite.com/payment/failed',
'cancel_redirect' => 'https://yoursite.com/payment/cancelled',
'ipn_url' => 'https://yoursite.com/api/webhooks/LIBPAY',
];
$result = $initiator->initiatePayment($paymentData);
const axios = require('axios');
const EnvironmentMode = {
SANDBOX: 'sandbox',
PRODUCTION: 'production'
};
class LIBPAYPaymentInitiator {
constructor(environment, merchantKey, apiKey) {
this.environment = environment;
this.merchantKey = merchantKey;
this.apiKey = apiKey;
this.baseUrl = 'https://app.libpay.app/api/v1';
}
// Factory methods
static sandbox(testMerchantKey, testApiKey) {
return new LIBPAYPaymentInitiator(EnvironmentMode.SANDBOX, testMerchantKey, testApiKey);
}
static production(merchantKey, apiKey) {
return new LIBPAYPaymentInitiator(EnvironmentMode.PRODUCTION, merchantKey, apiKey);
}
async initiatePayment(paymentData) {
try {
const response = await axios.post(`${this.baseUrl}/initiate-payment`, paymentData, {
headers: {
'Content-Type': 'application/json',
'X-Environment': this.environment,
'X-Merchant-Key': this.merchantKey,
'X-API-Key': this.apiKey
}
});
const data = response.data;
if (data.success) {
return { success: true, data };
}
return {
success: false,
status: data.status,
message: data.message || 'Payment initiation failed'
};
} catch (error) {
if (error.response) {
return {
success: false,
error: error.response.data.error || 'API request failed'
};
}
return { success: false, error: error.message };
}
}
}
// Usage: Choose appropriate factory method based on your environment
const initiator = LIBPAYPaymentInitiator.sandbox('test_merchant_key', 'test_api_key'); // For testing
// const initiator = LIBPAYPaymentInitiator.production('merchant_key', 'api_key'); // For production
const paymentData = {
payment_amount: 250.00,
currency_code: 'USD',
ref_trx: 'ORDER_12345',
description: 'Premium Subscription',
success_redirect: 'https://yoursite.com/payment/success',
failure_url: 'https://yoursite.com/payment/failed',
cancel_redirect: 'https://yoursite.com/payment/cancelled',
ipn_url: 'https://yoursite.com/api/webhooks/LIBPAY',
};
initiator.initiatePayment(paymentData)
.then(result => console.log(result))
.catch(error => console.error(error));
import requests
import logging
from enum import Enum
class EnvironmentMode(Enum):
SANDBOX = 'sandbox'
PRODUCTION = 'production'
class LIBPAYPaymentInitiator:
def __init__(self, environment, merchant_key, api_key):
self.environment = environment
self.merchant_key = merchant_key
self.api_key = api_key
self.base_url = 'https://app.libpay.app/api/v1'
@classmethod
def sandbox(cls, test_merchant_key, test_api_key):
return cls(EnvironmentMode.SANDBOX, test_merchant_key, test_api_key)
@classmethod
def production(cls, merchant_key, api_key):
return cls(EnvironmentMode.PRODUCTION, merchant_key, api_key)
def initiate_payment(self, payment_data):
try:
headers = {
'Content-Type': 'application/json',
'X-Environment': self.environment.value,
'X-Merchant-Key': self.merchant_key,
'X-API-Key': self.api_key
}
response = requests.post(
f"{self.base_url}/initiate-payment",
headers=headers,
json=payment_data,
timeout=30
)
if response.status_code == 200:
data = response.json()
if data['success']:
return {'success': True, 'data': data}
return {
'success': False,
'status': data['status'],
'message': data.get('message', 'Payment initiation failed')
}
return {'success': False, 'error': f'HTTP {response.status_code}'}
except requests.RequestException as e:
return {'success': False, 'error': str(e)}
# Usage: Choose appropriate factory method based on your environment
initiator = LIBPAYPaymentInitiator.sandbox('test_merchant_key', 'test_api_key') # For testing
# initiator = LIBPAYPaymentInitiator.production('merchant_key', 'api_key') # For production
payment_data = {
'payment_amount': 250.00,
'currency_code': 'USD',
'ref_trx': 'ORDER_12345',
'description': 'Premium Subscription',
'success_redirect': 'https://yoursite.com/payment/success',
'failure_url': 'https://yoursite.com/payment/failed',
'cancel_redirect': 'https://yoursite.com/payment/cancelled',
'ipn_url': 'https://yoursite.com/api/webhooks/LIBPAY',
}
result = initiator.initiate_payment(payment_data)
print(result)
{
"payment_url": "https://LIBPAY.test/payment/checkout?expires=1753724376&token=AmQvJdGIdGUVJUUMayJZZreBv2UcTyIHclk9Ps1s1pZhLpVlIqIBVPqGTRKQ3NUSehyM3qRUIf69IhLbNfJ1JqiMxlxNrnn22lNz1N01hZQn65r5VZnvhWmQPxQO8UX6rE4yfRUvT6bHdqLj7UDJhRPYRFSgCsG1b86sxSdKTZNOVJdWV5z8L6a5pNMZ2KlpG5e7bYa&signature=e9q7ea91456dcc167e7d498ea486f923570821957be8881566186655950f364",
"info": {
"ref_trx": "TXNT4AQFESTAG4F",
"description": "Order #1234",
"ipn_url": "https://webhook.site/5711b7d5-917a-4d94-bbb3-c28f4a37bea5",
"cancel_redirect": "https://merchant.com/cancel",
"success_redirect": "https://merchant.com/success",
"merchant_id": 1,
"merchant_name": "LIBPAY",
"amount": 200,
"currency_code": "USD",
"environment": "production",
"is_sandbox": false
}
}
{
"success": false,
"message": "Validation failed",
"errors": {
"payment_amount": ["The payment amount field is required."],
"currency_code": ["The currency code field is required."]
}
}
Verify the status of a payment using the LIBPAY transaction ID returned from the payment initiation.
/api/v1/verify-payment/{trxId}
Header | Value | Required | Description |
---|---|---|---|
Accept |
application/json |
✅ | Request content type |
X-Environment |
sandbox | production |
✅ | API environment mode |
X-Merchant-Key |
{merchant_key} |
✅ | Your Merchant ID (sandbox: test_ prefix, production: no prefix) |
X-API-Key |
{api_key} |
✅ | Your API Key (sandbox: test_ prefix, production: no prefix) |
Parameter | Type | Required | Description |
---|---|---|---|
trxId |
string | ✅ | LIBPAY transaction ID (e.g., TXNQ5V8K2L9N3XM1) |
curl -X GET "https://app.libpay.app/api/v1/verify-payment/TXNQ5V8K2L9N3XM1" \
-H "Accept: application/json" \
-H "X-Environment: {environment}" \
-H "X-Merchant-Key: {merchant_key}" \
-H "X-API-Key: {api_key}"
<?php
use App\Enums\EnvironmentMode;
use Illuminate\Support\Facades\Http;
class LIBPAYPaymentVerifier
{
private $environment;
private $merchantKey;
private $apiKey;
private $baseUrl = 'https://app.libpay.app/api/v1';
public function __construct(EnvironmentMode $environment, $merchantKey, $apiKey)
{
$this->environment = $environment;
$this->merchantKey = $merchantKey;
$this->apiKey = $apiKey;
}
// Factory methods for easy configuration
public static function sandbox($testMerchantKey, $testApiKey): self
{
return new self(EnvironmentMode::SANDBOX, $testMerchantKey, $testApiKey);
}
public static function production($merchantKey, $apiKey): self
{
return new self(EnvironmentMode::PRODUCTION, $merchantKey, $apiKey);
}
public function verifyPayment($trxId)
{
try {
$response = Http::withHeaders([
'Accept' => 'application/json',
'X-Environment' => $this->environment->value,
'X-Merchant-Key' => $this->merchantKey,
'X-API-Key' => $this->apiKey,
])->get("{$this->baseUrl}/verify-payment/{$trxId}");
if ($response->successful()) {
$data = $response->json();
if ($data['status'] === 'success') {
// Payment completed successfully
$this->fulfillOrder($data);
return ['success' => true, 'data' => $data];
}
return ['success' => false, 'status' => $data['status'], 'message' => $data['message'] ?? 'Payment not completed'];
}
return ['success' => false, 'error' => 'API request failed'];
} catch (Exception $e) {
return ['success' => false, 'error' => $e->getMessage()];
}
}
private function fulfillOrder($paymentData)
{
// Your order fulfillment logic here
logger('Payment verified successfully', $paymentData);
}
}
// Usage: Choose appropriate factory method based on your environment
$verifier = LIBPAYPaymentVerifier::sandbox('test_merchant_key', 'test_api_key'); // For testing
// $verifier = LIBPAYPaymentVerifier::production('merchant_key', 'api_key'); // For production
$result = $verifier->verifyPayment('TXNQ5V8K2L9N3XM1');
const axios = require('axios');
const EnvironmentMode = {
SANDBOX: 'sandbox',
PRODUCTION: 'production'
};
class LIBPAYPaymentVerifier {
constructor(environment, merchantKey, apiKey) {
this.environment = environment;
this.merchantKey = merchantKey;
this.apiKey = apiKey;
this.baseUrl = 'https://app.libpay.app/api/v1';
}
// Factory methods
static sandbox(testMerchantKey, testApiKey) {
return new LIBPAYPaymentVerifier(EnvironmentMode.SANDBOX, testMerchantKey, testApiKey);
}
static production(merchantKey, apiKey) {
return new LIBPAYPaymentVerifier(EnvironmentMode.PRODUCTION, merchantKey, apiKey);
}
async verifyPayment(trxId) {
try {
const response = await axios.get(`${this.baseUrl}/verify-payment/${trxId}`, {
headers: {
'Accept': 'application/json',
'X-Environment': this.environment,
'X-Merchant-Key': this.merchantKey,
'X-API-Key': this.apiKey
}
});
const data = response.data;
if (data.status === 'success') {
// Payment completed successfully
await this.fulfillOrder(data);
return { success: true, data };
}
return {
success: false,
status: data.status,
message: data.message || 'Payment not completed'
};
} catch (error) {
if (error.response) {
return {
success: false,
error: error.response.data.error || 'API request failed'
};
}
return { success: false, error: error.message };
}
}
async fulfillOrder(paymentData) {
// Your order fulfillment logic here
console.log('Payment verified successfully:', paymentData);
}
}
// Usage: Choose appropriate factory method based on your environment
const verifier = LIBPAYPaymentVerifier.sandbox('test_merchant_key', 'test_api_key'); // For testing
// const verifier = LIBPAYPaymentVerifier.production('merchant_key', 'api_key'); // For production
verifier.verifyPayment('TXNQ5V8K2L9N3XM1')
.then(result => console.log(result))
.catch(error => console.error(error));
import requests
import logging
from enum import Enum
class EnvironmentMode(Enum):
SANDBOX = 'sandbox'
PRODUCTION = 'production'
class LIBPAYPaymentVerifier:
def __init__(self, environment, merchant_key, api_key):
self.environment = environment
self.merchant_key = merchant_key
self.api_key = api_key
self.base_url = 'https://app.libpay.app/api/v1'
@classmethod
def sandbox(cls, test_merchant_key, test_api_key):
return cls(EnvironmentMode.SANDBOX, test_merchant_key, test_api_key)
@classmethod
def production(cls, merchant_key, api_key):
return cls(EnvironmentMode.PRODUCTION, merchant_key, api_key)
def verify_payment(self, trx_id):
try:
headers = {
'Accept': 'application/json',
'X-Environment': self.environment.value,
'X-Merchant-Key': self.merchant_key,
'X-API-Key': self.api_key
}
response = requests.get(
f"{self.base_url}/verify-payment/{trx_id}",
headers=headers,
timeout=30
)
if response.status_code == 200:
data = response.json()
if data['status'] == 'success':
# Payment completed successfully
self.fulfill_order(data)
return {'success': True, 'data': data}
return {
'success': False,
'status': data['status'],
'message': data.get('message', 'Payment not completed')
}
return {'success': False, 'error': f'HTTP {response.status_code}'}
except requests.RequestException as e:
return {'success': False, 'error': str(e)}
def fulfill_order(self, payment_data):
"""Your order fulfillment logic here"""
logging.info(f"Payment verified successfully: {payment_data}")
# Usage: Choose appropriate factory method based on your environment
verifier = LIBPAYPaymentVerifier.sandbox('test_merchant_key', 'test_api_key') # For testing
# verifier = LIBPAYPaymentVerifier.production('merchant_key', 'api_key') # For production
result = verifier.verify_payment('TXNQ5V8K2L9N3XM1')
print(result)
{
"status": "success",
"trx_id": "TXNQ5V8K2L9N3XM1",
"amount": 237.5,
"fee": 12.5,
"currency": "USD",
"net_amount": 237.5,
"customer": {
"name": "John Doe",
"email": "john@example.com"
},
"description": "Premium Subscription Payment",
"created_at": "2024-01-15T10:30:00.000000Z",
"updated_at": "2024-01-15T10:35:45.000000Z"
}
{
"status": "failed",
"trx_id": "TXNQ5V8K2L9N3XM1",
"message": "Payment failed or canceled."
}
{
"status": "pending",
"trx_id": "TXNQ5V8K2L9N3XM1",
"message": "Payment is still pending."
}
Status | Description | Action Required |
---|---|---|
pending |
Payment is still processing | Wait for webhook notification |
completed |
Payment was successful | Fulfill order/service |
failed |
Payment failed | Handle failed payment |
cancelled |
Payment was cancelled by user | Handle cancellation |
expired |
Payment session expired | Create new payment |
LIBPAY sends real-time notifications to your specified IPN URL when payment status changes. This ensures you're immediately notified of payment completions, failures, and other status updates. Webhooks work identically in both sandbox and production environments.
Use the same webhook URL for both sandbox and production. LIBPAY will include environment context in webhook payloads to help you differentiate between test and live transactions.
Header | Description | Example |
---|---|---|
Content-Type |
Always application/json |
application/json |
X-Signature |
HMAC-SHA256 signature for verification | a8b9c2d1e5f3... |
All webhook payloads include environment information to help you differentiate between sandbox and production transactions:
environment
field will be sandbox
for test transactions or production
for live transactions. Transaction IDs are prefixed accordingly (SANDBOX_
or PRODUCTION_
).
{
"data": {
"ref_trx": "TXNT4AQFESTAG4F",
"description": "Order #1234",
"ipn_url": "https://webhook.site/5711b7d5-917a-4d94-bbb3-c28f4a37bea5",
"cancel_redirect": "https://merchant.com/cancel",
"success_redirect": "https://merchant.com/success",
"customer_name": "John Doe",
"customer_email": "john@example.com",
"merchant_name": "Xanthus Wiggins",
"amount": 200,
"currency_code": "USD",
"environment": "production",
"is_sandbox": false
},
"message": "Payment Completed",
"status": "completed",
"timestamp": 1705747245
}
Always verify webhook signatures to ensure authenticity and prevent unauthorized requests. Use your API secret (environment-specific) to verify signatures:
test_webhook_secret
for sandbox and webhook_secret
for production environments.
<?php
// Laravel Webhook Handler
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use App\Enums\EnvironmentMode;
class LIBPAYWebhookController extends Controller
{
public function handle(Request $request)
{
// Get webhook headers
$environment = $request->header('X-Environment', 'production');
$signature = $request->header('X-Signature');
$webhookId = $request->header('X-Webhook-ID');
// Get appropriate secret based on environment
$secret = $this->getSecretForEnvironment($environment);
// Verify signature
if (!$this->verifySignature($request->getContent(), $signature, $secret)) {
Log::warning('LIBPAY webhook signature verification failed', [
'webhook_id' => $webhookId,
'environment' => $environment
]);
return response()->json(['error' => 'Invalid signature'], 401);
}
$payload = $request->json()->all();
// Handle based on environment
if ($environment === EnvironmentMode::SANDBOX->value) {
return $this->handleSandboxWebhook($payload);
} else {
return $this->handleProductionWebhook($payload);
}
}
private function getSecretForEnvironment(string $environment): string
{
// Return test secret for sandbox, live secret for production
return $environment === 'sandbox'
? config('libpay.test_webhook_secret')
: config('libpay.webhook_secret');
}
private function verifySignature(string $payload, string $signature, string $secret): bool
{
$expectedSignature = hash_hmac('sha256', $payload, $secret);
return hash_equals($expectedSignature, $signature);
}
private function handleSandboxWebhook(array $payload): JsonResponse
{
Log::info('Processing sandbox webhook', $payload);
// Your sandbox-specific logic here
// Don't fulfill orders, don't send emails to real customers, etc.
return response()->json(['status' => 'sandbox_processed']);
}
private function handleProductionWebhook(array $payload): JsonResponse
{
Log::info('Processing production webhook', $payload);
// Your production logic here
// Fulfill orders, send confirmation emails, etc.
return response()->json(['status' => 'processed']);
}
}
const crypto = require('crypto');
const express = require('express');
const EnvironmentMode = {
SANDBOX: 'sandbox',
PRODUCTION: 'production'
};
// Webhook handler
app.post('/api/webhooks/libpay', async (req, res) => {
const environment = req.headers['x-environment'] || 'production';
const signature = req.headers['x-signature'];
const webhookId = req.headers['x-webhook-id'];
// Get appropriate secret based on environment
const secret = getSecretForEnvironment(environment);
// Verify signature
if (!verifySignature(JSON.stringify(req.body), signature, secret)) {
console.warn('LIBPAY webhook signature verification failed', {
webhook_id: webhookId,
environment: environment
});
return res.status(401).json({ error: 'Invalid signature' });
}
const payload = req.body;
try {
// Handle based on environment
if (environment === EnvironmentMode.SANDBOX) {
await handleSandboxWebhook(payload);
} else {
await handleProductionWebhook(payload);
}
res.json({ status: 'processed' });
} catch (error) {
console.error('Webhook processing error:', error);
res.status(500).json({ error: 'Processing failed' });
}
});
function getSecretForEnvironment(environment) {
// Return test secret for sandbox, live secret for production
return environment === 'sandbox'
? process.env.LIBPAY_TEST_WEBHOOK_SECRET
: process.env.LIBPAY_WEBHOOK_SECRET;
}
function verifySignature(payload, signature, secret) {
if (!signature) {
return false;
}
const expectedSignature = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(payload)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expectedSignature),
Buffer.from(signature)
);
}
async function handleSandboxWebhook(payload) {
console.log('Processing sandbox webhook:', payload);
// Your sandbox-specific logic here
// Don't fulfill orders, don't send emails to real customers, etc.
}
async function handleProductionWebhook(payload) {
console.log('Processing production webhook:', payload);
// Your production logic here
// Fulfill orders, send confirmation emails, etc.
}
import hmac
import hashlib
import json
import logging
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
logger = logging.getLogger(__name__)
ENVIRONMENT_MODE = {
'SANDBOX': 'sandbox',
'PRODUCTION': 'production'
}
@csrf_exempt
@require_http_methods(["POST"])
def libpay_webhook(request):
environment = request.headers.get('X-Environment', 'production')
signature = request.headers.get('X-Signature', '')
webhook_id = request.headers.get('X-Webhook-ID')
// Get appropriate secret based on environment
secret = get_secret_for_environment(environment)
// Verify signature
if not verify_signature(request.body, signature, secret):
logger.warning('LIBPAY webhook signature verification failed', extra={
'webhook_id': webhook_id,
'environment': environment
})
return JsonResponse({'error': 'Invalid signature'}, status=401)
try:
payload = json.loads(request.body)
// Handle based on environment
if environment == ENVIRONMENT_MODE['SANDBOX']:
handle_sandbox_webhook(payload)
else:
handle_production_webhook(payload)
return JsonResponse({'status': 'processed'})
except Exception as e:
logger.error(f'Webhook processing error:{str(e)}')
return JsonResponse({'error': 'Processing failed'}, status=500)
def get_secret_for_environment(environment):
from django.conf import settings
// Return test secret for sandbox, live secret for production
return (settings.LIBPAY_TEST_WEBHOOK_SECRET
if environment == 'sandbox'
else settings.LIBPAY_WEBHOOK_SECRET)
def verify_signature(payload, signature, secret):
if not signature:
return False
expected_signature = 'sha256=' + hmac.new(
secret.encode('utf-8'),
payload,
hashlib.sha256
).hexdigest()
return hmac.compare_digest(expected_signature, signature)
def handle_sandbox_webhook(payload):
logger.info('Processing sandbox webhook', extra=payload)
// Your sandbox-specific logic here
// Don't fulfill orders, don't send emails to real customers, etc.
def handle_production_webhook(payload):
logger.info('Processing production webhook', extra=payload)
// Your production logic here
// Fulfill orders, send confirmation emails, etc.
Complete integration examples for popular platforms and frameworks.
<?php
// Laravel Integration Service
namespace App\Services;
use Illuminate\Support\Facades\Http;
use Exception;
class LIBPAYService
{
private string $baseUrl;
private string $merchantKey;
private string $apiKey;
private string $environment;
public function __construct()
{
$this->baseUrl = config('libpay.base_url');
$this->merchantKey = config('libpay.merchant_key');
$this->apiKey = config('libpay.api_key');
$this->environment = config('libpay.environment'); // 'sandbox' or 'production'
}
public function initiatePayment(array $paymentData): array
{
try {
$response = Http::withHeaders([
'Content-Type' => 'application/json',
'X-Environment' => $this->environment,
'X-Merchant-Key' => $this->merchantKey,
'X-API-Key' => $this->apiKey,
])->post("{$this->baseUrl}/api/v1/initiate-payment", $paymentData);
if ($response->successful()) {
return $response->json();
}
throw new Exception('LIBPAY API Error: Payment initiation failed');
} catch (Exception $e) {
throw new Exception('LIBPAY API Error: ' . $e->getMessage());
}
}
public function verifyPayment(string $transactionId): array
{
try {
$response = Http::withHeaders([
'Accept' => 'application/json',
'X-Environment' => $this->environment,
'X-Merchant-Key' => $this->merchantKey,
'X-API-Key' => $this->apiKey,
])->get("{$this->baseUrl}/api/v1/verify-payment/{$transactionId}");
if ($response->successful()) {
return $response->json();
}
throw new Exception('LIBPAY API Error: Payment verification failed');
} catch (Exception $e) {
throw new Exception('LIBPAY API Error: ' . $e->getMessage());
}
}
}
// Configuration (config/libpay.php)
return [
'base_url' => env('LIBPAY_BASE_URL', 'https://app.libpay.app'),
'environment' => env('LIBPAY_ENVIRONMENT', 'sandbox'), // sandbox or production
'merchant_key' => env('LIBPAY_MERCHANT_KEY'), // Use appropriate prefix
'api_key' => env('LIBPAY_API_KEY'), // Use appropriate prefix
];
// Usage in Controller
class PaymentController extends Controller
{
public function initiatePayment(Request $request, LIBPAYService $libpay)
{
$paymentData = [
'payment_amount' => $request->amount,
'currency_code' => 'USD',
'ref_trx' => 'ORDER_' . time(),
'description' => $request->description,
'success_redirect' => route('payment.success'),
'failure_url' => route('payment.failed'),
'cancel_redirect' => route('payment.cancelled'),
'ipn_url' => route('webhooks.libpay'),
];
try {
$result = $libpay->initiatePayment($paymentData);
return redirect($result['payment_url']);
} catch (Exception $e) {
return back()->withErrors(['error' => $e->getMessage()]);
}
}
}
// Node.js Integration Service
const axios = require('axios');
class LIBPAYService {
constructor() {
this.baseUrl = process.env.LIBPAY_BASE_URL || 'https://app.libpay.app';
this.environment = process.env.LIBPAY_ENVIRONMENT || 'sandbox'; // sandbox or production
this.merchantKey = process.env.LIBPAY_MERCHANT_KEY; // Use appropriate prefix
this.apiKey = process.env.LIBPAY_API_KEY; // Use appropriate prefix
}
async initiatePayment(paymentData) {
try {
const response = await axios.post(`${this.baseUrl}/api/v1/initiate-payment`, paymentData, {
headers: {
'Content-Type': 'application/json',
'X-Environment': this.environment,
'X-Merchant-Key': this.merchantKey,
'X-API-Key': this.apiKey
}
});
return response.data;
} catch (error) {
throw new Error(`LIBPAY API Error: ${error.message}`);
}
}
async verifyPayment(transactionId) {
try {
const response = await axios.get(`${this.baseUrl}/api/v1/verify-payment/${transactionId}`, {
headers: {
'Accept': 'application/json',
'X-Environment': this.environment,
'X-Merchant-Key': this.merchantKey,
'X-API-Key': this.apiKey
}
});
return response.data;
} catch (error) {
throw new Error(`LIBPAY API Error: ${error.message}`);
}
}
}
// Express.js Route Example
const express = require('express');
const app = express();
const libpay = new LIBPAYService();
app.post('/initiate-payment', async (req, res) => {
const paymentData = {
payment_amount: req.body.amount,
currency_code: 'USD',
ref_trx: `ORDER_${Date.now()}`,
description: req.body.description,
success_redirect: `${req.protocol}://${req.get('host')}/payment/success`,
failure_url: `${req.protocol}://${req.get('host')}/payment/failed`,
cancel_redirect: `${req.protocol}://${req.get('host')}/payment/cancelled`,
ipn_url: `${req.protocol}://${req.get('host')}/webhooks/libpay`,
};
try {
const result = await libpay.initiatePayment(paymentData);
res.redirect(result.payment_url);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
module.exports = LIBPAYService;
# Python/Django Integration Service
import os
import requests
from django.conf import settings
class LIBPAYService:
def __init__(self):
self.base_url = getattr(settings, 'LIBPAY_BASE_URL', 'https://app.libpay.app')
self.environment = getattr(settings, 'LIBPAY_ENVIRONMENT', 'sandbox') # sandbox or production
self.merchant_key = getattr(settings, 'LIBPAY_MERCHANT_KEY') # Use appropriate prefix
self.api_key = getattr(settings, 'LIBPAY_API_KEY') # Use appropriate prefix
def initiate_payment(self, payment_data):
try:
headers = {
'Content-Type': 'application/json',
'X-Environment': self.environment,
'X-Merchant-Key': self.merchant_key,
'X-API-Key': self.api_key
}
response = requests.post(
f"{self.base_url}/api/v1/initiate-payment",
headers=headers,
json=payment_data,
timeout=30
)
response.raise_for_status()
return response.json()
except requests.RequestException as e:
raise Exception(f'LIBPAY API Error: {str(e)}')
def verify_payment(self, transaction_id):
try:
headers = {
'Accept': 'application/json',
'X-Environment': self.environment,
'X-Merchant-Key': self.merchant_key,
'X-API-Key': self.api_key
}
response = requests.get(
f"{self.base_url}/api/v1/verify-payment/{transaction_id}",
headers=headers,
timeout=30
)
response.raise_for_status()
return response.json()
except requests.RequestException as e:
raise Exception(f'LIBPAY API Error: {str(e)}')
# Django Settings Configuration
LIBPAY_BASE_URL = 'https://app.libpay.app'
LIBPAY_ENVIRONMENT = 'sandbox' # Change to 'production' for live
LIBPAY_MERCHANT_KEY = os.environ.get('LIBPAY_MERCHANT_KEY') # Use appropriate prefix
LIBPAY_API_KEY = os.environ.get('LIBPAY_API_KEY') # Use appropriate prefix
# Django View Example
from django.shortcuts import redirect
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
import json
libpay = LIBPAYService()
@csrf_exempt
def initiate_payment(request):
if request.method == 'POST':
data = json.loads(request.body)
payment_data = {
'payment_amount': data['amount'],
'currency_code': 'USD',
'ref_trx': f'ORDER_{int(time.time())}',
'description': data['description'],
'success_redirect': request.build_absolute_uri('/payment/success/'),
'failure_url': request.build_absolute_uri('/payment/failed/'),
'cancel_redirect': request.build_absolute_uri('/payment/cancelled/'),
'ipn_url': request.build_absolute_uri('/webhooks/libpay/'),
}
try:
result = libpay.initiate_payment(payment_data)
return redirect(result['payment_url'])
except Exception as e:
return JsonResponse({'error': str(e)}, status=500)
# Environment Variables Setup
export LIBPAY_ENVIRONMENT="sandbox" # or "production"
export LIBPAY_MERCHANT_KEY="test_merchant_your_key" # or "merchant_your_key" for production
export LIBPAY_API_KEY="test_your_api_key" # or "your_api_key" for production
# Initiate Payment
curl -X POST "https://app.libpay.app/api/v1/initiate-payment" \
-H "Content-Type: application/json" \
-H "X-Environment: $LIBPAY_ENVIRONMENT" \
-H "X-Merchant-Key: $LIBPAY_MERCHANT_KEY" \
-H "X-API-Key: $LIBPAY_API_KEY" \
-d '{
"payment_amount": 250.00,
"currency_code": "USD",
"ref_trx": "ORDER_12345",
"description": "Premium Subscription",
"success_redirect": "https://yoursite.com/payment/success",
"failure_url": "https://yoursite.com/payment/failed",
"cancel_redirect": "https://yoursite.com/payment/cancelled",
"ipn_url": "https://yoursite.com/api/webhooks/libpay"
}'
# Verify Payment
curl -X GET "https://app.libpay.app/api/v1/verify-payment/TXNQ5V8K2L9N3XM1" \
-H "Accept: application/json" \
-H "X-Environment: $LIBPAY_ENVIRONMENT" \
-H "X-Merchant-Key: $LIBPAY_MERCHANT_KEY" \
-H "X-API-Key: $LIBPAY_API_KEY"
# Environment-specific credential examples:
# Sandbox: test_merchant_xxxxx, test_api_key_xxxxx
# Production: merchant_xxxxx, api_key_xxxxx
Advanced LIBPAY payment gateway with modern WooCommerce Blocks support, dynamic branding, and enterprise-grade security features.
Production-ready payment gateway with WooCommerce Blocks (Gutenberg) support, dynamic branding, and secure webhook processing.
Enterprise-grade WooCommerce payment gateway with modern Blocks support and dynamic branding.
Enterprise-grade payment processing with modern architecture
Full Gutenberg checkout compatibility with React-based UI
Auto-fetch logo, colors, and branding from LIBPAY API
HMAC-SHA256 signature verification for payment callbacks
Space-efficient, responsive design for all devices
Multi-header authentication with environment isolation
Seamless sandbox testing with production deployment
Get started with LIBPAY WooCommerce integration in minutes
Download LIBPAY WooCommerce Gateway v2.8.0 from the download section above. This includes all latest features and security updates.
Navigate to Plugins → Add New → Upload Plugin
and select the downloaded ZIP file. The plugin will auto-extract and install.
Activate the plugin and go to WooCommerce → Settings → Payments → LIBPAY
. Enter your API credentials and webhook secret.
Enable Test Mode, process a sandbox transaction to verify Blocks checkout, webhook delivery, and order completion.
Disable test mode, ensure production API keys are configured, and start accepting real payments with full webhook processing.
Essential API settings for secure payment processing
https://app.libpay.app
Your unique merchant credentials from LIBPAY dashboard
RequiredHMAC-SHA256 signature verification for secure callbacks
RecommendedRequired headers for all LIBPAY API requests:
X-Environment: sandbox|production
X-Merchant-Key: your_merchant_id
X-API-Key: your_api_key
Content-Type: application/json
Real-time payment status updates and order processing
https://yoursite.com/wc-api/libpay_webhook
Configure this URL in your LIBPAY merchant dashboard for automatic order updates.
Modern Gutenberg checkout with React-based payment UI
Compact, mobile-optimized payment interface that adapts to any screen size.
Automatically fetches and displays your LIBPAY branding and logos.
Clear SSL and security badges to build customer trust during checkout.
Clear sandbox indicators for testing without affecting live transactions.
Ensure everything is configured correctly before going live
Common issues and solutions for LIBPAY WooCommerce integration
Solutions:
Solutions:
Solutions:
Need assistance with LIBPAY WooCommerce integration? Our technical team provides comprehensive support.
Test LIBPAY API endpoints directly from this documentation. Use the demo credentials below for sandbox testing.
Use these demo credentials to test all payment methods in sandbox environment:
123456789
Password:
demo123
TESTVOUCHER
Auto Success
X-ENVIRONMENT: sandbox
in your API requestssandbox
for testing and production
for live transactions. Only sandbox credentials use test_
prefix, production credentials have no prefix.
Base URL: https://app.libpay.app
Environment Header: X-Environment: sandbox
Credentials: Use test_
prefixed keys
Purpose: Safe testing without real money
Base URL: https://app.libpay.app
Environment Header: X-Environment: production
Credentials: No prefix for production keys
Purpose: Live transactions with real money
LIBPAY API uses conventional HTTP response codes to indicate the success or failure of API requests.
Code | Status | Description |
---|---|---|
200 | OK | Request succeeded |
400 | Bad Request | Invalid request parameters |
401 | Unauthorized | Invalid or missing API credentials |
403 | Forbidden | Insufficient permissions |
404 | Not Found | Resource not found |
429 | Too Many Requests | Rate limit exceeded |
500 | Internal Server Error | Server error occurred |
Error Code | Description | Solution |
---|---|---|
INVALID_CREDENTIALS |
Invalid API credentials provided | Check your Merchant ID and API Key |
INSUFFICIENT_FUNDS |
Customer has insufficient funds | Customer needs to add funds to their wallet |
PAYMENT_DECLINED |
Payment was declined by payment processor | Customer should try a different payment method |
INVALID_AMOUNT |
Payment amount is invalid | Check minimum and maximum amount limits |
INVALID_CURRENCY |
Unsupported currency code | Use a supported currency code (USD, EUR, etc.) |
DUPLICATE_REFERENCE |
Transaction reference already exists | Use a unique transaction reference |
EXPIRED_SESSION |
Payment session has expired | Create a new payment request |
MERCHANT_SUSPENDED |
Merchant account is suspended | Contact LIBPAY support |
{
"success": false,
"message": "Validation failed",
"error_code": "INVALID_AMOUNT",
"errors": {
"payment_amount": [
"The payment amount must be at least 1.00"
]
},
"timestamp": "2024-01-20T10:30:00Z"
}
Get help with your LIBPAY integration from our support team and developer resources.
For API integration help:
Include your Merchant ID and detailed error descriptions for faster resolution.
Contact Support