mohamed-saad/laravel-payment-gateways
Composer 安装命令:
composer require mohamed-saad/laravel-payment-gateways
包简介
Unified Laravel interface for Paymob, MyFatoorah, Tabby and Tamara payment gateways.
README 文档
README
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
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
php artisan vendor:publish --tag=payment-gateways-config php artisan vendor:publish --tag=payment-gateways-migrations php artisan migrate
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
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
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 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 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
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
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
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
- 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.
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 0
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-07-14