Download the PHP package lacasera/collector-paystack without Composer
On this page you can find all versions of the php package lacasera/collector-paystack. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download lacasera/collector-paystack
More information about lacasera/collector-paystack
Files in lacasera/collector-paystack
Package collector-paystack
Short Description Subscription billing for Laravel with PayStack: a hosted-style billing portal, plan switching, webhooks and a Cashier-like API.
License MIT
Homepage https://github.com/lacasera/collector-paystack
Informations about the package collector-paystack
Collector PayStack
A modern Laravel package for managing subscription billing with PayStack integration. Collector PayStack provides a complete billing portal with subscription management, payment processing, and customer billing features.
Features
- 🚀 Laravel 12 and 13 support
- 💳 Complete PayStack integration
- 📊 Subscription management (create, update, cancel)
- 🎨 Beautiful React-based billing portal
- 📅 Multiple billing intervals (monthly, yearly, daily, hourly)
- 🔄 Trial periods and grace periods
- 📧 Webhook handling for payment verification
- 🎯 Plan switching capabilities
- 📱 Responsive design with Tailwind CSS
Requirements
- PHP 8.2+ (8.3+ on Laravel 13)
- Laravel 12.0+ or 13.0+
- PayStack account and API keys
Installation
Install the package via composer:
Then run the interactive installer, which publishes the config and assets and runs the migrations:
Prefer to do it by hand? The installer is equivalent to:
The migrations add billing columns to your
userstable (paystack_id,pm_type,trial_ends_at, …) and create asubscriptionstable.
Configuration
Add your PayStack credentials to your .env file:
Configure your subscription plans in config/collector.php:
Usage
1. Prepare Your User Model
Add the Collectable trait to your User model:
2. Access the Billing Portal
The billing portal is automatically available at /collector/billing. From the
portal users can:
- Browse the configured plans and toggle between monthly and yearly pricing
- Subscribe to a plan (or switch plans)
- Cancel their current subscription
Customising the portal URL
The portal URI is built from prefix + path, and both are yours to change in
config/collector.php:
| Config | Portal URL |
|---|---|
| defaults | /collector/billing |
'prefix' => 'account' |
/account/billing |
'prefix' => 'account', 'path' => 'subscription' |
/account/subscription |
'domain' => 'billing.example.com', 'prefix' => null |
https://billing.example.com/billing |
The subscribe and cancel endpoints move with the prefix, and the billing portal frontend receives them as shared Inertia props — so nothing needs rebuilding when you change these values.
Always link to the portal with the route name rather than a literal path, so your links follow the config:
The webhook URL does not move with the prefix. It has its own
webhook_pathsetting, because PayStack learns that URL out-of-band from your dashboard — relocating the portal must not silently break an endpoint PayStack is already posting to. See Handle Webhooks.
3. The Subscription Management Portal
Subscribed customers can manage their billing at /collector/billing/manage
(route('collector.manage')), a tabbed page covering:
- Overview — current plan, amount, next billing date, trial and grace-period state, with actions to change plan or cancel
- Payment History — every PayStack transaction, paginated
- Payment Methods — stored cards, de-duplicated (PayStack records one authorization per transaction, so one card can appear many times)
- Subscriptions — the full subscription history, active and past
The portal reconciles with PayStack on load, so subscriptions started or cancelled outside your application still show up.
Linking to a section
The open section lives in the URL, so a reload keeps its place and you can send customers straight where they need to go:
Valid sections are overview, history, methods and subscriptions; an
unrecognised value falls back to the overview rather than erroring, so a stale
bookmark still lands somewhere useful. Switching section in the browser updates
the URL without refetching, and the back button moves between sections.
How the two pages relate
A customer with an active subscription who visits the plans page is forwarded to
the management page — there is no point showing a plan grid to someone who
already has a plan. "Change plan" sends them back with ?change=1, which is the
flag that suppresses the forward; without it the button would bounce straight
back and appear to do nothing.
Cancelling lives only on the management page. A cancelled subscription stays visible there for the rest of its grace period, showing the date access ends, rather than disappearing the moment it is cancelled.
What PayStack can and cannot do
PayStack's API differs from Stripe's in two ways that shape this page:
| Action | How it works here |
|---|---|
| Change plan | PayStack has no endpoint to move a subscription to another plan. "Change plan" cancels the current subscription and starts a new checkout. |
| Update card | PayStack has no card-replacement API. The portal mints a short-lived link to PayStack's own hosted page, so card details never touch your application. |
Because plan changes are cancel-then-resubscribe, the package cancels any active subscription before starting a new checkout — reconciling with PayStack first, so a subscription missing from your local table cannot survive the switch and keep billing alongside its replacement.
4. Query Subscription State
The Collectable trait and the Subscription model expose the state you need:
Customers & Payment Methods
5. Start a Subscription
Subscriptions are created through PayStack's hosted checkout. The billing portal
does this for you when a user picks a plan, but you can also start the flow
yourself with a fluent, Cashier-style builder. checkout() returns a redirect to
PayStack:
success_urlmaps to PayStack'scallback_url; omit it to return to the built-in billing portal, which verifies and records the payment automatically.trialDays()records a trial period on the resulting subscription.- Starting a new subscription cancels the user's existing active subscription on PayStack (plan switching).
Need the raw URL instead of a redirect (e.g. for a JSON/API response)? Cast the result to a string:
6. Cancel a Subscription
Cancelling disables the subscription on PayStack and keeps it valid until the end of the current billing period (grace period).
7. Handle Webhooks
The package registers a webhook endpoint at POST /collector/webhooks. Add
this URL to your PayStack dashboard (Settings → API Keys & Webhooks). When
PAYSTACK_SECRET_KEY is set, every request is verified against PayStack's
x-paystack-signature header before it is processed.
This path is set by collector.webhook_path and is deliberately independent of
the portal's prefix, so moving the billing portal leaves the webhook where
your PayStack dashboard expects it. If you do change webhook_path, update the
URL in the dashboard at the same time or events will start 404ing. The endpoint
is named, so you can always resolve it with route('collector.webhook').
Handled events: subscription.create, subscription.not_renew,
charge.success, invoice.create, and invoice.payment_failed.
Events
Collector dispatches events throughout the billing lifecycle so you can hook in your own logic (send receipts, provision access, notify Slack, …):
| Event | Dispatched when |
|---|---|
Collector\Events\WebhookReceived |
Any signed PayStack webhook is received |
Collector\Events\PaymentReceived |
A charge.success / failed-invoice webhook arrives |
Collector\Events\InvoiceCreated |
An invoice.create webhook arrives |
Collector\Events\PaymentVerified |
A user returns from checkout with a reference |
Collector\Events\SubscriptionCanceled |
A subscription is cancelled |
Listen for them as usual:
Authorization & Custom Resolution
By default the billing portal resolves the collectable from the authenticated user and allows access to anyone signed in. Override either behaviour from a service provider:
You can also change the portal path and its middleware in config/collector.php
(path and middleware).
Custom Models
If you extend the package's models, register them from a service provider (a
single useCustomerModel() call configures both collectable resolution and the
Subscription → owner relationship):
Frontend Customization
The package ships a pre-built React portal (React 18 + TypeScript + Tailwind + Inertia.js); the compiled assets are inlined into the portal page, so no build step is required to use it.
To tweak the Blade shell, publish the views:
To modify the React source, edit resources/js and rebuild the bundle:
Testing
PHP (Pest / Testbench):
Frontend and end-to-end:
Code Style
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
If you discover any security related issues, please email [email protected] instead of using the issue tracker.
Credits
- Agyenim Boateng
- All Contributors
License
The MIT License (MIT). Please see License File for more information.
All versions of collector-paystack with dependencies
illuminate/contracts Version ^12.0|^13.0
illuminate/database Version ^12.0|^13.0
illuminate/support Version ^12.0|^13.0
illuminate/http Version ^12.0|^13.0
illuminate/validation Version ^12.0|^13.0
inertiajs/inertia-laravel Version ^1.3.1|^2.0
moneyphp/money Version ^4.5
guzzlehttp/guzzle Version ^7.8
ext-intl Version *