khalti/php-sdk

PHP SDK for Khalti Payment Gateway - Web Checkout (KPG-2) API

Installs: 50

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 1

Forks: 0

Open Issues: 0

pkg:composer/khalti/php-sdk

v1.1.1 2025-03-23 01:45 UTC

This package is auto-updated.

Last update: 2026-01-05 14:50:22 UTC


README

A simple and powerful PHP SDK for integrating Khalti Payment Gateway Web Checkout (KPG-2) API into your PHP applications.

🚀 Quick Start

Installation

composer require khalti/php-sdk

Basic Usage

<?php
require_once 'vendor/autoload.php';

use KhaltiSDK\Khalti;
use KhaltiSDK\Exceptions\ApiException;
use KhaltiSDK\Exceptions\ValidationException;

// Initialize SDK
$khalti = new Khalti([
    'environment' => 'sandbox', // or 'live' for production
    'secretKey' => 'your_secret_key_here',
    'enableLogging' => true
]);

// Initiate Payment
try {
    $response = $khalti->ePayment()->initiate([
        'return_url' => 'https://yoursite.com/success',
        'website_url' => 'https://yoursite.com',
        'amount' => 1000, // 10 NPR in paisa
        'purchase_order_id' => 'ORDER-123',
        'purchase_order_name' => 'Test Product',
        'customer_info' => [
            'name' => 'John Doe',
            'email' => 'john@example.com',
            'phone' => '9800000000'
        ]
    ]);
    
    // Redirect user to payment URL
    header('Location: ' . $response['payment_url']);
    exit;
    
} catch (ValidationException $e) {
    echo "Error: " . $e->getMessage();
} catch (ApiException $e) {
    echo "API Error: " . $e->getMessage();
}

Verify Payment

<?php
// After user returns from payment
$pidx = $_GET['pidx'];

try {
    $result = $khalti->ePayment()->verify($pidx);
    
    if ($result['status'] === 'Completed') {
        echo "Payment successful!";
        // Update your database, send confirmation email, etc.
    } else {
        echo "Payment failed or pending";
    }
    
} catch (Exception $e) {
    echo "Verification failed: " . $e->getMessage();
}

🔧 Configuration

Sandbox Setup

  1. Get Sandbox Credentials:

    • Visit test-admin.khalti.com
    • Sign up for a merchant account
    • Use OTP: 987654 for sandbox login
    • Get your live_secret_key from the dashboard
  2. Update Your Code:

    $khalti = new Khalti([
        'environment' => 'sandbox',
        'secretKey' => 'live_secret_key_from_sandbox_dashboard',
        'enableLogging' => true
    ]);
  3. Test Credentials:

    • Phone: 9800000001
    • MPIN: 1111
    • OTP: 987654

Production Setup

  1. Get Production Credentials:

    • Visit admin.khalti.com
    • Complete merchant verification
    • Get your production live_secret_key
  2. Update Your Code:

    $khalti = new Khalti([
        'environment' => 'live',
        'secretKey' => 'live_secret_key_from_production_dashboard',
        'enableLogging' => false // Disable logging in production
    ]);

📝 Complete Example

Payment Initiation (initiate.php)

<?php
require_once 'vendor/autoload.php';

use KhaltiSDK\Khalti;
use KhaltiSDK\Exceptions\ApiException;
use KhaltiSDK\Exceptions\ValidationException;

$khalti = new Khalti([
    'environment' => 'sandbox',
    'secretKey' => 'your_secret_key_here',
    'enableLogging' => true
]);

if ($_POST) {
    try {
        $response = $khalti->ePayment()->initiate([
            'return_url' => 'http://' . $_SERVER['HTTP_HOST'] . '/verify.php',
            'website_url' => 'http://' . $_SERVER['HTTP_HOST'],
            'amount' => (int)($_POST['amount'] * 100),
            'purchase_order_id' => 'ORDER-' . time(),
            'purchase_order_name' => $_POST['product_name'],
            'customer_info' => [
                'name' => $_POST['customer_name'],
                'email' => $_POST['customer_email'],
                'phone' => $_POST['customer_phone']
            ]
        ]);
        
        header('Location: ' . $response['payment_url']);
        exit;
        
    } catch (Exception $e) {
        $error = $e->getMessage();
    }
}
?>

<!DOCTYPE html>
<html>
<head>
    <title>Khalti Payment</title>
    <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-100 p-8">
    <div class="max-w-md mx-auto bg-white rounded-lg shadow-md p-6">
        <h1 class="text-2xl font-bold mb-6 text-center">Pay with Khalti</h1>
        
        <?php if (isset($error)): ?>
        <div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4">
            <?php echo htmlspecialchars($error); ?>
        </div>
        <?php endif; ?>
        
        <form method="POST">
            <div class="mb-4">
                <label class="block text-gray-700 text-sm font-bold mb-2">Product Name</label>
                <input type="text" name="product_name" value="Test Product" 
                       class="w-full px-3 py-2 border rounded-lg focus:outline-none focus:border-blue-500" required>
            </div>
            
            <div class="mb-4">
                <label class="block text-gray-700 text-sm font-bold mb-2">Amount (NPR)</label>
                <input type="number" name="amount" value="10" min="10" 
                       class="w-full px-3 py-2 border rounded-lg focus:outline-none focus:border-blue-500" required>
            </div>
            
            <div class="mb-4">
                <label class="block text-gray-700 text-sm font-bold mb-2">Customer Name</label>
                <input type="text" name="customer_name" value="John Doe" 
                       class="w-full px-3 py-2 border rounded-lg focus:outline-none focus:border-blue-500" required>
            </div>
            
            <div class="mb-4">
                <label class="block text-gray-700 text-sm font-bold mb-2">Email</label>
                <input type="email" name="customer_email" value="john@example.com" 
                       class="w-full px-3 py-2 border rounded-lg focus:outline-none focus:border-blue-500" required>
            </div>
            
            <div class="mb-6">
                <label class="block text-gray-700 text-sm font-bold mb-2">Phone</label>
                <input type="text" name="customer_phone" value="9800000001" 
                       class="w-full px-3 py-2 border rounded-lg focus:outline-none focus:border-blue-500" required>
            </div>
            
            <button type="submit" 
                    class="w-full bg-purple-600 hover:bg-purple-700 text-white font-bold py-2 px-4 rounded-lg">
                Pay with Khalti
            </button>
        </form>
    </div>
</body>
</html>

Payment Verification (verify.php)

<?php
require_once 'vendor/autoload.php';

use KhaltiSDK\Khalti;
use KhaltiSDK\Exceptions\ApiException;

$khalti = new Khalti([
    'environment' => 'sandbox',
    'secretKey' => 'your_secret_key_here',
    'enableLogging' => true
]);

$pidx = $_GET['pidx'] ?? '';

if ($pidx) {
    try {
        $result = $khalti->ePayment()->verify($pidx);
        
        if ($result['status'] === 'Completed') {
            $message = "Payment successful! Transaction ID: " . $result['transaction_id'];
            $status = 'success';
        } else {
            $message = "Payment status: " . $result['status'];
            $status = 'warning';
        }
        
    } catch (Exception $e) {
        $message = "Verification failed: " . $e->getMessage();
        $status = 'error';
    }
} else {
    $message = "No payment ID provided";
    $status = 'error';
}
?>

<!DOCTYPE html>
<html>
<head>
    <title>Payment Result</title>
    <script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="bg-gray-100 p-8">
    <div class="max-w-md mx-auto bg-white rounded-lg shadow-md p-6">
        <h1 class="text-2xl font-bold mb-6 text-center">Payment Result</h1>
        
        <div class="bg-<?php echo $status === 'success' ? 'green' : ($status === 'warning' ? 'yellow' : 'red'); ?>-100 
                    border border-<?php echo $status === 'success' ? 'green' : ($status === 'warning' ? 'yellow' : 'red'); ?>-400 
                    text-<?php echo $status === 'success' ? 'green' : ($status === 'warning' ? 'yellow' : 'red'); ?>-700 
                    px-4 py-3 rounded mb-4">
            <?php echo htmlspecialchars($message); ?>
        </div>
        
        <div class="text-center">
            <a href="/" class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
                Back to Home
            </a>
        </div>
    </div>
</body>
</html>

🛠️ Advanced Configuration

$khalti = new Khalti([
    'environment' => 'sandbox',
    'secretKey' => 'your_secret_key',
    'publicKey' => 'your_public_key', // Optional
    'enableLogging' => true,
    'logPath' => '/path/to/logs/khalti.log',
    'logLevel' => 'info', // debug, info, warning, error, critical
    'timeout' => 30
]);

📋 API Reference

Payment Initiation

$response = $khalti->ePayment()->initiate([
    'return_url' => 'https://yoursite.com/success',     // Required
    'website_url' => 'https://yoursite.com',            // Required
    'amount' => 1000,                                   // Required (in paisa)
    'purchase_order_id' => 'ORDER-123',                 // Required
    'purchase_order_name' => 'Product Name',            // Required
    'customer_info' => [                                // Optional
        'name' => 'John Doe',
        'email' => 'john@example.com',
        'phone' => '9800000000'
    ],
    'amount_breakdown' => [                             // Optional
        ['label' => 'Product', 'amount' => 900],
        ['label' => 'VAT', 'amount' => 100]
    ],
    'product_details' => [                              // Optional
        [
            'identity' => 'PROD-001',
            'name' => 'Product Name',
            'total_price' => 1000,
            'quantity' => 1,
            'unit_price' => 1000
        ]
    ]
]);

Payment Verification

$result = $khalti->ePayment()->verify($pidx);

// Response:
// [
//     'pidx' => 'payment_id',
//     'total_amount' => 1000,
//     'status' => 'Completed', // Completed, Pending, User canceled, Expired, Refunded
//     'transaction_id' => 'transaction_id',
//     'fee' => 0,
//     'refunded' => false
// ]

🚨 Error Handling

use KhaltiSDK\Exceptions\ValidationException;
use KhaltiSDK\Exceptions\ApiException;
use KhaltiSDK\Exceptions\NetworkException;
use KhaltiSDK\Exceptions\ConfigurationException;

try {
    $response = $khalti->ePayment()->initiate($params);
} catch (ValidationException $e) {
    // Invalid parameters
    echo "Validation Error: " . $e->getMessage();
} catch (ApiException $e) {
    // API error
    echo "API Error: " . $e->getMessage();
} catch (NetworkException $e) {
    // Network error
    echo "Network Error: " . $e->getMessage();
} catch (ConfigurationException $e) {
    // Configuration error
    echo "Configuration Error: " . $e->getMessage();
}

📦 Requirements

  • PHP 7.2 or higher
  • cURL extension
  • JSON extension

📄 License

MIT License - see LICENSE file for details.

🆘 Support

🔄 Changelog

v1.1.1

  • Enhanced validation and error handling
  • Improved documentation
  • Added comprehensive examples
  • Fixed API endpoint compatibility

v1.1.0

  • Initial release with Web Checkout (KPG-2) support
  • Payment initiation and verification
  • Comprehensive error handling
  • Logging support