PHPackages                             offline/oc-cashier-plugin - 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. offline/oc-cashier-plugin

ArchivedOctober-plugin[Payment Processing](/categories/payments)

offline/oc-cashier-plugin
=========================

October CMS plugin to handle Stripe and Braintree payments using Laravel Cashier

v3.0.0(1y ago)149511MITPHP

Since Dec 19Pushed 1y ago4 watchersCompare

[ Source](https://github.com/OFFLINE-GmbH/oc-cashier-plugin)[ Packagist](https://packagist.org/packages/offline/oc-cashier-plugin)[ RSS](/packages/offline-oc-cashier-plugin/feed)WikiDiscussions master Synced today

READMEChangelogDependencies (2)Versions (8)Used By (0)

October Cashier Plugin
======================

[](#october-cashier-plugin)

October CMS plugin to handle Stripe and Braintree payments using [Laravel Cashier](https://laravel.com/docs/5.5/billing).

This plugin integrates Laravel Cashier with the help of [Rainlab.User](https://github.com/rainlab/user-plugin) into October CMS. You can do "one-off" charges on your Rainlab users or subscribe them to your Stripe plans.

The plugin comes preloaded with simple Stripe Elements form and invoice list components. All features of Laravel Cashier are available. An easily customizable invoice view and some useful events have been added for this October CMS version of Cashier.

Breaking changes in v2.0.0
--------------------------

[](#breaking-changes-in-v200)

In version 2.0.0 of this plugin Laravel Cashier was updated to version 9.0. This makes the plugin compatible with Laravel 5 and Laravel 6 based October versions.

With this update, some architectural problems with the plugins have been solved that might introduce breaking changes depending on your setup:

- The `\OFFLINE\Cashier\Models\User` was removed completely. Use `\RainLab\User\Models\User` in its place.
- Because the custom User model was removed, you have to make sure any relations that might point to the old model class are moved to the RainLab.User model.
- The `stripeelementsform/script.js` partial was renamed to `script.htm`. If you override this partial make sure to rename your overriding partial as well.

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

[](#installation)

In `config/services.php` replace the `stripe` configuration with the following:

```
'stripe' => [
   'model'   => \RainLab\User\Models\User::class,
   'key'     => env('STRIPE_KEY'),
   'secret'  => env('STRIPE_SECRET'),
   'webhook' => [
       'url'     => '/stripe/webhook',
       'handler' => '\OFFLINE\Cashier\Classes\WebhookController@handleWebhook'
   ]
],
```

Now add your `STRIPE_KEY` and `STRIPE_SECRET` to your `.env` file.

```
STRIPE_KEY=pk_test_XXXXXXXXXXXXXXXXXXXXXX
STRIPE_SECRET=sk_test_XXXXXXXXXXXXXXXXXXXXXX

```

Make sure to include the [October CMS framework extras](http://octobercms.com/docs/ajax/extras) if you want to use the `StripeElementsForm` component.

You're done!

Handle Stripe Webhooks
----------------------

[](#handle-stripe-webhooks)

To receive Stripe webhooks configure Stripe to send them to `https:///stripe/webhook` (you can change this URL via the `services.stripe.webhook.url` config entry).

Subscription cancellation on failed charges are handled by default by Laravel Cashier. If you wish to react to other webhooks [listen for the generic `offline.cashier::stripe.webhook.received` event](http://octobercms.com/docs/services/events#events-subscribing) that is fired for all incomming webhooks or create a listener for a specific webhook event like `offline.cashier::stripe.webhook.invoice.payment_succeeded` (using the format `offline.cashier::stripe.webhook.`). All event listeners receive a `$payload` and a `$request` variable.

Alternatively you can set your own webhook handler controller in the `services.stripe.webhook.handler` config entry and implement everything yourself.

```
Event::listen('offline.cashier::stripe.webhook.invoice.payment_succeeded', function ($payload, $request) {
    $subscription = $payload['data']['object']['subscription'];

    $user = \RainLab\User\Models\User::fromSubscriptionId($subscription);

    $user->payment_succeeded_at = \Carbon\Carbon::now();
    $user->save();

    logger()->debug('Received payment', compact('user', 'subscription'));
});
```

Components
----------

[](#components)

### InvoicesList

[](#invoiceslist)

This component lists all invoices of a specific user account.

#### Use your own number formatter

[](#use-your-own-number-formatter)

If you want to have complete control over the way the amounts are formatted in your invoices, you have the possibility to listen for the `offline.cashier::format.amount` event and format the amount yourself.

```
Event::listen('offline.cashier::format.amount', function ($amount) {
    return number_format((float)$amount / 100, 2, '.', "'") . ' CHF';
});
```

#### Customize the invoice template

[](#customize-the-invoice-template)

The invoice template is stored in `views/receipt.htm`. You can copy this template and store it in your own plugin or theme. To load your own partial for the invoices set the new view path in the backend settings of Cashier.

You can pass additional data to the invoice using the repeater on the backend settings form. Each variable you specify will be available in the template. This is useful if you want to show a phone number or email address on your invoices.

#### Properties

[](#properties)

##### userId

[](#userid)

Specify the id of the user you want to load the invoices for. If you leave this blank the currently logged in user will be used.

##### includePending

[](#includepending)

Whether or not to include pending invoices in the list.

##### loadingText

[](#loadingtext)

For performance reasons the invoice list is loaded asynchronously. During the loading period this string is displayed to the user (defaults to `Loading invoices...`).

### StripeElementsForm

[](#stripeelementsform)

This component provides you with a simple starting point to integrate [Stripe Elements](https://stripe.com/docs/elements) into your Website.

Simply add the component **to your page** and you will be presented with a simple credit card input form.

#### Token Handler Callback

[](#token-handler-callback)

To extend the default `stripeTokenHandler` function that receives the generated Stripe token, copy the `plugins/offline/cashier/components/stripeelementsform/tokenHandler.htm` to `themes//partials/stripeElementsForms/tokenHandler.htm` and modify as needed.

#### Handle form submission

[](#handle-form-submission)

When the user submits the form the `offline.cashier::stripeElementForm.submit` event is triggered. You can [listen for this event in your own plugin](http://octobercms.com/docs/services/events#events-subscribing) and store the payment information for later use, charge your user or create a subscription.

Checkout the [Laravel Cashier Documentation](https://laravel.com/docs/5.5/billing) for more information on how to use the generated `stripeToken` to charge or subscribe a user.

For a working example see the code below:

```
public function boot()
{
    parent::boot();

    Event::listen('offline.cashier::stripeElementForm.submit', function ($post) {
        $token = $post['token']['id'] ?? null;
        if ( ! $token) {
            throw new \RuntimeException('Stripe token is missing!');
        }

        $user = \Auth::getUser();
        $user->newSubscription('main', 'users-selected-plan-id')->create($token);

        return [
            'redirect' => \Url::to('thank-you')
        ];
    });
}
```

#### Properties

[](#properties-1)

##### includeStripeJs

[](#includestripejs)

This property includes the `https://js.stripe.com/v3/` code into your page. If you have multiple instances of the component on one page make sure to enable this property only on one of them. If you include the code globally you can safely uncheck this property.

##### includeCss

[](#includecss)

This property includes the `styles.htm` partial from the component (which you can overwrite) with the component. If you defined your Stripe Elements styles gl

##### submitButtonLabel

[](#submitbuttonlabel)

This property specifies the submit button's label during the form submission.

### NeedsSubscription

[](#needssubscription)

Place this component on any page that is only accessible by users with a valid subscription. Users without a valid subscription are redirected to the page you defined.

#### Extend the subscription logic

[](#extend-the-subscription-logic)

If you need to extend the subscription logic you can listen for the `offline.cashier::subscription.check` event. The event receives the `user` and the `NeedsSubscription` component instance.

If you return `true` from any event listener the user will be allowed to view the page. If you return `false` from any event listener the user will be redirected. Please be aware that any `true` value takes precedence. If you don't return any `boolean` value the check will fallback to Laravel Cashier's `subscribed` method.

##### Extend the subscription logic

[](#extend-the-subscription-logic-1)

If you need to extend the subscription logic you can listen for the `offline.cashier::subscription.check` event. The event receives the `user` and the `NeedsSubscription` component instance.

If you return `true` from any event listener the user will be allowed to view the page. If you return `false` from any event listener the user will be redirected. Please be aware that any `true` value takes precedence. If you don't return any `boolean` value the check will fallback to Laravel Cashier's `subscribed` method.

```
 Event::listen('offline.cashier::subscription.check', function ($user, $component) {
    if ( ! $user) {
        return false;
    }

    if (isBanned($user)) {
        return false;
    }

    return $user->subscribed($component->property('subscription'));
});
```

#### Properties

[](#properties-2)

##### redirect

[](#redirect)

Unauthorized users are redirected to this route.

##### subscription

[](#subscription)

The name of the subscription a user needs to access the page. Default is `main`.

###  Health Score

36

—

LowBetter than 82% of packages

Maintenance35

Infrequent updates — may be unmaintained

Popularity20

Limited adoption so far

Community18

Small or concentrated contributor base

Maturity62

Established project with proven stability

 Bus Factor1

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

Every ~346 days

Recently: every ~367 days

Total

6

Last Release

600d ago

Major Versions

v1.0.9 → v2.0.02021-05-13

v2.0.1 → v3.0.02024-09-16

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/8600029?v=4)[Tobias Kündig](/maintainers/tobias-kuendig)[@tobias-kuendig](https://github.com/tobias-kuendig)

---

Top Contributors

[![tobias-kuendig](https://avatars.githubusercontent.com/u/8600029?v=4)](https://github.com/tobias-kuendig "tobias-kuendig (30 commits)")[![RomainMazB](https://avatars.githubusercontent.com/u/53976837?v=4)](https://github.com/RomainMazB "RomainMazB (8 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (1 commits)")[![Fl0Cri](https://avatars.githubusercontent.com/u/16371551?v=4)](https://github.com/Fl0Cri "Fl0Cri (1 commits)")[![therealkevinard](https://avatars.githubusercontent.com/u/12756908?v=4)](https://github.com/therealkevinard "therealkevinard (1 commits)")

### Embed Badge

![Health badge](/badges/offline-oc-cashier-plugin/health.svg)

```
[![Health](https://phpackages.com/badges/offline-oc-cashier-plugin/health.svg)](https://phpackages.com/packages/offline-oc-cashier-plugin)
```

###  Alternatives

[wp-pay-extensions/gravityforms

Gravity Forms driver for the WordPress payment processing library.

1133.3k2](/packages/wp-pay-extensions-gravityforms)

PHPackages © 2026

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