PHPackages                             mohamed-saad/laravel-payment-gateways - 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. mohamed-saad/laravel-payment-gateways

ActiveLibrary

mohamed-saad/laravel-payment-gateways
=====================================

Unified Laravel interface for Paymob, MyFatoorah, Tabby and Tamara payment gateways.

v1.0.1(1mo ago)07MITPHPPHP ^8.1

Since Jul 14Pushed 1mo agoCompare

[ Source](https://github.com/Mohamed-Saad288/laravel-payment-gateways)[ Packagist](https://packagist.org/packages/mohamed-saad/laravel-payment-gateways)[ RSS](/packages/mohamed-saad-laravel-payment-gateways/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (5)Versions (3)Used By (0)

Laravel Payment Gateways
========================

[](#laravel-payment-gateways)

Laravel package for using multiple payment gateways from one clean API.

Supported gateways:

- Paymob
- MyFatoorah
- Tabby
- Tamara

The package gives you:

- One fluent checkout builder: `Payment::via('gateway')->...->createCheckout()`
- A facade for every gateway: `Paymob`, `MyFatoorah`, `Tabby`, `Tamara`
- Unified response DTOs for checkout, status, refunds, and webhooks
- One webhook route for all gateways: `POST /payment-webhooks/{gateway}`
- Publishable config and migration stubs

Installation
------------

[](#installation)

### 1. Install With Composer

[](#1-install-with-composer)

From your Laravel project root:

```
composer require mohamed-saad/laravel-payment-gateways
```

Laravel auto-discovery registers the service provider and facades automatically. After installation, you can use the package anywhere in your Laravel app through the facades:

```
use MohamedSaad\PaymentGateways\Facades\Payment;
use MohamedSaad\PaymentGateways\Facades\Paymob;
use MohamedSaad\PaymentGateways\Facades\MyFatoorah;
use MohamedSaad\PaymentGateways\Facades\Tabby;
use MohamedSaad\PaymentGateways\Facades\Tamara;
```

### 2. Publish Config And Migration

[](#2-publish-config-and-migration)

```
php artisan vendor:publish --tag=payment-gateways-config
php artisan vendor:publish --tag=payment-gateways-migrations
php artisan migrate
```

### 3. Add Environment Keys

[](#3-add-environment-keys)

```
PAYMENT_GATEWAY_DEFAULT=paymob
PAYMENT_GATEWAY_WEBHOOK_PATH=payment-webhooks

PAYMOB_BASE_URL=https://accept.paymob.com
PAYMOB_SECRET_KEY=
PAYMOB_PUBLIC_KEY=
PAYMOB_PAYMENT_METHODS=card
PAYMOB_HMAC_SECRET=

MYFATOORAH_API_KEY=
MYFATOORAH_COUNTRY=SA
MYFATOORAH_TEST_MODE=true
MYFATOORAH_NOTIFICATION_OPTION=LNK

TABBY_SECRET_KEY=
TABBY_PUBLIC_KEY=
TABBY_MERCHANT_CODE=
TABBY_BASE_URL=https://api.tabby.ai

TAMARA_API_TOKEN=
TAMARA_NOTIFICATION_TOKEN=
TAMARA_BASE_URL=https://api-sandbox.tamara.co
```

Paymob base URLs by country:

```
# Egypt
PAYMOB_BASE_URL=https://accept.paymob.com

# Oman
PAYMOB_BASE_URL=https://oman.paymob.com

# Saudi Arabia
PAYMOB_BASE_URL=https://ksa.paymob.com

# UAE
PAYMOB_BASE_URL=https://uae.paymob.com
```

Use `https://api.tabby.sa` for Tabby KSA production. Use Tamara production URL when your Tamara account is live.

Basic Usage
-----------

[](#basic-usage)

Use the generic facade when the gateway is dynamic:

```
use MohamedSaad\PaymentGateways\Facades\Payment;

$checkout = Payment::via('tabby')
    ->amount(150)
    ->currency('SAR')
    ->customer([
        'name' => 'Mona Lisa',
        'email' => 'customer@email.com',
        'phone' => '566027755',
    ])
    ->items([
        [
            'name' => 'Lego City 8601',
            'quantity' => 1,
            'unit_amount' => 150,
            'category' => 'Toys',
        ],
    ])
    ->callback(
        route('payment.success'),
        route('payment.cancel'),
        route('payment.failure')
    )
    ->orderReference('ORDER-1001')
    ->createCheckout();

return redirect($checkout->url);
```

Or use the direct gateway facade:

```
use MohamedSaad\PaymentGateways\Facades\Tamara;

$checkout = Tamara::amount(300)
    ->currency('SAR')
    ->customer($user)
    ->items($items)
    ->callback(route('payment.success'), route('payment.cancel'), route('payment.failure'))
    ->orderReference($order->id)
    ->createCheckout();
```

Gateway Examples
----------------

[](#gateway-examples)

### Paymob

[](#paymob)

Paymob flow: create an intention, receive a `client_secret`, then redirect to Paymob Unified Checkout.

```
use MohamedSaad\PaymentGateways\Facades\Paymob;

$checkout = Paymob::amount(500)
    ->currency('EGP')
    ->customer([
        'name' => 'Ahmed Ali',
        'email' => 'ahmed@example.com',
        'phone' => '01000000000',
    ])
    ->callback(
        route('payment.success'),
        route('payment.cancel'),
        route('payment.failure')
    )
    ->items([
        [
            'name' => 'Order items',
            'quantity' => 1,
            'unit_amount' => 500,
        ],
    ])
    ->orderReference('PAYMOB-ORDER-1001')
    ->meta([
        'payment_methods' => ['card'], // or integration IDs like [1256]
        'notification_url' => 'https://your-domain.com/payment-webhooks/paymob',
        'billing_data' => [
            'city' => 'Cairo',
            'country' => 'EG',
            'street' => 'NA',
        ],
    ])
    ->createCheckout();

return redirect($checkout->url);
```

Important Paymob values:

```
$checkout->checkoutId;    // Paymob intention id
$checkout->referenceCode; // Paymob order id / intention_order_id
$checkout->url;           // Unified Checkout URL
$checkout->raw;           // Full Paymob intention response, including client_secret
```

Paymob callbacks are sent to `notification_url`. Add this URL in the intention payload or in your dashboard:

```
https://your-domain.com/payment-webhooks/paymob

```

For old Paymob transaction inquiry/refund endpoints, also set the legacy API key:

```
PAYMOB_API_KEY=
```

### MyFatoorah

[](#myfatoorah)

MyFatoorah flow: send payment, redirect customer to invoice URL, then verify invoice status.

```
use MohamedSaad\PaymentGateways\Facades\MyFatoorah;

$checkout = MyFatoorah::amount(250)
    ->currency('SAR')
    ->customer([
        'name' => 'Mona Lisa',
        'email' => 'mona@example.com',
        'phone' => '0500000000',
    ])
    ->callback(
        route('payment.success'),
        route('payment.cancel'),
        route('payment.failure')
    )
    ->items([
        [
            'name' => 'Order items',
            'quantity' => 1,
            'unit_amount' => 250,
        ],
    ])
    ->orderReference('MYFATOORAH-ORDER-1001')
    ->meta([
        'notification_option' => 'LNK',
        'language' => 'en',
        'webhook_url' => 'https://your-domain.com/payment-webhooks/myfatoorah',
    ])
    ->createCheckout();

return redirect($checkout->url);
```

Verify payment:

```
$status = MyFatoorah::verifyPayment($invoiceId);
```

Refund:

```
$refund = MyFatoorah::refund($paymentId, 50);
```

Callback URL:

```
https://your-domain.com/payment-webhooks/myfatoorah

```

### Tabby

[](#tabby)

Tabby checkout endpoint:

```
POST https://api.tabby.ai/api/v2/checkout

```

Example:

```
use MohamedSaad\PaymentGateways\Facades\Tabby;

$checkout = Tabby::amount(100)
    ->currency('AED')
    ->customer([
        'name' => 'John Doe',
        'email' => 'jsmith@example.com',
        'phone' => '500000001',
    ])
    ->items([
        [
            'title' => 'Name of the product',
            'quantity' => 1,
            'unit_price' => '100.00',
            'category' => 'Clothes',
            'reference_id' => 'SKU123',
            'description' => 'Description of the product',
            'image_url' => 'https://example.com/image.jpg',
            'product_url' => 'https://example.com/product',
            'brand' => 'Brand Name',
            'is_refundable' => true,
        ],
    ])
    ->callback(
        'https://your-store/success',
        'https://your-store/cancel',
        'https://your-store/failure'
    )
    ->orderReference('TABBY-ORDER-1001')
    ->meta([
        'lang' => 'en',
        'buyer_dob' => '2000-01-20',
        'shipping_address' => [
            'city' => 'Dubai',
            'address' => 'Dubai',
            'zip' => '1111',
        ],
        'buyer_history' => [
            'registered_since' => now()->subYear()->toIso8601String(),
            'loyalty_level' => 2,
        ],
        'order_history' => [],
    ])
    ->createCheckout();

return redirect($checkout->url);
```

Important Tabby values:

```
$checkout->checkoutId;    // Tabby session id
$checkout->referenceCode; // Tabby payment id, save this
$checkout->url;           // Redirect URL
```

Verify, capture, and refund:

```
$status = Tabby::verifyPayment($paymentId);
$captured = Tabby::capture($paymentId, 100);
$refund = Tabby::refund($paymentId, 50);
```

Register Tabby webhook:

```
Tabby::registerWebhook(
    'https://your-domain.com/payment-webhooks/tabby',
    [
        'title' => 'X-Webhook-Token',
        'value' => 'your-random-webhook-token',
    ]
);
```

Tabby registers webhooks per `merchant_code` and per environment. A test secret key registers test webhooks, and a live secret key registers production webhooks.

More details: [Tabby README](docs/gateways/tabby/README.md)

### Tamara

[](#tamara)

Tamara checkout endpoint:

```
POST https://{environment}.tamara.co/checkout

```

Sandbox example:

```
POST https://api-sandbox.tamara.co/checkout

```

Example:

```
use MohamedSaad\PaymentGateways\Facades\Tamara;

$checkout = Tamara::amount(300)
    ->currency('SAR')
    ->customer([
        'name' => 'Mona Lisa',
        'email' => 'customer@email.com',
        'phone' => '566027755',
    ])
    ->items([
        [
            'name' => 'Lego City 8601',
            'type' => 'Digital',
            'reference_id' => '123',
            'sku' => 'SA-12436',
            'quantity' => 1,
            'unit_amount' => 490,
            'discount_amount' => ['amount' => 100, 'currency' => 'SAR'],
            'tax_amount' => ['amount' => 10, 'currency' => 'SAR'],
            'item_url' => 'https://item-url.com/1234',
            'image_url' => 'https://image-url.com/1234',
        ],
    ])
    ->callback(
        'http://example.com/#/success',
        'http://example.com/#/cancel',
        'http://example.com/#/fail'
    )
    ->orderReference('abd12331-a123-1234-4567-fbde34ae')
    ->meta([
        'order_number' => 'A123125',
        'shipping_amount' => ['amount' => 1, 'currency' => 'SAR'],
        'tax_amount' => ['amount' => 1, 'currency' => 'SAR'],
        'discount' => [
            'amount' => ['amount' => 0, 'currency' => 'SAR'],
        ],
        'country_code' => 'SA',
        'description' => 'Enter order description here.',
        'billing_address' => [
            'city' => 'Riyadh',
            'country_code' => 'SA',
            'first_name' => 'Mona',
            'last_name' => 'Lisa',
            'line1' => '3764 Al Urubah Rd',
            'line2' => 'string',
            'phone_number' => '532298658',
            'region' => 'As Sulimaniyah',
        ],
        'shipping_address' => [
            'city' => 'Riyadh',
            'country_code' => 'SA',
            'first_name' => 'Mona',
            'last_name' => 'Lisa',
            'line1' => '3764 Al Urubah Rd',
            'line2' => 'string',
            'phone_number' => '532298658',
            'region' => 'As Sulimaniyah',
        ],
        'platform' => 'Laravel',
        'is_mobile' => false,
        'locale' => 'ar_SA',
        'risk_assessment' => [
            'customer_age' => 21,
            'customer_dob' => '01-12-2000',
            'customer_gender' => 'Female',
            'customer_nationality' => 'SA',
            'is_premium_customer' => false,
            'is_existing_customer' => false,
            'is_guest_user' => false,
        ],
        'additional_data' => [
            'delivery_method' => 'Home Delivery',
            'pickup_store' => 'Store A',
            'store_code' => 'Branch A',
        ],
    ])
    ->createCheckout();

return redirect($checkout->url);
```

Important Tamara values:

```
$checkout->checkoutId;    // Tamara checkout_id
$checkout->referenceCode; // Tamara order_id
$checkout->url;           // Redirect URL
```

Verify, authorise, and refund:

```
$status = Tamara::verifyPayment($orderId);
$authorised = Tamara::authorise($orderId);
$refund = Tamara::refund($orderId, 50);
```

Register Tamara webhook:

```
Tamara::registerWebhook([
    'type' => 'order',
    'events' => [
        'order_approved',
        'order_authorised',
        'order_canceled',
        'order_updated',
        'order_captured',
        'order_refunded',
    ],
    'url' => 'https://your-domain.com/payment-webhooks/tamara',
    'headers' => [
        'authorization' => 'your-webhook-authorization-token',
    ],
]);
```

You can also add the webhook URL manually in the Tamara dashboard:

```
https://your-domain.com/payment-webhooks/tamara

```

More details: [Tamara README](docs/gateways/tamara/README.md)

Webhooks
--------

[](#webhooks)

The package registers one route:

```
POST /payment-webhooks/{gateway}

```

Examples:

```
POST /payment-webhooks/paymob
POST /payment-webhooks/myfatoorah
POST /payment-webhooks/tabby
POST /payment-webhooks/tamara

```

Listen for payment status changes:

```
use Illuminate\Support\Facades\Event;
use MohamedSaad\PaymentGateways\Events\PaymentStatusChanged;

Event::listen(PaymentStatusChanged::class, function (PaymentStatusChanged $event) {
    $event->result->gateway;
    $event->result->transactionId;
    $event->result->status;
    $event->result->signatureValid;
});
```

Response DTOs
-------------

[](#response-dtos)

Checkout returns `CheckoutResponseDTO`:

```
$checkout->gateway;
$checkout->checkoutId;
$checkout->url;
$checkout->referenceCode;
$checkout->raw;
```

Payment status returns `PaymentStatusDTO`:

```
$status->gateway;
$status->transactionId;
$status->status;
$status->amount;
$status->currency;
$status->raw;
```

Refund returns `RefundResponseDTO`:

```
$refund->gateway;
$refund->refundId;
$refund->amount;
$refund->successful;
$refund->raw;
```

Notes
-----

[](#notes)

- BNPL gateways need item, customer, address, and history data for scoring.
- Tabby usually needs capture after authorization: `Tabby::capture($paymentId, $amount)`.
- Tamara usually needs authorise before settlement: `Tamara::authorise($orderId)`.
- Always save the gateway checkout/payment/order IDs returned in `$checkout->raw`.
- Test all gateways with sandbox credentials before production.

###  Health Score

38

—

LowBetter than 83% of packages

Maintenance90

Actively maintained with recent releases

Popularity6

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity43

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

Every ~0 days

Total

2

Last Release

48d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/131921827?v=4)[Mohamed Saad](/maintainers/Mohamed-Saad288)[@Mohamed-Saad288](https://github.com/Mohamed-Saad288)

---

Top Contributors

[![Mohamed-Saad288](https://avatars.githubusercontent.com/u/131921827?v=4)](https://github.com/Mohamed-Saad288 "Mohamed-Saad288 (2 commits)")

---

Tags

laravelpaymentsmyfatoorahtamarabnplpaymobtabby

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/mohamed-saad-laravel-payment-gateways/health.svg)

```
[![Health](https://phpackages.com/badges/mohamed-saad-laravel-payment-gateways/health.svg)](https://phpackages.com/packages/mohamed-saad-laravel-payment-gateways)
```

###  Alternatives

[laravel/socialite

Laravel wrapper around OAuth 1 &amp; OAuth 2 libraries.

5.7k118.2M1.0k](/packages/laravel-socialite)[psalm/plugin-laravel

Psalm plugin for Laravel

3365.5M359](/packages/psalm-plugin-laravel)[simplestats-io/laravel-client

Server-side analytics for Laravel that follows the full funnel from visit to registration to payment, attributed to the channel that drove it. Revenue, MRR, churn and ad-spend profit (ROAS/CAC) per channel. GDPR compliant, ad-blocker proof.

5226.7k](/packages/simplestats-io-laravel-client)[fleetbase/core-api

Core Framework and Resources for Fleetbase API

1346.4k29](/packages/fleetbase-core-api)[api-platform/laravel

API Platform support for Laravel

58190.1k22](/packages/api-platform-laravel)[jasara/php-amzn-selling-partner-api

A fluent interface for Amazon's Selling Partner API in PHP

1349.6k1](/packages/jasara-php-amzn-selling-partner-api)

PHPackages © 2026

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