Download the PHP package a7my/payment-hub without Composer

On this page you can find all versions of the php package a7my/payment-hub. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package payment-hub

Laravel Payment Hub

A provider-agnostic payment framework for Laravel 10+ / PHP 8.2+, built around the Strategy pattern: switch payment providers via config, not application code. Stripe, Paymob, and MyFatoorah are built in today; PayPal is planned but not yet implemented — see Status below.

Install

No repositories block needed — the package is on Packagist.

Install from GitHub directly (before Packagist, or for unreleased commits) Add to your app's `composer.json`:

Publish config & migrations:

Set provider credentials in .env — see Environment variables below. Never commit real keys; use placeholders in docs and keep secrets in .env only.

Environment variables

Shared:

Stripe — test mode is encoded in the key (sk_test_… / pk_test_…):

Paymob (KSA) — test mode is encoded in the key (sau_sk_test_… / sau_pk_test_…):

MyFatoorah — test mode is the host (apitest vs api-sa), not the key prefix. Use MYFATOORAH_SANDBOX so MyFatoorah can stay live while Stripe/Paymob stay on test keys:

MYFATOORAH_COUNTRY_CODE Live host
SAU https://api-sa.myfatoorah.com
ARE / QAT / EGY api-ae / api-qa / api-eg
KWT / BHR / OMN / JOR https://api.myfatoorah.com

After changing .env: php artisan config:clear.

Driver reference docs

Provider-specific details (webhooks, callbacks, env quirks) live in separate files:

Driver Reference
Stripe STRIPE.md
Paymob PAYMOB.md
MyFatoorah MYFATOORAH.md
Checkout (sdk, confirm, callbacks) CHECKOUT.md

Core concepts

Usage

This is how you call any driver — the calling code below is not Stripe-specific. Every array key, method name, and response method (isSuccessful(), getStatus(), …) is identical no matter which provider is configured; only what happens behind the call differs per provider. Switch providers by changing Payment::driver('…') or PAYMENT_DRIVER in .env — no application code changes required. Stripe, Paymob, and MyFatoorah are built in today (see Status).

Every example below uses $payment from this line.

charge() — take a payment immediately

authorize() / capture() / void() — reserve funds, then settle or release

refund() / partialRefund()

verify() / lookup() — read-only status checks

saveCard() / chargeToken() — save a card, charge it later

Saving a card creates a Stripe Customer behind the scenes (this package has no other way to identify "this card belongs to this Stripe customer" later). Persist getProviderReference() yourself — it's your only way to charge that card again.

provider_customer_reference is required for chargeToken() — Stripe rejects charging a saved payment method under any customer other than the one it was originally attached to, so omitting it throws a clear InvalidArgumentException before any API call is made, rather than a cryptic Stripe error.

createSubscription() / cancelSubscription()

plan_id must be an existing Stripe Price ID (create it once via the Stripe dashboard or API) — this driver does not support ad-hoc/inline subscription pricing, and does not create Products/Prices on your behalf.

createPaymentLink() — hosted checkout page

See the dedicated walkthrough below.

createPaymentLink() walkthrough

createPaymentLink() itself is a generic driver method (same call shape for any provider), but the explanation below of what happens behind it is specifically how Stripe's driver currently implements it (via a Checkout Session) — another provider's driver would generate the hosted page differently internally, even though the call into it looks identical.

What each field does, and what actually happens on Stripe's side:

One thing to fix in the snippet above: return redirect($response->getPaymentUrl()) is correct — it sends an HTTP redirect. If you instead write return $response->getPaymentUrl(); (dropping redirect()), Laravel just returns the URL as plain text in the response body — the browser is never actually redirected anywhere. Keep the redirect() wrapper.

Don't trust return_url alone to mark an order as paid. A customer can reach return_url by hitting the browser back/forward buttons, refreshing, or even guessing the URL, none of which mean they paid. Once webhook handling (processWebhook()) lands in this package, listen for checkout.session.completed there to confirm payment server-side. Until then, use lookup() (via the transaction/session id) to confirm the actual payment status before fulfilling an order — never fulfil directly off of a return_url hit.

Generic checkout endpoint

Everything above requires you to write your own controller/route. This package can also expose a single, ready-to-use checkout endpoint that works against any of your own Eloquent models, with zero routes or controllers of your own — you implement one interface on a model, register it in config, and the endpoint already exists.

1. Implement Payable on your model

total_cents must already be in the smallest currency unit (cents), same as everywhere else in this package. currency_code must be a value Currency::from() accepts (e.g. 'USD', 'EGP') — either a plain string column or store a Currency enum cast, both work.

If your amount isn't a single stored column (e.g. it's computed from related rows), skip the trait and implement getPaymentAmount()/getPaymentCurrency() yourself — they just need to return Money/Currency values, however you get there.

Example — Package with a stored price in major units (SAR):

Optional — snapshot data at checkout time (CapturesCheckoutContext):

Some values only exist during the original POST /payment/checkout call (a locked-in price, a discount code). Implement captureCheckoutContext() to persist them into the pending transaction; read them back in onPaymentCompleted() via $context->get('key') or $context->payer().

See CHECKOUT.md for confirmation flows (callback, webhook, confirm()), and the app-wide CheckoutPaymentConfirmed event.

2. Register it in config

This is a deliberate allowlist, not optional boilerplate — the endpoint never resolves a class from the request directly; only keys registered here are reachable at all. An unregistered model_type gets a 422, not a lookup attempt.

3. Call the endpoint from your frontend

Stripe (webview + web — package handles callback redirect):

Paymob (KSA):

MyFatoorah (Saudi):

The request body shape is identical for every driver — only "driver" changes.

Success response (HTTP 200, webview mode):

Redirect the browser (or open a webview) to checkout_url. Failure responses always look like {"status": "fail", "message": "..."}, with the HTTP status telling you what kind of failure it was: 404 (no such record), 422 (unknown model_type, driver not allowed for this model, invalid driver_type, or a driver that doesn't support the requested driver_type), 403 (authorizePayment() returned false), 502 (the provider API itself failed).

Whichever driver_type you use, createPaymentLink()/createSdkIntent() alone never confirms a payment happened — see CHECKOUT.md for why POST {route}/confirm is a required second step, not an optional extra.

Route configuration

Configured under payment.checkout in step 2 above. Change route if /payment/checkout collides with something in your app, or set enabled to false to register the route yourself. Don't rely on middleware alone — authorizePayment() is always checked by the controller regardless of route middleware.

Events

Every mutating operation dispatches a Laravel event you can listen for — PaymentInitiated, PaymentSucceeded, PaymentFailed, PaymentCaptured, PaymentVoided, PaymentRefunded, CardSaved, TokenCharged, SubscriptionCreated, SubscriptionCancelled, PaymentLinkCreated, TransactionLookuped — each carrying the original request DTO and the resulting response.

Status

This package is under active development. Driver method support, per provider:

Driver charge / authorize / void / capture / refund verify / lookup saveCard / chargeToken subscriptions createPaymentLink sdk checkout webhooks
Stripe ✅ ✅ ✅ ✅ ✅ ✅ ✅
Paymob ✅ ✅ ✅ 🚫 ✅ ✅ ⚠️
MyFatoorah ✅ ✅ 🚫 🚫 ✅ ✅ ⚠️
PayPal — — — — — — planned, not started

✅ implemented and tested · 🚧 not yet implemented (throws until it is) · 🚫 not supported by this provider (throws UnsupportedOperationException) · ⚠️ implemented, but unverified against a real provider signature — see CHECKOUT.md before relying on it in production

Stripe's and Paymob's webhooks both double as the automatic checkout-confirmation trigger — see CHECKOUT.md.

Two things worth knowing about Paymob specifically before relying on it:

MyFatoorah-specific notes:

Publishing (maintainers)

To make composer require a7my/payment-hub work for everyone without a VCS repository block, submit this repo to Packagist:

  1. Public GitHub repo — https://github.com/A7my/payment-hub must be public.
  2. Create a release tag (Packagist needs at least one tag for stable installs):

    Supported frameworks: Laravel 10 / 11 / 12 / 13 (laravel/framework: ^10|^11|^12|^13), PHP ^8.2.

  3. Register on Packagist — sign in at packagist.org with GitHub.
  4. Submit package — paste https://github.com/A7my/payment-hub and confirm.
  5. Enable auto-update — on the package page, set up the GitHub webhook so new tags/commits sync automatically.

After that, anyone can run composer require a7my/payment-hub with no extra config.

License

MIT


All versions of payment-hub with dependencies

PHP Build Version
Package Version
Requires php Version ^8.2
laravel/framework Version ^10.0|^11.0|^12.0|^13.0
stripe/stripe-php Version ^13.0|^14.0|^15.0|^16.0|^17.0|^18.0|^19.0|^20.0
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package a7my/payment-hub contains the following files

Loading the files please wait ...