Download the PHP package damms005/laravel-cashier without Composer

On this page you can find all versions of the php package damms005/laravel-cashier. 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 laravel-cashier

Laravel Multipay 💸

Art image for laravel-multipay

GitHub GitHub tag (with filter) Total Downloads GitHub Workflow Status (with event)

An opinionated Laravel package to handle payments, complete with blade views, routing, and everything in-between.

Whether you want to quickly bootstrap payment processing for your Laravel applications, or you want a way to test supported payment processors, this package's got you!

Although opinionated, this package allows you to "theme" the views. It achieves this theming by @extend()ing whatever view you specify in config('laravel-multipay.extended_layout') (defaults to layout.app).

Requirements:

This package is tested against:

Currently supported payment handlers

Currently, this package supports the following online payment processors/handlers

[!NOTE] key: ** for the indicated providers, a few features may be missing. PRs welcomed if you cannot afford the wait 😉

[!TIP] Your preferred payment handler is not yet supported? Please consider opening the appropriate issue type.

[!TIP] Adding a new payment handler is straight-forward. Simply add a class that extends Damms005\LaravelMultipay\Services\PaymentHandlers\BasePaymentHandler and implement Damms005\LaravelMultipay\Contracts\PaymentHandlerInterface

[!NOTE] Payment providers that you so register as described above are resolvable from the Laravel Container to improve the flexibility of this package and improve DX.

Installation

Publish the config file.

Run migrations.

Demo Repo

I published an open source app that uses this payment package. It is also an excellent example of a Laravel app that uses Laravel Vite and leverages on Laravel Echo to provide realtime experience via public and private channels using Laravel Websocket, powered by Livewire.

Test drive 🚀

Want to take things for a spin? Visit /payment/test-drive (route('payment.test-drive') provided by this package) . For Paystack, ensure to set paystack_secret_key key in the laravel-multipay.php config file that you published previously at installation. You can get your key from your settings page.

Warning
Ensure you have TailwindCSS installed, then add this package's views to the content key of your tailwind.config.js configuration file, like below:

Needed Third-party Integrations:

The PAYSTACK_TERMINAL_ID is only required if you intend to use Paystack Terminal for payment processing.

PAYSTACK_RECURRING_CHANNELS (default card,bank) sets the channels offered on checkouts that must stay chargeable. See Channels that can be charged again.

See the Bachs section below for the required API-key scopes and product-cache options.

See the Polar section below for auth, amount format, and webhook verification.

See the Moniepoint (Monnify) section below for recurring collection, mandates, and webhook verification.

For most of the above environment variables, you should rather use the (published) config file to set the corresponding values.

Usage

Typical process-flow

Step 1

Send a POST request to /payment/details/confirm (route('payment.show_transaction_details_for_user_confirmation') provided by this package).

Check the test-drive/pay.blade.php).

This POST request will typically be made by submitting a form from your frontend to the route described above.

[!NOTE] if you need to store additional/contextual data with this payment, you can include such data in the request, in a field named metadata. The value must be a valid JSON string.

Step 2

Upon user confirmation of transaction, user is redirected to the appropriate payment handler's gateway.

Step 3

When user is done with the transaction on the payment handler's end (either successfully paid, or declined transaction), user is redirected back to /payment/completed (route('payment.finished.callback_url') provided by this package) .

Metadata Usage

In the payment initiation request in Step 1, you can provide a metadata field. This field is stored in the metadata column of the payments table, and available as AsArrayObject::class property of the Payment model and it provides powerful customization options for individual payments.

The metadata should be a valid JSON string containing key-value pairs that modify payment behavior.

Available Metadata Keys

completion_url

payment_processor

split_code (Paystack only)

additional_payment_payload (Paystack only)

channels (Paystack only)

requires_reusable_authorization

Subscriptions (Recurring Payments)

This package provides built-in support for subscription-based recurring payments via the SubscriptionService class.

Supported Handlers

Handler Create plan Subscribe Pause / Cancel / Resume
Paystack ✅ ✅ ✅
Bachs ✅ ✅ Cancel only (no resume)
Polar ✅ ✅ ✅
Flutterwave ✅ ✅ —
Monnify — — —

Pause/cancel/resume requires the handler to implement the ManagesSubscriptions contract. Paystack, Bachs, and Polar do; calling the management methods with an unsupported handler throws a SubscriptionManagementException.

Monnify has no server-side plans or subscriptions, so SubscriptionService does not apply to it — createPaymentPlan() and subscribeToPlan() throw with a message pointing at the right API. Recurring collection on Monnify is merchant-scheduled: your application owns the renewal clock and charges a mandate or a stored card token when a period falls due. See Moniepoint (Monnify).

Channels that can be charged again

A subscription is only as good as the instrument behind it. Paystack renews a subscription from a card authorization or a Nigerian direct debit mandate only; a first payment made by transfer, USSD or a wallet channel succeeds but leaves nothing the provider can charge when the next period falls due. Monnify can only charge again from a stored card token.

The package applies that rule for you:

Situation Paystack channels offered Monnify methods offered
SubscriptionService::subscribeToPlan() (a plan is always recurring) card, bank + direct debit filter —
Payment metadata carries requires_reusable_authorization card, bank + direct debit filter CARD
Ordinary one-off payment Every channel enabled on the account Every method

When bank is among the channels, Paystack is also sent metadata.custom_filters.recurring = true, so the payer only sees banks that support Direct Debit and the checkout creates a mandate rather than a one-off debit.

Flag a non-plan payment like this:

Channels you request yourself are narrowed, never widened: asking for ['card', 'ussd'] on such a payment yields ['card']. Change the allow-list with the PAYSTACK_RECURRING_CHANNELS environment variable, or the paystack_recurring_channels config key:

Direct debit is a Nigeria-only Paystack feature, so accounts outside Nigeria should set the list to card.

Creating a Payment Plan

Before subscribing users, create a payment plan:

This registers the plan with the payment provider and stores it locally in the payment_plans table.

If a plan with the same amount, interval, and currency already exists for the handler, use findOrCreatePaymentPlan to avoid duplicates:

Subscribing a User to a Plan

This redirects the user to the payment gateway. Upon successful payment, a Subscription record is created automatically with the appropriate next_payment_due_date.

You can optionally provide a custom transaction reference and additional metadata:

Checking Active Subscriptions

A subscription is considered active if its status is active and its next_payment_due_date is in the future. Paused and cancelled subscriptions are excluded.

Managing Subscriptions (Pause, Cancel, Resume)

Subscriptions can be paused (temporarily suspended, intended to be resumed later), cancelled (permanently stopped), or resumed. Under the hood, both pause and cancel call the provider's "disable" endpoint so the subscription stops renewing; the difference between them is intent, tracked locally via the status column. Resume calls the provider's "enable" endpoint.

Capturing the provider's subscription code and token

To manage a subscription you need the provider's subscription code and email token. For Paystack these are delivered on the subscription.create webhook (data.subscription_code and data.email_token) shortly after the first successful charge on a plan. Persist them onto the local Subscription with recordProviderSubscriptionData():

If you did not capture them at creation time, you can retrieve them from the provider (Paystack) via the handler:

Pause, cancel, resume

Each method calls the provider, updates the local status, and returns the refreshed Subscription. They throw SubscriptionManagementException when:

Provider-side failures (e.g. an invalid subscription code) bubble up as an Exception carrying the provider's message.

Changing Subscription Seat Count (Quantity)

Handlers that can change the seat count (line-item quantity) on an active subscription implement the SupportsSubscriptionQuantity capability contract. Feature-check before you call, so unsupported providers degrade gracefully rather than throw:

Provider matrix:

Provider supports() Mechanism
Polar true Native. PATCH /v1/subscriptions/{id} with a seats field; the subscription code stays the same. Generic proration maps to Polar values (create_prorations → prorate, none → next_period).
Paystack true Shim. Disables the current subscription, creates a new Plan at unit_amount × newQuantity, and creates a fresh subscription on the same customer authorization. Returns replacedPreviousCode=true and dispatches SubscriptionCodeReplaced — listen for it to migrate any local FK. Paystack cannot prorate; the new subscription's first charge is a full period.
Bachs false Not supported. Bachs exposes no quantity-change endpoint and cancellation is irreversible. changeSubscriptionQuantity() throws UnsupportedOperationException; fall back to a fresh checkout for the additional seat.

The local Subscription model has a nullable quantity column that consumers should keep in sync with the provider (Polar's subscription.updated webhook is wired to do this automatically when it carries a seats value).

Models

PaymentPlan — represents a recurring billing plan:

Column Description
name Unique plan name
amount Billing amount
interval monthly or yearly
description Human-readable description
currency Currency code (e.g., NGN)
payment_handler_fqcn Payment handler class name
payment_handler_plan_id Plan ID from the payment provider

Subscription — represents a user's subscription to a plan:

Column Description
user_id The subscribed user
payment_plan_id FK to payment_plans
next_payment_due_date When the next payment is due
metadata Optional JSON metadata
payment_handler_subscription_code Provider's subscription code (required to manage it)
payment_handler_email_token Provider's email token (required to manage it)
status active, paused, or cancelled

On successful payment, SuccessfulLaravelMultipayPaymentEvent is fired — listen for this to run any domain-specific logic.

Payment Conflict Resolution (PCR)

If for any reason, your user/customer claims that the payment they made was successful but that your platform did not reflect such successful payment, this PCR feature enables you to resolve such claims by simply calling:

The payment will be re-resolved and the payment will be updated in the database. If the payment is successful, the SuccessfulLaravelMultipayPaymentEvent event will be fired, so you can run any domain/application-specific procedures.

Webhook Payment Notifications (optional)

One of the benefits of this package is to remove the need for you to have to deal with payment webhooks. Depending on your needs, the event handling may suffice for your use case.

If you need webhook notifications from payment providers, use the webhook endpoint provided by this package: route('payment.external-webhook-endpoint').

If you use this payment notification URL feature, ensure that in the handler for SuccessfulLaravelMultipayPaymentEvent, you have not previously handled the event for that same payment.

Webhook origin verification

The endpoint is public, so every handler that receives provider webhooks verifies that the payload really came from that provider before acting on it. Verification uses the credential you already configured for the provider — there is nothing extra to set up.

Provider Header Digest
Paystack x-paystack-signature HMAC SHA512 of the raw body, keyed with PAYSTACK_SECRET_KEY
Moniepoint (Monnify) monnify-signature HMAC SHA512 of the raw body, keyed with MONNIFY_SECRET_KEY
Bachs X-Bachs-Signature (with X-Bachs-Timestamp) keyed with BACHS_WEBHOOK_SIGNING_SECRET
Polar webhook-signature (with webhook-id, webhook-timestamp) keyed with POLAR_WEBHOOK_SECRET

Bachs and Polar also send a timestamp and are rejected outside a five-minute window. Paystack and Monnify sign the body only, so their signatures carry no replay window.

A single endpoint serves every provider, so the handlers distinguish two failure modes:

That second case is what catches a stale or swapped key: after you move to a new provider account, webhooks still in flight from the old one no longer verify and are refused rather than silently applied.

Because the digest is taken over the raw request body, any middleware that re-encodes the body before the handler sees it will break verification.

Events

SuccessfulLaravelMultipayPaymentEvent

If there are additional steps you want to take upon successful payment, listen for SuccessfulLaravelMultipayPaymentEvent. This event will be fired whenever a successful payment occurs, with its corresponding Payment model.

Webhook Push Notifications

When a payment succeeds, this package can automatically send a webhook to an external system (e.g. a financial tracking service). This uses spatie/laravel-webhook-server under the hood.

Setup

  1. Install the webhook server package:

  2. Set the webhook URL and signing secret in your .env:

  3. Create a class that implements Damms005\LaravelMultipay\Contracts\WebhookPayloadPackager:

  4. Register your packager in a service provider:

Once configured, every SuccessfulLaravelMultipayPaymentEvent will trigger a signed webhook POST to the configured URL with the payload returned by your packager.

Backfilling Existing Payments

To send existing successful payments to the webhook endpoint:

Options:

The command fail-fast aborts after 3 consecutive batch failures.

Provider-specific notes

The sections below cover setup and behavior specific to individual providers. See the Currently supported payment handlers list for the full set.

Bachs

Bachs supports one-off payments, subscriptions, subscription management, and webhooks.

Environment / config

All of the above are also exposed under the bachs key of the published config file.

Required API-key scopes

The secret key must have these scopes:

Amounts

Bachs amounts are decimal strings with an ISO currency (e.g. "75000.00" / "USD"). Do not pass minor units.

Products

Bachs bills a checkout against a fixed-price product. You can supply a bachs_product_id in the payment metadata to bill against a specific product, or omit it to have the handler find-or-create one from the transaction details. Resolved product ids are cached per BACHS_PRODUCT_CACHE_*.

Webhooks

Point your Bachs webhook endpoint at route('payment.external-webhook-endpoint'). Requests are verified via the X-Bachs-Timestamp and X-Bachs-Signature (HMAC-SHA256) headers with a 300s timestamp tolerance. Handled events: collection.succeeded, collection.failed, customer.subscription.created, and invoice.paid.

Subscriptions

Bachs supports create, subscribe, and cancel, but not resume. To reactivate a customer, create a new subscription. See Managing Subscriptions.

Polar

Polar supports one-off payments, subscriptions, subscription management, and webhooks.

Environment / config

All of the above are also exposed under the polar key of the published config file.

The base URL is derived from POLAR_SERVER: sandbox → https://sandbox-api.polar.sh, production → https://api.polar.sh. Set POLAR_BASE_URL to override.

Authentication

Auth uses a Bearer Organization Access Token (Authorization: Bearer polar_oat_…), set via POLAR_ACCESS_TOKEN.

Amounts

Polar amounts are integer minor units (cents) with a lowercase ISO currency ("usd"). Do not pass decimal amounts.

Products

Polar bills a checkout against a fixed-price product. You can supply a polar_product_id in the payment metadata to bill against a specific product, or omit it to have the handler find-or-create one from the transaction details. Resolved product ids are cached per POLAR_PRODUCT_CACHE_*.

Webhooks

Point your Polar webhook endpoint at route('payment.external-webhook-endpoint'). Requests are verified per the Standard Webhooks spec using the webhook-id, webhook-timestamp, and webhook-signature headers with a 300s timestamp tolerance. Handled events: order.paid, order.refunded, subscription.created/active/uncanceled/resumed, and subscription.canceled/revoked/paused.

Subscriptions

Polar supports create, subscribe, cancel, and resume. See Managing Subscriptions.

Moniepoint (Monnify)

Moniepoint collects online payments through its gateway, Monnify. The handler supports one-off payments, direct debit mandates, stored card tokens, and webhooks. It does not support server-side payment plans or subscriptions — see Recurring collection below.

Environment / config

All of the above are also exposed under the monnify key of the published config file.

Authentication

Monnify uses OAuth2 client credentials: the API key and secret key are Basic-auth'd against api/v1/auth/login to obtain a bearer token, which is then sent on every request. The handler caches that token per MONNIFY_TOKEN_CACHE_* (keyed by base URL and API key, so sandbox and production tokens never collide) and re-authenticates once automatically if a call comes back unauthorised.

Monnify replies 200 OK on business failures, so the client checks the requestSuccessful flag in the body as well as the HTTP status.

Amounts

Monnify amounts are decimal strings in the major unit (e.g. "3900.00" / "NGN"). Do not pass minor units (kobo).

Recurring collection

Monnify does not own a renewal clock. Unlike Paystack, there is no provider-side plan that charges the customer every month — your application decides when a period is due and initiates the charge. Two rails are available:

Rail Contract First charge Notes
Stored card token ChargesStoredInstruments ✅ Tokenised from a completed card payment
Direct debit mandate ManagesMandates ❌ Renewals only; needs bank activation before use

A mandate can never collect the first payment: after the payer authorises it, the bank takes anywhere from five minutes to 48 hours to activate it. Collect the first payment through an ordinary checkout (card or bank transfer) and use the mandate for subsequent periods.

Because only a card can be tokenised, a checkout whose payment carries the requires_reusable_authorization metadata key is offered CARD alone — any monnify_payment_methods value on the same payment is ignored. See Channels that can be charged again.

Stored card tokens

After a successful card payment, pull the reusable token off the transaction and charge it later:

The token and the email it was created with are a pair — Monnify rejects the charge if you send the token with a different email.

Direct debit mandates

Mandate authorisation is fully digital — the payer either follows an authorisation link and enters an OTP, or sends a small token transfer from the account being mandated, depending on their bank. Create the mandate as open-ended so it has no end date; the authorisation window is a one-time setup deadline, not a recurring re-approval.

MandateStatus and DebitOutcome classify what came back. DebitOutcome::isRetryable(), retryAfterHours(), and requiresNewInstrument() let you drive dunning without pattern-matching provider strings yourself.

Webhooks

Point your Monnify webhook endpoint at route('payment.external-webhook-endpoint'). Requests are verified with the monnify-signature header (HMAC-SHA512 of the raw body, keyed by MONNIFY_SECRET_KEY). Handled event: SUCCESSFUL_TRANSACTION.

Monnify only sends webhooks for successful transactions. Failures are never pushed, so poll getDebitStatus() for any debit you initiated and did not hear back about.

Paystack Terminal

Paystack Terminal allows you to process payments on physical payment terminals. This feature is useful for point-of-sale (POS) systems and retail environments.

Prerequisites

  1. Ensure you have PAYSTACK_SECRET_KEY configured in your .env file
  2. Obtain your Terminal ID from Paystack Dashboard
  3. Set the PAYSTACK_TERMINAL_ID in your .env file:

Alternatively, you can set the Terminal ID dynamically in your session:

Usage

The Paystack Terminal functionality is provided via the Terminal class:

Creating a Payment Request

Create a payment request that can be pushed to a terminal:

This creates a payment record and returns a Payment model instance with the payment details stored in metadata.

Checking Terminal Status

Verify that the terminal hardware is online and ready before pushing payments:

Pushing Payment to Terminal

Send a payment request to the terminal for processing:

The returned $eventId can be used to track the payment request delivery status.

Verifying Terminal Receipt

Confirm that the terminal received the payment request (within 48 hours of creation):

Error Handling

The Terminal class throws \Exception on failures. Common scenarios include:

Always wrap Terminal method calls in try-catch blocks for proper error handling.

Testing

Credits

This package is made possible by the nice works done by the following awesome projects:

License

The MIT License (MIT). Please see License File for more information.


All versions of laravel-cashier with dependencies

PHP Build Version
Package Version
Requires php Version ^8.1
guzzlehttp/guzzle Version ^7.3
illuminate/support Version ^7.0|^8.0|^9.0|^10.0|^11.0|^12.0|^13.0
yabacon/paystack-php Version ^2.2
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 damms005/laravel-cashier contains the following files

Loading the files please wait ...