PHPackages                             karpovigorok/subkit - 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. [Payment Processing](/categories/payments)
4. /
5. karpovigorok/subkit

ActiveLibrary[Payment Processing](/categories/payments)

karpovigorok/subkit
===================

A Laravel package for subscription and billing orchestration.

v1.0.0(2mo ago)3535[1 PRs](https://github.com/karpovigorok/subkit/pulls)MITPHPPHP ^8.4CI passing

Since Apr 3Pushed 2mo ago1 watchersCompare

[ Source](https://github.com/karpovigorok/subkit)[ Packagist](https://packagist.org/packages/karpovigorok/subkit)[ Docs](https://github.com/karpovigorok/subkit)[ GitHub Sponsors]()[ RSS](/packages/karpovigorok-subkit/feed)WikiDiscussions main Synced 4w ago

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

SubKit
======

[](#subkit)

Laravel subscriptions with a ready-to-use Filament UI.
Replace days of custom billing logic with a working setup on top of Stripe (Cashier).

- Skip custom subscription logic
- Skip building pricing UI
- Skip wiring Stripe webhooks manually

[![SubKit Pricing](art/demo-how-subkit-works.gif)](art/screen-subkit-theme-default.png)

SubKit provides a Filament admin panel to manage plans and plan sets, themeable Blade components for your pricing page and subscription dashboard, and a clean PHP API for subscription lifecycle operations.

**Why use SubKit?**While Laravel Cashier is incredibly powerful, building the actual UI and admin panel for subscriptions takes days. SubKit bridges this gap by providing a **"Lickable UI"** out of the box and a powerful Filament admin to manage it all without writing boilerplate code.

What it does
------------

[](#what-it-does)

- Integrates with Stripe via Laravel Cashier (webhooks, checkout sessions, billing portal)
- Provides a Filament admin panel to manage Plans, Plan Sets, and Provider Prices
- Provides Blade components: a pricing table and a subscription management UI, with multiple themes
- Exposes a PHP facade and REST API for subscription operations (checkout, cancel, resume, billing portal)

Live Demo
---------

[](#live-demo)

Try it in action: **[subkit.noxls.net](https://subkit.noxls.net)**

- Register a test account to explore the customer billing flow.
- Once registered, navigate to **`/admin`** to check out the Filament control panel.

What it does NOT do
-------------------

[](#what-it-does-not-do)

- Process payments or store card data
- Replace Stripe or Laravel Cashier — it orchestrates on top of them
- Handle invoicing, taxes, or compliance
- Manage user authentication or access control

---

Requirements
------------

[](#requirements)

- PHP 8.4+
- Laravel 11+
- Laravel Cashier (`laravel/cashier` ^16.5) installed and configured
- Filament (`filament/filament` ^3.2)
- MySQL 8+ (or MariaDB 10.5+)
- A Stripe account

---

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

[](#installation)

```
composer require karpovigorok/subkit
```

Publish the config and run migrations:

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

Register the plugin in your Filament panel provider:

```
use SubKit\Filament\SubKitPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        // ...
        ->plugin(SubKitPlugin::make());
}
```

---

Configuration
-------------

[](#configuration)

```
php artisan vendor:publish --tag=subkit-config
```

Add to your `.env`:

```
STRIPE_KEY=pk_live_...
STRIPE_SECRET=sk_live_...
STRIPE_WEBHOOK_SECRET=whsec_...

# Optional
EASY_SUB_CURRENCY_CODE=USD
EASY_SUB_CURRENCY_SYMBOL=$
```

Your `User` model must use Cashier's `Billable` trait:

```
use Laravel\Cashier\Billable;

class User extends Authenticatable
{
    use Billable;
}
```

---

Stripe setup
------------

[](#stripe-setup)

### 1. Create plans in the admin panel

[](#1-create-plans-in-the-admin-panel)

Navigate to your Filament admin panel (usually `/admin`) → **Plans** → Create a plan. After creating a plan, add a Stripe Price ID in the **Provider Prices** tab on the plan edit page.

### 2. Register the Stripe webhook

[](#2-register-the-stripe-webhook)

Point your Stripe webhook to Cashier's built-in route:

```
https://your-app.com/stripe/webhook

```

Events to enable in Stripe:

- `customer.subscription.created`
- `customer.subscription.updated`
- `customer.subscription.deleted`
- `invoice.paid`
- `invoice.payment_failed`

---

Usage
-----

[](#usage)

### Pricing table

[](#pricing-table)

Drop the pricing table into any Blade view. The component uses the currently authenticated user automatically — no user ID needed.

```

```

With a plan set (for multiple landing pages or A/B testing):

```

```

#### All pricing table props

[](#all-pricing-table-props)

PropTypeDefaultDescription`set``string|null``null`Plan set code. If omitted, shows all active plans.`theme``string|null``'default'`UI theme (`default`, `dark`, `light`, or a custom theme).`provider``string``'stripe'`Payment provider.`success-url``string``''`Redirect after successful checkout. Accepts a route name, relative path, or full URL.`cancel-url``string``''`Redirect when the user cancels checkout.`free-url``string``''`CTA destination for $0 plans (authenticated users).`guest-redirect-url``string|null``null`Where unauthenticated visitors are sent. Defaults to `/register`.`company-id``string|null``null`For B2B: attaches the subscription to a company rather than a user.`subscribe-label``string|null``null`Override the "Get Started" button text.`free-label``string|null``null`Override the "Get Started Free" button text.`guest-label``string|null``null`Override the "Create Account to Subscribe" button text.URL props accept a **route name** (e.g. `'dashboard'`), a **relative path** (e.g. `'/thanks?utm_source=fb'`), or a **full URL**. Route names are resolved automatically. URLs set in the admin panel (per Plan Set) serve as defaults when the prop is omitted.

For the best UX, point **Free Plan URL** to a route that automatically creates a $0 subscription for the authenticated user.

Button labels follow a three-tier fallback: **Blade prop → Plan Set admin setting → translation string**.

### Manage subscriptions

[](#manage-subscriptions)

Drop the manage component into your dashboard or account page:

```

```

This renders the user's active subscriptions: plan name, status badge, trial/renewal dates, and action buttons (Cancel, Resume, Manage Billing). Renders nothing if the user has no subscriptions.

#### All manage-subscriptions props

[](#all-manage-subscriptions-props)

PropTypeDefaultDescription`theme``string|null``'default'`UI theme.`return-url``string``''`URL to return to from the Stripe billing portal.`guest-redirect-url``string|null``null`Where guests are sent. Renders a redirect link instead of the subscription UI.### Check subscription access

[](#check-subscription-access)

```
use SubKit\Facades\SubKit;

if (SubKit::hasAccess((string) auth()->id())) {
    // User has an active or trialing subscription
}
```

`hasAccess()` returns `true` for `active` and `trialing` states.

### Get subscriptions for a user

[](#get-subscriptions-for-a-user)

```
$subscriptions = SubKit::forUser((string) auth()->id());

$active = SubKit::activeForUser((string) auth()->id()); // returns Cashier Subscription or null
```

### Cancel a subscription

[](#cancel-a-subscription)

```
// Cancel at period end (access continues until the billing period ends)
SubKit::cancel($subscriptionId);

// Cancel immediately
SubKit::cancel($subscriptionId, immediately: true);
```

### Resume a subscription

[](#resume-a-subscription)

```
SubKit::resume($subscriptionId);
```

### Billing portal

[](#billing-portal)

Redirect the user to the Stripe-hosted billing portal to manage payment methods and invoices:

```
$url = SubKit::billingPortal($subscriptionId, route('dashboard'));
return redirect()->away($url);
```

---

Plan Sets
---------

[](#plan-sets)

Plan Sets let you curate groups of plans for specific contexts — landing pages, A/B tests, regional pricing, etc.

Create a plan set in the admin panel under **Plan Sets**, assign plans to it, and reference it by code:

```

```

Per Plan Set you can configure:

- **Theme** — override the default UI theme
- **Description** — subtitle shown above the pricing table
- **URLs** — default success, cancel, free, and guest redirect URLs
- **Button Labels** — override button text per set

---

Plan Features
-------------

[](#plan-features)

SubKit includes a normalized, Many-to-Many feature management system. Instead of hardcoding features in your Blade files, you can manage a global library of features (e.g., "Priority Support", "Unlimited Projects") directly in the Filament admin panel.

Simply attach features to your Plans using the intuitive Filament interface, and SubKit's pricing tables will automatically render them with beautiful checkmarks inside the pricing cards.

---

B2B usage
---------

[](#b2b-usage)

For company-level subscriptions, pass `company-id`:

```

```

`company-id` is a plain string with no foreign key constraint — it can reference any table in your app (`teams`, `organizations`, `workspaces`, etc.).

---

Themes
------

[](#themes)

Three themes are bundled: `default`, `dark`, and `light`. Specify the theme per component or per Plan Set.

To create a custom theme, publish the views and add a new folder:

```
php artisan vendor:publish --tag=subkit-views
```

Create `resources/views/vendor/subkit/themes/{your-theme}/pricing-table.blade.php`. The theme will appear automatically in the admin panel's theme selector.

---

REST API
--------

[](#rest-api)

MethodURLDescription`POST``/api/subkit/checkout`Create a Stripe Checkout session`GET``/api/subkit/subscriptions/user`List subscriptions for the authenticated user`GET``/api/subkit/subscriptions/company`List subscriptions for a company`POST``/api/subkit/subscriptions/{id}/cancel`Cancel a subscription`POST``/api/subkit/subscriptions/{id}/resume`Resume a subscriptionAdd authentication middleware in `config/subkit.php`:

```
'api' => [
    'middleware' => ['api', 'auth:sanctum'],
    'prefix'     => 'api/subkit',
],
```

---

Subscription states
-------------------

[](#subscription-states)

Subscription state is owned by Cashier and sourced from Stripe's `stripe_status` field:

StateMeaning`trialing`In a free trial period`active`Paid and active`past_due`Payment failed, awaiting retry`paused`Paused by the customer`canceled`Canceled (may still have access until period end)`incomplete`Checkout started but not completed---

Listening to subscription events
--------------------------------

[](#listening-to-subscription-events)

SubKit delegates all webhook processing to Cashier. To react to lifecycle changes, listen to Cashier's `WebhookHandled` event in your `AppServiceProvider`:

```
use Laravel\Cashier\Events\WebhookHandled;

Event::listen(WebhookHandled::class, function (WebhookHandled $event) {
    if ($event->payload['type'] === 'customer.subscription.deleted') {
        // revoke access, send email, etc.
    }
});
```

---

Publish tags
------------

[](#publish-tags)

TagPublishes`subkit-config``config/subkit.php``subkit-migrations`All package migrations`subkit-views`Blade views (for customization)`subkit-lang`Translation strings---

Running tests
-------------

[](#running-tests)

```
composer test
```

---

License
-------

[](#license)

MIT

###  Health Score

44

—

FairBetter than 91% of packages

Maintenance85

Actively maintained with recent releases

Popularity16

Limited adoption so far

Community13

Small or concentrated contributor base

Maturity54

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 62.5% 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

Unknown

Total

1

Last Release

89d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/7913548?v=4)[Ihor Karpov](/maintainers/karpovigorok)[@karpovigorok](https://github.com/karpovigorok)

---

Top Contributors

[![karpovigorok](https://avatars.githubusercontent.com/u/7913548?v=4)](https://github.com/karpovigorok "karpovigorok (5 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (2 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (1 commits)")

---

Tags

billingfilament-pluginfilamentphplaravellaravel-cashierlaravel-packagelaravel-saaspaymentspricingpricing-tablesaassaas-boilerplatestarter-kitstripesubscriptionstall-stacklaravelIhor Karpovsubkit

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/karpovigorok-subkit/health.svg)

```
[![Health](https://phpackages.com/badges/karpovigorok-subkit/health.svg)](https://phpackages.com/packages/karpovigorok-subkit)
```

###  Alternatives

[spatie/laravel-permission

Permission handling for Laravel 12 and up

12.9k102.4M1.3k](/packages/spatie-laravel-permission)[spatie/laravel-pdf

Create PDFs in Laravel apps

1.0k4.8M46](/packages/spatie-laravel-pdf)[rawilk/profile-filament-plugin

Profile &amp; MFA starter kit for filament.

3913.7k](/packages/rawilk-profile-filament-plugin)[dedoc/scramble

Automatic generation of API documentation for Laravel applications.

2.1k11.2M95](/packages/dedoc-scramble)[stephenjude/filament-jetstream

A Laravel starter kit built with Filament inspired by Jetstream.

17760.2k2](/packages/stephenjude-filament-jetstream)[stephenjude/filament-debugger

About

104162.2k2](/packages/stephenjude-filament-debugger)

PHPackages © 2026

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