PHPackages                             payhub/payhub - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Payment Processing](/categories/payments)
4. /
5. payhub/payhub

ActiveLibrary[Payment Processing](/categories/payments)

payhub/payhub
=============

Official PayHub SDK for PHP.

v1.0.0(1mo ago)02↓100%[1 issues](https://github.com/safwatech/payhub-php/issues)MITPHPPHP &gt;=8.1CI passing

Since May 9Pushed 1mo agoCompare

[ Source](https://github.com/safwatech/payhub-php)[ Packagist](https://packagist.org/packages/payhub/payhub)[ Docs](https://payhub.ly)[ RSS](/packages/payhub-payhub/feed)WikiDiscussions main Synced 1w ago

READMEChangelog (1)Dependencies (1)Versions (2)Used By (0)

payhub/payhub — PHP SDK
=======================

[](#payhubpayhub--php-sdk)

Official PayHub SDK for PHP. PHP 8.1+, ext-curl, ext-json. Drop-in for Laravel, Symfony, WordPress (WooCommerce), and plain PSR-7 stacks.

```
composer require payhub/payhub

```

> **PayHub API:** v1 · **PHP:** ≥8.1 · **License:** MIT

1. Authenticate
---------------

[](#1-authenticate)

```
use Payhub\Payhub;

$client = new Payhub(
    apiKey: getenv('PAYHUB_API_KEY'),     // "phk_."
    baseUrl: 'https://app.payhub.ly',
);
```

2. Your first payment — Sadad OTP, end to end
---------------------------------------------

[](#2-your-first-payment--sadad-otp-end-to-end)

```
use Payhub\OtpRequired;

$payment = $client->payments->create([
    'psp' => 'sadad',
    'merchant_order_ref' => 'ord-42',
    'amount_minor' => 4500,                       // 4.5 LYD
    'customer' => [
        'msisdn' => '218910000001',               // mandatory for Sadad
        'birth_year' => 1990,                     // mandatory for Sadad
    ],
]);

if ($payment->nextAction instanceof OtpRequired) {
    echo "OTP sent to {$payment->nextAction->maskedDestination}\n";
}

// Customer types the code into your form; you POST it back.
$settled = $client->payments->confirmOtp($payment->id, '123456');
echo $settled->status;  // "succeeded" or "failed"
```

The SDK auto-mints a UUID4 `Idempotency-Key` for every `create` / `confirmOtp` / `refund`. Pass `idempotencyKey:` to use your own.

3. Webhook receiver (Laravel)
-----------------------------

[](#3-webhook-receiver-laravel)

> ⚠️ **Pass the raw body bytes, never a parsed array.** Re-encoding a JSON body changes whitespace and breaks the HMAC. In Laravel: `$request->getContent()`.

```
use Illuminate\Http\Request;
use Payhub\WebhookEvent;
use Payhub\WebhookSignatureError;

Route::post('/webhooks/payhub', function (Request $request) {
    $sig = $request->header('Hub-Signature');
    if (!$sig) {
        return response('missing signature', 400);
    }
    try {
        $event = WebhookEvent::verify(
            secret: env('PAYHUB_WEBHOOK_SECRET'),  // raw bytes
            body: $request->getContent(),         // raw, not json_decode'd
            header: $sig,
        );
    } catch (WebhookSignatureError $e) {
        return response('invalid signature', 401);
    }

    match ($event->type) {
        'payment.succeeded' => Order::where('id', $event->paymentId)->update(['paid_at' => now()]),
        'payment.failed', 'payment.expired' => /* unlock cart */ null,
        'payment.refunded' => /* update accounting */ null,
        default => null,                          // forward-compat: future event types
    };
    return response('', 200);
});
```

For WooCommerce / WordPress, use `file_get_contents('php://input')` to grab the raw body.

4. Errors
---------

[](#4-errors)

ClassFires on`Payhub\AuthenticationError`401`Payhub\PermissionError`403`Payhub\NotFoundError`404`Payhub\ValidationError`422`Payhub\IdempotencyConflict`409`Payhub\RateLimited`429 — exposes `->retryAfter``Payhub\GatewayError`502 from a `gateway..*` code`Payhub\ServerError`other 5xx`Payhub\TimeoutError`, `Payhub\ConnectionError`, `Payhub\DecodeError`network / serialization`Payhub\WebhookSignatureError` (base)webhook verification→ `MalformedHeader`header missing `t=` or `v1=`→ `TimestampOutOfTolerance``|now − t| > tolerance` (carries `->skewSeconds`)→ `InvalidSignature`HMAC mismatch / non-JSON bodyAPI errors carry `->errorCode`, `->httpStatus`, `->details`, `->requestId`. Log `requestId` to support tickets.

Configuration
-------------

[](#configuration)

```
new Payhub(
    apiKey: 'phk_…',
    baseUrl: 'https://app.payhub.ly',
    timeout: 30.0,
    maxRetries: 2,                   // idempotent calls only
    httpClient: $myCustomHttp,       // implement Payhub\Http\HttpClient
    userAgentSuffix: 'Acme/1.2',
);
```

`HttpClient` is a one-method interface — bridge to Guzzle / Symfony HttpClient by writing a 20-line adapter.

Versioning
----------

[](#versioning)

Independent semver. Compatible with PayHub API v1.

Development
-----------

[](#development)

```
composer install
vendor/bin/phpunit

```

Tests load `../shared/test-vectors/webhook-signing.json` — the canonical spec consumed by every PayHub SDK and by the server's own `tests/unit/test_webhook_signing_vectors.py`.

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance94

Actively maintained with recent releases

Popularity3

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity42

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

32d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/49ef2c3a0ec3b6656127d573df278ceb1e98c02228743f38deb5f51097f4d043?d=identicon)[safwatech](/maintainers/safwatech)

---

Top Contributors

[![akrambazina](https://avatars.githubusercontent.com/u/21319843?v=4)](https://github.com/akrambazina "akrambazina (5 commits)")

---

Tags

paymentssadadPayHublibyamoamalatmobicashtlync

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/payhub-payhub/health.svg)

```
[![Health](https://phpackages.com/badges/payhub-payhub/health.svg)](https://phpackages.com/packages/payhub-payhub)
```

###  Alternatives

[srmklive/paypal

PayPal REST API client for Laravel and standalone PHP.

1.1k4.0M28](/packages/srmklive-paypal)[amzn/amazon-pay-sdk-php

Amazon Pay SDK (PHP)

20612.2M3](/packages/amzn-amazon-pay-sdk-php)[unicodeveloper/laravel-paystack

A Laravel Package for Paystack

6531.0M11](/packages/unicodeveloper-laravel-paystack)[shetabit/payment

Laravel Payment Gateway Integration Package

943336.8k5](/packages/shetabit-payment)[ignited/laravel-omnipay

Integrates Omnipay with Laravel and provides an easy configuration.

5231.1M12](/packages/ignited-laravel-omnipay)[recurly/recurly-client

The PHP client library for the Recurly API

1746.5M8](/packages/recurly-recurly-client)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
