PHP SDK
Official PHP SDK for PayGate.
PHP SDK
The official PHP SDK for PayGate provides a convenient way to access the PayGate API from PHP applications.
Requirements: PHP 8.0 or later. Composer for installation.
Installation
composer require paygate/paygate-phpQuick Start
<?php
require 'vendor/autoload.php';
$paygate = new \PayGate\PayGate('sk_test_...');
// Create a payment
$payment = $paygate->payments->create([
'amount' => 5000,
'currency' => 'GHS',
'payment_method' => 'mobile_money',
'provider' => 'mtn',
'phone' => '0241234567'
]);
echo $payment->id;Configuration
API Key
<?php
// Using environment variable (recommended)
$paygate = new \PayGate\PayGate(getenv('PAYGATE_SECRET_KEY'));
// Or pass directly
$paygate = new \PayGate\PayGate('sk_test_...');Options
<?php
$paygate = new \PayGate\PayGate('sk_test_...', [
// API version (defaults to latest)
'api_version' => '2024-01-01',
// Request timeout in seconds (default: 30)
'timeout' => 60,
// Maximum retries for failed requests (default: 3)
'max_retries' => 5,
// Custom base URL (for testing)
'base_url' => 'https://api.sandbox.paygate.com.gh'
]);Payments
Create a Payment
$payment = $paygate->payments->create([
'amount' => 5000,
'currency' => 'GHS',
'payment_method' => 'mobile_money',
'provider' => 'mtn',
'phone' => '0241234567',
'description' => 'Order #1234',
'metadata' => [
'order_id' => '1234',
'customer_email' => 'customer@example.com'
]
]);Retrieve a Payment
$payment = $paygate->payments->retrieve('pay_abc123');List Payments
// Get a page of payments
$payments = $paygate->payments->list([
'limit' => 10,
'status' => 'succeeded'
]);
foreach ($payments->data as $payment) {
echo $payment->id . "\n";
}
// Check for more pages
if ($payments->has_more) {
$nextPage = $paygate->payments->list([
'limit' => 10,
'starting_after' => $payments->data[count($payments->data) - 1]->id
]);
}Cancel a Payment
$payment = $paygate->payments->cancel('pay_abc123');Customers
Create a Customer
$customer = $paygate->customers->create([
'email' => 'customer@example.com',
'name' => 'John Doe',
'phone' => '0241234567',
'metadata' => ['user_id' => '123']
]);Update a Customer
$customer = $paygate->customers->update('cus_abc123', [
'name' => 'Jane Doe'
]);Delete a Customer
$paygate->customers->delete('cus_abc123');Subscriptions
Create a Subscription
$subscription = $paygate->subscriptions->create([
'customer' => 'cus_abc123',
'plan' => 'plan_xyz789',
'payment_method' => [
'type' => 'mobile_money',
'phone' => '0241234567',
'provider' => 'mtn'
]
]);Cancel a Subscription
// Cancel at period end
$paygate->subscriptions->update('sub_abc123', [
'cancel_at_period_end' => true
]);
// Cancel immediately
$paygate->subscriptions->cancel('sub_abc123');Webhooks
Verify Webhook Signature
<?php
require 'vendor/autoload.php';
$endpointSecret = 'whsec_...';
$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_X_PAYGATE_SIGNATURE'];
try {
$event = \PayGate\Webhook::constructEvent(
$payload,
$signature,
$endpointSecret
);
} catch (\PayGate\Exception\SignatureVerificationException $e) {
http_response_code(400);
echo 'Invalid signature';
exit();
} catch (\Exception $e) {
http_response_code(400);
echo 'Error: ' . $e->getMessage();
exit();
}
// Handle the event
switch ($event->type) {
case 'payment.succeeded':
$payment = $event->data->object;
error_log("Payment {$payment->id} succeeded!");
// Fulfill the order
break;
case 'payment.failed':
$payment = $event->data->object;
error_log("Payment {$payment->id} failed");
// Notify customer
break;
case 'subscription.created':
$subscription = $event->data->object;
// Handle new subscription
break;
default:
error_log("Unhandled event type: {$event->type}");
}
http_response_code(200);
echo json_encode(['received' => true]);Laravel Example
<?php
// routes/web.php
Route::post('/webhooks/paygate', [WebhookController::class, 'handle']);
// app/Http/Controllers/WebhookController.php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use PayGate\Webhook;
use PayGate\Exception\SignatureVerificationException;
class WebhookController extends Controller
{
public function handle(Request $request)
{
$payload = $request->getContent();
$signature = $request->header('X-PayGate-Signature');
$secret = config('services.paygate.webhook_secret');
try {
$event = Webhook::constructEvent($payload, $signature, $secret);
} catch (SignatureVerificationException $e) {
return response('Invalid signature', 400);
}
match ($event->type) {
'payment.succeeded' => $this->handlePaymentSuccess($event->data->object),
'payment.failed' => $this->handlePaymentFailure($event->data->object),
'subscription.created' => $this->handleSubscriptionCreated($event->data->object),
default => null,
};
return response()->json(['received' => true]);
}
private function handlePaymentSuccess($payment)
{
// Fulfill the order
}
private function handlePaymentFailure($payment)
{
// Notify customer
}
private function handleSubscriptionCreated($subscription)
{
// Set up subscription
}
}Error Handling
<?php
use PayGate\PayGate;
use PayGate\Exception\PayGateException;
use PayGate\Exception\AuthenticationException;
use PayGate\Exception\InvalidRequestException;
use PayGate\Exception\PaymentException;
use PayGate\Exception\RateLimitException;
use PayGate\Exception\ApiException;
$paygate = new PayGate('sk_test_...');
try {
$payment = $paygate->payments->create([
'amount' => 5000,
'currency' => 'GHS',
'payment_method' => 'mobile_money',
'provider' => 'mtn',
'phone' => '0241234567'
]);
} catch (AuthenticationException $e) {
// Invalid API key
echo 'Check your API key';
} catch (InvalidRequestException $e) {
// Invalid parameters
echo 'Invalid parameter: ' . $e->getParam();
echo 'Message: ' . $e->getMessage();
} catch (PaymentException $e) {
// Payment-specific error
switch ($e->getErrorCode()) {
case 'insufficient_funds':
echo 'Please top up your account';
break;
case 'phone_unreachable':
echo 'Please check your phone';
break;
default:
echo $e->getMessage();
}
} catch (RateLimitException $e) {
// Too many requests
sleep(60);
// Retry
} catch (ApiException $e) {
// Server error
error_log('PayGate server error: ' . $e->getMessage());
} catch (PayGateException $e) {
// Generic error
echo 'Error: ' . $e->getMessage();
}Error Types
| Exception | Description |
|---|---|
AuthenticationException | Invalid API key |
InvalidRequestException | Invalid parameters |
PaymentException | Payment-specific error |
RateLimitException | Too many requests |
ApiException | Server error |
Idempotency
Use idempotency keys to safely retry requests:
$payment = $paygate->payments->create([
'amount' => 5000,
'currency' => 'GHS',
'payment_method' => 'mobile_money',
'provider' => 'mtn',
'phone' => '0241234567'
], [
'idempotency_key' => 'order_1234_payment'
]);Pagination Helper
// Iterator for all payments
$iterator = $paygate->payments->all(['status' => 'succeeded']);
foreach ($iterator as $payment) {
echo $payment->id . "\n";
}
// Or collect all into an array (be careful with memory)
$allPayments = iterator_to_array($iterator);PSR-18 HTTP Client
The SDK supports any PSR-18 compatible HTTP client:
<?php
use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\Psr7\HttpFactory;
$httpClient = new GuzzleClient();
$requestFactory = new HttpFactory();
$paygate = new \PayGate\PayGate('sk_test_...', [
'http_client' => $httpClient,
'request_factory' => $requestFactory
]);Invoices
Create an Invoice
$invoice = $paygate->invoices->create([
'customer' => 'cus_abc123',
'items' => [
['description' => 'Consulting Services', 'amount' => 50000],
['description' => 'Development Work', 'amount' => 150000]
],
'due_date' => '2024-02-15',
'metadata' => ['project' => 'Website Redesign']
]);Send an Invoice
// Send invoice via email/SMS
$paygate->invoices->send('inv_abc123');Pay an Invoice
$invoice = $paygate->invoices->pay('inv_abc123', [
'payment_method' => [
'type' => 'mobile_money',
'phone' => '0241234567',
'provider' => 'mtn'
]
]);List Invoices
$invoices = $paygate->invoices->list(['status' => 'open', 'limit' => 10]);
foreach ($invoices->data as $invoice) {
echo "{$invoice->id}: " . ($invoice->amount_due / 100) . " {$invoice->currency}\n";
}Coupons
Create a Coupon
// Percentage discount
$coupon = $paygate->coupons->create([
'code' => 'SAVE20',
'type' => 'percent',
'percent_off' => 20,
'duration' => 'repeating',
'duration_in_months' => 3,
'max_redemptions' => 100
]);
// Fixed amount discount
$coupon = $paygate->coupons->create([
'code' => 'FLAT50',
'type' => 'amount',
'amount_off' => 5000, // 50 GHS in pesewas
'currency' => 'GHS',
'duration' => 'once'
]);Validate a Coupon
try {
$validation = $paygate->coupons->validate('SAVE20');
if ($validation->valid) {
echo "Discount: {$validation->percent_off}%\n";
}
} catch (\PayGate\Exception\InvalidRequestException $e) {
echo "Coupon is invalid or expired\n";
}List Coupons
$coupons = $paygate->coupons->list(['limit' => 10]);
foreach ($coupons->data as $coupon) {
echo "{$coupon->code}: {$coupon->times_redeemed}/{$coupon->max_redemptions}\n";
}QR Codes
Create a Static QR Code
// Reusable payment QR code
$qrCode = $paygate->qrCodes->create([
'type' => 'static',
'name' => 'Store Counter QR',
'description' => 'Scan to pay at checkout'
]);
echo "QR Image URL: {$qrCode->image_url}\n";Create a Dynamic QR Code
// QR code for specific payment
$qrCode = $paygate->qrCodes->create([
'type' => 'dynamic',
'amount' => 5000,
'currency' => 'GHS',
'description' => 'Order #1234',
'expires_in' => 3600 // 1 hour
]);
echo "QR Image URL: {$qrCode->image_url}\n";Retrieve QR Code Status
$qrCode = $paygate->qrCodes->retrieve('qr_abc123');
echo "Status: {$qrCode->status}\n";
echo "Times Used: {$qrCode->times_used}\n";Reports
Generate a Report
$report = $paygate->reports->create([
'type' => 'payments_summary',
'parameters' => [
'start_date' => '2024-01-01',
'end_date' => '2024-01-31',
'group_by' => 'day'
],
'format' => 'csv'
]);
echo "Report ID: {$report->id}\n";Retrieve Report Status
do {
$report = $paygate->reports->retrieve('report_abc123');
if ($report->status === 'pending') {
sleep(5);
}
} while ($report->status === 'pending');
if ($report->status === 'ready') {
echo "Download URL: {$report->download_url}\n";
}Available Report Types
$reportTypes = [
'payments_summary',
'payouts_summary',
'settlements',
'disputes',
'customers',
'subscriptions',
'revenue'
];Events
List Events
// Get recent events
$events = $paygate->events->list(['limit' => 20]);
foreach ($events->data as $event) {
echo "{$event->type}: {$event->id}\n";
}
// Filter by type
$paymentEvents = $paygate->events->list([
'type' => 'payment.succeeded',
'limit' => 10
]);Retrieve an Event
$event = $paygate->events->retrieve('evt_abc123');
echo "Type: {$event->type}\n";
print_r($event->data);Event Types
Common event types include:
payment.createdpayment.succeededpayment.failedpayout.createdpayout.succeededcustomer.createdsubscription.createdsubscription.cancelledinvoice.createdinvoice.paiddispute.createddispute.closed
Settings
Settlement Schedule
// Get current settlement schedule
$schedule = $paygate->settings->getSettlementSchedule();
echo "Frequency: {$schedule->frequency}\n";
echo "Day of week: {$schedule->day_of_week}\n";
// Update settlement schedule
$schedule = $paygate->settings->updateSettlementSchedule([
'frequency' => 'weekly',
'day_of_week' => 'friday'
]);Transaction Limits
// Get current limits
$limits = $paygate->settings->getTransactionLimits();
echo "Min: {$limits->min_amount}\n";
echo "Max: {$limits->max_amount}\n";
echo "Daily: {$limits->daily_limit}\n";
// Update limits
$limits = $paygate->settings->updateTransactionLimits([
'min_amount' => 100, // 1 GHS
'max_amount' => 10000000, // 100,000 GHS
'daily_limit' => 50000000 // 500,000 GHS
]);Two-Factor Authentication
Setup 2FA
// Generate 2FA secret and QR code
$setup = $paygate->auth->setup2FA();
echo "Secret: {$setup->secret}\n";
echo "QR Code URL: {$setup->qr_code_url}\n";
// Display QR code to user for scanningEnable 2FA
// Verify and enable 2FA
$result = $paygate->auth->enable2FA([
'code' => '123456' // Code from authenticator app
]);
if ($result->enabled) {
echo "2FA enabled successfully\n";
print_r($result->backup_codes);
}Verify 2FA Code
// Verify a 2FA code
$result = $paygate->auth->verify2FA(['code' => '123456']);
if ($result->valid) {
echo "Code is valid\n";
}Disable 2FA
// Disable 2FA (requires current code)
$paygate->auth->disable2FA(['code' => '123456']);Regenerate Backup Codes
// Get new backup codes
$result = $paygate->auth->regenerateBackupCodes(['code' => '123456']);
print_r($result->backup_codes);