PHPackages                             digikraaft/laravel-paystack-subscription - 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. digikraaft/laravel-paystack-subscription

ActiveLibrary[Payment Processing](/categories/payments)

digikraaft/laravel-paystack-subscription
========================================

A simple interface to Paystack's subscription billing services. It takes the pain of implementing subscription management off you.

v2.1.0(3y ago)231.2k13[2 issues](https://github.com/digikraaft/laravel-paystack-subscription/issues)[2 PRs](https://github.com/digikraaft/laravel-paystack-subscription/pulls)MITPHPPHP ^8.0|^8.1CI failing

Since Jun 22Pushed 1y ago2 watchersCompare

[ Source](https://github.com/digikraaft/laravel-paystack-subscription)[ Packagist](https://packagist.org/packages/digikraaft/laravel-paystack-subscription)[ Docs](https://github.com/digikraaft/laravel-paystack-subscription)[ RSS](/packages/digikraaft-laravel-paystack-subscription/feed)WikiDiscussions master Synced today

READMEChangelog (9)Dependencies (6)Versions (10)Used By (0)

Paystack subscription in a Laravel application
==============================================

[](#paystack-subscription-in-a-laravel-application)

Laravel Paystack Subscription offers a simple, fluent interface to [Paystack's](https://paystack.com/) subscription billing services. No need to worry about writing subscription billing code anymore!

[![tests](https://github.com/digikraaft/laravel-paystack-subscription/workflows/tests/badge.svg)](https://github.com/digikraaft/laravel-paystack-subscription/workflows/tests/badge.svg)[![License: MIT](https://camo.githubusercontent.com/784362b26e4b3546254f1893e778ba64616e362bd6ac791991d2c9e880a3a64e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e2e737667)](https://opensource.org/licenses/MIT)

Installation
============

[](#installation)

You can install the package via composer:

```
composer require digikraaft/laravel-paystack-subscription
```

#### Configuration File

[](#configuration-file)

The Laravel Paystack Subscription package comes with a configuration file, here is the content of the file:

```
return [

    /*
    |--------------------------------------------------------------------------
    | Paystack Keys
    |--------------------------------------------------------------------------
    |
    | The Paystack publishable key and secret key. You can get these from your Paystack dashboard.
    |
    */

    'public_key' => env('PAYSTACK_PUBLIC_KEY'),

    'secret' => env('PAYSTACK_SECRET'),

    /*
    |--------------------------------------------------------------------------
    | Subscription Model
    |--------------------------------------------------------------------------
    |
    | This is the model in your application that implements the Billable trait
    | provided by PaystackSubscription. It will serve as the primary model you use while
    | interacting with PaystackSubscription related methods, subscriptions, etc.
    |
    */
    'model' => env('SUBSCRIPTION_MODEL', App\User::class),

    /*
   |--------------------------------------------------------------------------
   | User Table
   |--------------------------------------------------------------------------
   |
   | This is the table in your application where your users' information is stored.
   |
   */
    'user_table' => 'users',

    /*
   |--------------------------------------------------------------------------
   | Webhooks Path
   |--------------------------------------------------------------------------
   |
   | This is the base URI path where webhooks will be handled from.
   |
   | This should correspond to the webhooks URL set in your Paystack dashboard:
   | https://dashboard.paystack.com/#/settings/developer.
   |
   | If your webhook URL is https://domain.com/paystack/webhook/ then you should simply enter paystack here.
   |
   | Remember to also add this as an exception in your VerifyCsrfToken middleware.
   |
   | See the demo application linked on github to help you get started.
   |
   */
    'webhook_path' => env('PAYSTACK_WEBHOOK_PATH', 'paystack'),

];
```

You can publish this config file with the following commands:

```
php artisan vendor:publish --provider="Digikraaft\PaystackSubscription\PaystackSubscriptionServiceProvider" --tag="config"
```

#### Database Migrations

[](#database-migrations)

You will need to publish the database migrations with these commands:

```
php artisan vendor:publish --provider="Digikraaft\PaystackSubscription\PaystackSubscriptionServiceProvider" --tag="migrations"
php artisan migrate
```

The migrations will add several columns to your users table as well as create a new subscriptions table to hold all of your customer's subscriptions.

Configuration
=============

[](#configuration)

### Billable Model

[](#billable-model)

Before using the package, add the Billable trait to your model definition. This trait provides various methods to allow you to perform common billing tasks, such as creating subscriptions, renewing subscriptions and cancelling subscriptions:

```
use Digikraaft\PaystackSubscription\Billable;

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

The package assumes that your Billable model will be the default App\\User class that ships with Laravel. If you wish to change this you can specify a different model in your .env file or in the published config file of the package:

```
SUBSCRIPTION_MODEL = App\User
```

Please note that if you're using a model other than Laravel's supplied App\\User model, you'll need to publish and alter the migrations provided to match your alternative model's table name.

You can also specify a different table name for your billable model. See the [Configuration File](#configuration-file) section.

### API Keys

[](#api-keys)

Next, you should configure your Paystack keys in your .env file. You can get your Paystack API keys from the Paystack dashboard.

```
PAYSTACK_PUBLIC_KEY=your-paystack-public-key
PAYSTACK_SECRET=your-paystack-secret
```

Customers
---------

[](#customers)

### Retrieving Customers

[](#retrieving-customers)

You can retrieve a customer by their Paystack ID using the `PaystackSubscription::findBillable` method. This will return an instance of the Billable model:

```
use Digikraaft\PaystackSubscription\PaystackSubscription;

$user = PaystackSubscription::findBillable($paystackId);

```

### Creating Customers

[](#creating-customers)

If you need to create a Paystack customer without starting a subscription immediately, you can do by using the `createAsPaystackCustomer` method:

```
$paystackCustomer = $user->createAsPaystackCustomer();

```

The code creates a customer in Paystack. You can then begin a subscription at a later date. You can also use an optional `$options` array to pass in any additional parameters that are supported by the Paystack API:

```
$paystackCustomer = $user->createAsPaystackCustomer($options);

```

If the billable entity is already a customer in Paystack, you can retrieve the customer object using the `asPaystackCustomer` method:

```
$paystackCustomer = $user->asPaystackCustomer();

```

If you are not sure that the billable entity is already a Paystack customer, the `createOrGetPaystackCustomer` method can be used to the get the customer object. This method will create a new customer in Paystack if one does not already exist:

```
$paystackCustomer = $user->createOrGetPaystackCustomer();

```

### Updating Customers

[](#updating-customers)

If you need to update the Paystack customer with additional information, you can do this using the `updatePaystackCustomer` method:

```
$paystackCustomer = $user->updatePaystackCustomer($options);

```

Subscriptions
-------------

[](#subscriptions)

### Creating Subscriptions

[](#creating-subscriptions)

To create a subscription, first retrieve an instance of your billable model, which typically will be an instance of App\\User. Once you have retrieved the model instance, you may use the newSubscription method to create the model's subscription:

```
$user = User::find(1);

$user->newSubscription('default', 'PLN_paystackplan_code')->create($transactionId);

```

The first argument passed to the `newSubscription` method should be the name of the subscription. If your application only offers a single subscription, you might call this `default` or `primary`. The second argument is the specific plan the user is subscribing to. This value should correspond to the plan's code in Paystack.

The `create` method, which accepts a Paystack transaction ID, will begin the subscription as well as update your database with the customer ID and other relevant billing information.

You can check the [implementation demo app](https://github.com/digikraaft/laravel-paystack-subscription-demo) to see how you can easily get this plan code and process payment to get the `$transactionID` from Paystack.

### Authorization Code

[](#authorization-code)

When a customer is initially charged, Paystack creates an authorization code that can be used later to bill the customer should the customer cancel. If you would like to bill the customer at a later date, the authorization code can be passed as a second argument to the `create` method:

```
$user->newSubscription('default', 'PLN_paystackplan_code')->create(null, $authorizationCode);

```

### Additional Details

[](#additional-details)

If you would like to specify additional customer information, you may do so by passing them as the third argument to the `create` method:

```
$user->newSubscription('default', 'PLN_paystackplan_code')->create($transactionId, null, [
    'email' => $email,
]);

```

The additional fields specified must be supported by Paystack's API.

Checking Subscription Status
----------------------------

[](#checking-subscription-status)

Once a user is subscribed to your application, you may easily check their subscription status using a variety of convenient methods. First, the `subscribed` method returns `true` if the user has an active subscription, even if the subscription is cancelled and is due not to renew at the end of the billing period:

```
if ($user->subscribed('default')) {
    //
}

```

The `subscribed` method can also be used in a route middleware, allowing you to filter access to routes and controllers based on the user's subscription status:

```
public function handle($request, Closure $next)
{
    if ($request->user() && ! $request->user()->subscribed('default')) {
        // This user is not a paying customer...
        return redirect('billing');
    }

    return $next($request);
}

```

An example of this can be seen in the demo implementation of this package [here](https://github.com/digikraaft/laravel-paystack-subscription-demo)

The `subscribedToPlan` method may be used to determine if the user is subscribed to a given plan based on a given Paystack plan code. In this example, we will determine if the user's `default` subscription is actively subscribed to the `PLN_paystackplan_code` plan:

```
if ($user->subscribedToPlan('PLN_paystackplan_code', 'default')) {
    //
}

```

By passing an array to the `subscribedToPlan` method, you may determine if the user's `default` subscription is actively subscribed to the `PLN_paystackplan_code` or the `PLN_paystackplan_code2` plan:

```
if ($user->subscribedToPlan(['PLN_paystackplan_code', 'PLN_paystackplan_code2'], 'default')) {
    //
}

```

The `active` method may be used to determine if the user currently has an active subscription:

```
if ($user->subscription('default')->active()) {
    //
}

```

The `renews` method may be used to determine if the user's subscription will renew after the current billing period:

```
if ($user->subscription('default')->renews()) {
    //
}

```

The `daysLeft` method may be used to get the number of days left on the current billing period:

```
$daysLeft = $user->subscription('default')->daysLeft();

```

The `endsAt` method may be used to get the date the current billing period will end:

```
$endDate = $user->subscription('default')->endsAt();

```

### Cancelled Subscription Status

[](#cancelled-subscription-status)

To determine if the user has cancelled their subscription, you may use the `isCancelled` method:

```
if ($user->subscription('default')->isCancelled()) {
    //
}

```

To determine if the user's subscription is past due, you may use the `pastDue` method:

```
if ($user->subscription('default')->pastDue()) {
    //
}

```

### Subscription Scopes

[](#subscription-scopes)

The `active` and` cancelled` subscription states are also available as query scopes so that you may easily query your database for subscriptions:

```
// Get all active subscriptions...
$subscriptions = Subscription::query()->active()->get();

// Get all of the cancelled subscriptions for a user...
$subscriptions = $user->subscriptions()->cancelled()->get();

```

Cancelling Subscriptions
------------------------

[](#cancelling-subscriptions)

To cancel a subscription, call the `cancel` method on the user's subscription:

```
$user->subscription('default')->cancel();

```

When a subscription is cancelled, the `paystack_status` column in your database is set to `complete`. This is based on Paytstack's implementation, meaning the subscription will not renew at the end of the billing period. The subscription continues to be active until the end of the current billing period.

Resuming Subscriptions
----------------------

[](#resuming-subscriptions)

If a user has cancelled their subscription and you wish to resume it, use the `enable` method.

```
$user->subscription('default')->enable();

```

If the user cancels a subscription and then resumes that subscription before the subscription has fully expired, they will not be billed immediately. Instead, their subscription will be re-activated, and they will be billed on the original billing cycle.

Handling Paystack Webhooks
==========================

[](#handling-paystack-webhooks)

Paystack can notify your application about various events via webhooks. By default, a route that points to this package's webhook controller is configured through the service provider. This controller will handle all incoming webhook requests.

By default, this controller will automatically handle cancelling subscriptions, enabling subscriptions and failed invoices. This controller can be extended to handle any webhook event you like.

To ensure your application can handle Paystack webhooks, be sure to configure the webhook URL in the Paystack dashboard. By default, this package's webhook controller listens to the `/paystack/webhook`

### Webhooks &amp; CSRF Protection

[](#webhooks--csrf-protection)

Since Paystack webhooks need to bypass Laravel's CSRF protection, be sure to list the URI as an exception in your `VerifyCsrfToken` middleware or list the route outside of the `web` middleware group:

```
protected $except = [
    'paystack/*',
];

```

### Defining Webhook Event Handlers

[](#defining-webhook-event-handlers)

If you have additional webhook events you would like to handle, extend the Webhook controller. Your method names should correspond to this package's expected convention, specifically, methods should be prefixed with `handle` and the "camel case" name of the webhook you wish to handle. For example, if you wish to handle the `invoice.create` webhook, you should add a `handleInvoiceCreate` method to the controller:

```
