Cartalyst LLC.
Stripe-billing-laravel by Cartalyst
3
16
2
0
2

This package requires a valid subscription. Subscribe for access.

Preface

Introduction

Stripe Billing functionality for Laravel 5.7.

The package requires PHP 7.1.3+ and follows the FIG standards PSR-1, PSR-2 and PSR-4 to ensure a high level of interoperability between shared PHP.

Have a read through the Installation Guide and on how to Integrate it with Laravel 5.7.

Features

Our billing library provides robust interaction with our comprehensive Stripe API library.

General Cartalyst Laravel Cashier
Synchronize stripe data to database Yes No
Detailed Events Yes No
Easily swap internal models and gateways Yes No
Webhook Controller Yes Yes
Customers Cartalyst Laravel Cashier
Create a Stripe customer and attach to the entity Yes No
Update a Stripe customer Yes No
Delete a Stripe customer Yes No
Attach an existing Stripe customer to the entity Yes No
Manage a Stripe customer discount Yes No
Synchronize Stripe customer to entity Yes No
Cards Cartalyst Laravel Cashier
Create a card Yes Yes * 1
Update a card Yes Yes * 2
Delete a card Yes No
Retrieve all cards Yes No
Retrieve expired and non expired cards Yes No
Check if the entity has any active cards Yes No
Check if a card has expired or is expiring soon Yes No
Check if a card is the default card Yes No
Retrieve the entity default card Yes No
Set an existing card as the default one Yes No
Update the default card Yes No
Synchronize Stripe cards to entity Yes No
  • 1 : It creates a card via a Stripe.js token when creating a charge or a subscription. It doesn't have an endpoint to add new cards on demand.
  • 2 : Only allows to update the default card, not a specific card.
Charges Cartalyst Laravel Cashier
Create a charge Yes Yes
Update a charge Yes No
Retrieve all charges Yes No
Retrieve all captured and uncaptured charges Yes No
Can set a charge to be captured later Yes No
Can capture a charge Yes No
Check if a charge can be captured Yes No
Check if a charge has failed to be captured Yes No
Check if a charge has been captured Yes No
Check if a charge has been refunded Yes No
Check if a charge has been partially refunded Yes No
Synchronize charges to entity Yes No
Refunds Cartalyst Laravel Cashier
Create a partial or a full charge refund Yes No
Update a charge refund Yes No
Retrieve all refunds of a charge Yes No
Retrieve all refunds Yes No
Synchronize charge refunds to entity Yes No
Subscriptions Cartalyst Laravel Cashier
Create a subscription Yes Yes
Update a subscription Yes No
Cancel a subscription Yes Yes
Resume a subscription Yes Yes
Can have multiple subscriptions Yes No
Swap an active subscription plan Yes Yes
Retrieve all subscriptions Yes No
Retrieve expired and non expired subscriptions Yes No
Can set the trial period of a subscription Yes Yes
Can remove the trial period of a subscription Yes Yes
Can change a subscription quantity Yes Yes
Check if a subscription has expired Yes No
Check if a subscription has been canceled Yes No
Check if a subscription is on the grace period Yes No
Check if a subscription is on its trial period Yes No
Manage a subscription discount Yes No
Synchronize Stripe subscriptions to entity Yes No
Invoices Cartalyst Laravel Cashier
Create an invoice Yes No
Update an invoice Yes No
Check invoice status Yes No
Pay an invoice Yes No
Retrieve all invoices and their items Yes Yes
Create an invoice item Yes No
Update an invoice item Yes No
Delete an invoice item Yes No
Retrieve all pending invoice items Yes No
Synchronize Stripe invoices to entity Yes No
Synchronize Stripe invoice items to entity Yes No

Examples

// Get the entity object
$entity = User::find(1);

// Loop through all the entity subscriptions
foreach ($entity->subscriptions as $subscription) {
    // Check if the subscription is expired
    if ($subscription->isExpired()) {
        echo 'Subscription has expired!';
    }
}
// Get the entity object
$entity = User::find(1);

// Find a card
$card = $entity->cards->find(10);

// Check if the is expired
if ($card->hasExpired() {
    echo 'The card has expired.';
}

Setup

Installation

Cartalyst packages utilize Composer, for more information on how to install Composer please read the Composer Documentation.

Preparation

Open your composer.json file and add the following to the require array:

"cartalyst/stripe-billing-laravel": "^9.0"

Add the following lines after the require array on your composer.json file:

"repositories": [
    { "type": "composer", "url": "https://packages.cartalyst.com" }
]

Note: Make sure that after the required changes your composer.json file is valid by running composer validate.

Install the dependencies

Run the composer install or composer update to install or update the new requirement.

Integration

Note: Please read the Cartalyst Stripe Laravel integration documentation before continuing!!

After installing the package, open your Laravel config file located at config/app.php and add the following lines.

In the $providers array add the following service provider for this package.

Cartalyst\Stripe\Billing\Laravel\StripeServiceProvider::class,
Model setup

Add the Cartalyst\Stripe\Billing\Laravel\Billable to your Eloquent model and make sure that the model implements the Cartalyst\Stripe\Billing\Laravel\BillableContract:

<?php

use Illuminate\Database\Eloquent\Model;
use Cartalyst\Stripe\Billing\Laravel\Billable;
use Cartalyst\Stripe\Billing\Laravel\BillableContract;

class User extends Model implements BillableContract
{
    use Billable;

    /**
     * {@inheritdoc}
     */
    protected $table = 'users';
}
Migrations

Now you need to migrate your database, but before doing that, you'll need to generate the migrations that suits your billable table.

To do this you just need to run the following command and follow the instructions given on screen:

$ php artisan stripe:schema

Now that the migration files have been created all that's left to do is to run the php artisan migrate command to create the tables on your database.

Entity

Now that you have the billing package configured correctly, it's now time to set or even create a new Stripe customer and attach this customer to a billable entity.

Note: This is a required step as every billable entity needs to have a Stripe customer attached, otherwise you'll receive a BadRequestHttpException exception.

Attach a Customer

This method is useful when you already have an existing Stripe customer and you want to attach it to a billable entity:

// Get the entity object
$entity = User::find(1);

// Attach the Stripe customer to the entity
$entity->attachStripeCustomer('cus_5Nq3Ee9rD5wLde');

Now your billable entity has a valid Stripe customer attached :)

Create a new Customer

Creating a new Stripe customer and attaching it to a billable entity couldn't be any easier:

// Get the entity object
$entity = User::find(1);

// Create the Stripe customer
$entity->createStripeCustomer([
    'email' => $entity->email,
]);

If you want to create a new Stripe customer and set a coupon on the account you can call the withStripeDiscount() method and pass the coupon name as the first and only parameter:

// Get the entity object
$entity = User::find(1);

// Create the Stripe customer and set the given discount
$entity->withStripeDiscount('5OFF')->createStripeCustomer([
    'email' => $entity->email,
]);

Update a Customer

You can also update a Stripe customer, just call the updateStripeCustomer() method and pass an array with the parameters you wish to update:

// Get the entity object
$entity = User::find(1);

// Update the Stripe customer
$entity->updateStripeCustomer([
    'description' => 'This is a VIP customer!',
]);

Delete a Customer

There are situations where you might want to delete a Stripe customer, you can easily do that by doing:

// Get the entity object
$entity = User::find(1);

// Delete the Stripe customer
$entity->deleteStripeCustomer();

Note: This step is irreversible and it will delete all the account data from Stripe and from your local storage!!

General methods

In this section we'll cover some actions you can perform against your billable entity object.

Note We're covering most of these in this section as they don't fit on the other sections.

Determine if the entity is billable

This method is very useful when you need to determine if the entity is ready to be billed, or in other words, if the entity has a Stripe customer already attached.

Usage
// Get the entity object
$entity = User::find(1);

// Check if the entity is billable
if (! $entity->isBillable()) {
    echo "Entity is not ready to be billed!";
}

Determine if entity has a discount applied

Determine if the entity has a Stripe discount coupon applied

Usage
// Get the entity object
$entity = User::find(1);

// Check if the entity has a stripe discount applied
if (! $entity->hasStripeDiscount()) {
    echo "Entity doesn't have a Stripe discount applied.";
}

Apply a discount on the entity

Applies a coupon on the entity, this will execute a Stripe API call to apply the coupon on the Stripe customer that is attached to this entity.

Arguments
Key Required Type Default Description
$coupon true string null The coupon unique identifier.
Usage
// Get the submitted Stripe coupon
$coupon = Input::get('coupon');

// Get the entity object
$entity = User::find(1);

// Apply the coupon on the entity
$entity->applyStripeDiscount($coupon);

$entity->removeStripeDiscount()

Removes the coupon from the billable entity.

Usage
// Get the entity object
$entity = User::find(1);

// Apply the coupon on the entity
$entity->removeStripeDiscount();

Synchronize the entity

There are situations where you want to synchronize an entity with Stripe, we make this extremely easy for you.

You just need to call the syncWithStripe(); method on the entity:

Usage
// Get the entity object
$entity = User::find(1);

// Synchronize the entity with Stripe
$entity->syncWithStripe();

This will syncronize up the cards, charges, invoices and their invoice items, the pending invoice items and subscriptions that belongs to your entity.

Note: Due to the nature of this method, we highly recommend you to run this through a CLI, to avoid timeouts and interruptions.

Cards

You can store multiple cards on an Entity in order to charge the Entity later.

Create a card

When attaching a card to an entity, you can either pass a card token that was either created using Stripe.js or trough a Stripe Card Token or by passing an array with the card information.

Arguments

The following are the arguments that the create() method of the Card Gateway accepts.

Key Required Type Default Description
$card true string | array [] The card to attach.
$card

The following are the valid parameters that the $card argument accepts when being passed as an array.

Key Required Type Default Description
number true string null The card number, as a string without any spaces or separators.
exp_month true string | number null Two digit number representing the card's expiration month.
exp_year true string | number null Two or four digit number representing the card's expiration year.
cvc true string null The card's security code
name false string null The cardholder's full name.
address_line1 false string null The cardholder's address, line 1.
address_line2 false string null The cardholder's address, line 2.
address_city false string null The cardholder's address city.
address_zip false string null The cardholder's address zip.
address_state false string null The cardholder's address state.
address_country false string null The cardholder's address country.
Usage examples

Create a new card with a Stripe.js Token (recommended):

// Get the submitted Stripe token
$token = Input::get('stripe_token');

// Get the entity object
$entity = User::find(1);

// Create the card
$card = $entity->card()->create($token);

Note: The name of the stripe_token field might be different on your application!

Create a new card with a Stripe API Token:

// Create a new card token
$token = Stripe::tokens()->create([
    'card' => [
        'number'    => '4242424242424242',
        'exp_month' => 10,
        'cvc'       => 314,
        'exp_year'  => 2020,
    ],
]);

// Get the entity object
$entity = User::find(1);

// Create the card
$card = $entity->card()->create($token['id']);

Create a new card with an array:

// Get the entity object
$entity = User::find(1);

// Create the card
$card = $entity->card()->create([
    'number'    => '4242424242424242',
    'exp_month' => 10,
    'cvc'       => 314,
    'exp_year'  => 2020,
]);

Create a new card and set it as the default card:

If you want to attach a card to the entity and make it the default card, you need to use the makeDefault() method.

// Get the submitted Stripe token
$token = Input::get('stripe_token');

// Get the entity object
$entity = User::find(1);

// Create the card and make it default
$entity->card()->makeDefault()->create($token);

Retrieve a card

To retrieve an existing card that is attached to an entity all you're required to do is to call the find() method and pass the card id on the cards collection.

Usage examples
// Get the entity object
$entity = User::find(1);

// Find the card
$card = $entity->cards->find(10);

If a more robust search is required, you can use the normal Laravel Eloquent methods like where() etc..

// Get the entity object
$entity = User::find(1);

// Find the card
$card = $entity->cards()->where('stripe_id', 'card_15jFeqJvzVWl1WTeGu1fVIuB')->first();
Check if the card is expiring

In this example we'll be checking if the card is expiring in the upcoming month.

// Create a new Carbon object date
$date = Carbon\Carbon::now()->addMonth();

// Get the entity object
$entity = User::find(1);

// Find the card
$card = $entity->cards->find(10);

// Check if the card is expiring
if ($card->isExpiring($date)) {
    echo 'The card is going to expire next month!';
}
Check if the entity has active cards
// Get the entity object
$entity = User::find(1);

// Check if the entity has active cards
if (! $entity->hasActiveCards()) {
    echo "Entity doesn't have any active card!";
}
Get the entity default Card
// Get the entity object
$entity = User::find(1);

// Get the entity default card object
$card = $entity->getDefaultCard();

echo $card->last_four;

Card status

To determine if the card has expired, you may use the hasExpired() method:

// Get the entity object
$entity = User::find(1);

// Find the card
$card = $entity->cards->find(10);

if ($card->hasExpired() {
    echo 'The card has expired.';
}

To determine if the card is expiring, you may use isExpiring(:date) method:

// Get the entity object
$entity = User::find(1);

// Find the card
$card = $entity->cards->find(10);

// Create a new Carbon instance
$date = Carbon\Carbon::now()->addMonth();

if ($card->isExpiring($date)) {
    echo 'The card is going to expire next month.';
}

To determine if the card is the default card, you may use the isDefault() method:

// Get the entity object
$entity = User::find(1);

// Find the card
$card = $entity->cards->find(10);

if ($card->isDefault()) {
    echo 'This is the default card.';
}

Update a card

Updating a card is very easy.

Arguments

The following are the arguments that the update() method accepts

Key Required Type Default Description
$parameteres false array [] The card parameteres.
$parameteres

The following are the valid parameters that the $parameteres argument accepts.

Key Required Type Default Description
exp_month false string | number null Two digit number representing the card's expiration month.
exp_year false string | number null Two or four digit number representing the card's expiration year.
name false string null The cardholder's full name.
address_line1 false string null The cardholder's address, line 1.
address_line2 false string null The cardholder's address, line 2.
address_city false string null The cardholder's address city.
address_zip false string null The cardholder's address zip.
address_state false string null The cardholder's address state.
address_country false string null The cardholder's address country.
metadata false array [] A set of key/value pairs to attach to the card object.
Usage examples
// Get the entity object
$entity = User::find(1);

// Find the card to be updated
$card = $entity->cards->find(10);

// Update the card
$card->update([
    'name' => 'John Doe',
]);
Setting an existing card the default card.
$entity = User::find(1);

$entity->cards->find(10)->setDefault();
Update the entity default card

By default this method replaces the current default card with the given one, to override this behavior just pass a boolean of false as the second argument so it forces the card to not be deleted.

// Get the submitted Stripe token
$token = Input::get('stripe_token');

// Get the entity object
$entity = User::find(1);

// Update the card
$entity->updateDefaultCard($token);

Note: You can pass a Stripe token or an array, please check the create a card section for more information.

Delete a card

Deleting a card couldn't be more simple, just find the card you want to delete, and call the delete() method on the card object.

Usage example
// Get the entity object
$entity = User::find(1);

// Find the card to be deleted
$card = $entity->cards->find(10);

// Delete the card
$card->delete();

Retrieve all cards

To retrieve all cards that are attached to an entity all you're required to do is to call the cards collection, yeah, that simple.

Usage examples
// Get the entity object
$entity = User::find(1);

// Find the cards
$cards = $entity->cards;

If a more robust search is required, you can use the normal Laravel Eloquent methods like where(), orderBy() etc..

// Get the entity object
$entity = User::find(1);

// Find the cards
$cards = $entity->cards()->where('exp_year', '>=', '2014')->get();
Find all expired cards

There are cases where you might need to fetch all the expired cards:

// Get the entity object
$entity = User::find(1);

// Find all the expired cards
$cards = $entity->cards()->hasExpired()->get();
Find all non expired cards

You can also retrieve all the non expired cards too :)

// Get the entity object
$entity = User::find(1);

// Find all the cards that have not expired
$cards = $entity->cards()->hasNotExpired()->get();

Synchronization

Often you might have the need to synchronize the data from Stripe with your database, we have an easy way to achieve this.

This method synchronizes all the entity cards from Stripe into the local storage.

// Get the entity object
$entity = User::find(1);

// Synchronize this entity cards
$entity->card()->syncWithStripe();

Charges

To charge a credit or a debit card, you create a charge object. You can retrieve and refund individual charges as well as list all charges. Charges are identified by a unique random ID.

Creating a charge

To charge a credit card, you create a charge object. If your API key is in test mode, the supplied card won't actually be charged, though everything else will occur as if in live mode. (Stripe assumes that the charge would have completed successfully).

Arguments

The following are the arguments that the create() method of the Card Gateway accepts.

Key Required Type Default Description
$amount true number null The amount to charge.
$parameters false array [] The charge parameters.
$parameters

The following are the valid parameters that the $parameters argument accepts when being passed as an array.

token, currency
Key Required Type Default Description
description false string null An arbitrary string which you can attach to a charge object.
metadata false array [] A set of key/value pairs to attach to the charge object.
capture false bool true Whether or not to immediately capture the charge.
statement_descriptor false string null An arbitrary string to be displayed on your customer's credit card statement.
receipt_email false string null The email address to send this charge's receipt to.
application_fee false string null A fee in pence that will be applied to the charge and transferred to the application owner's Stripe account.
shipping false array [] Shipping information for the charge. Helps prevent fraud on charges for physical goods.
Usage examples
// Get the entity object
$entity = User::find(1);

// Create the charge
$charge = $entity
    ->charge()
    ->create(150.95, [
        'description' => 'Purchased Book!',
    ])
;

Creating a charge with a new credit card:

// Get the submitted Stripe token
$token = Input::get('stripe_token');

// Get the entity object
$entity = User::find(1);

// Create the charge
$charge = $entity
    ->charge()
    ->setToken($token)
    ->create(150.95, [
        'description' => 'Purchased Book!',
    ])
;

Creating a charge with a differnt currency:

// Get the entity object
$entity = User::find(1);

// Create the charge
$charge = $entity
    ->charge()
    ->setCurrency('eur')
    ->create(150.95, [
        'description' => 'Purchased Book!',
    ])
;

Creating a charge to be captured later:

// Get the entity object
$entity = User::find(1);

// Create the charge
$charge = $entity
    ->charge()
    ->captureLater()
    ->create(150.95, [
        'description' => 'Purchased Book!',
    ])
;

Retrieve a charge

To retrieve an existing charge that is attached to an entity all you're required to do is to call the find() method and pass the charge id on the charges collection.

Usage examples
// Get the entity object
$entity = User::find(1);

// Find the charge
$charge = $entity->charges->find(10);

If a more robust search is required, you can use the normal Laravel Eloquent methods like where() etc..

// Get the entity object
$entity = User::find(1);

// Find the charge
$charge = $entity->charges()->where('stripe_id', 'ch_15jaLgJvzVWl1WTeiY8u661R')->first();

Charge status

To determine if the charge is captured, you may use the isCaptured() method:

// Get the entity object
$entity = User::find(1);

// Find the charge
$charge = $entity->charges->find(10);

if (! $charge->isCaptured() {
    echo 'The charge is not captured.';
}

To determine if the charge can be captured, you may use the canBeCaptured() method:

// Get the entity object
$entity = User::find(1);

// Find the charge
$charge = $entity->charges->find(10);

if (! $charge->canBeCaptured() {
    echo "The charge can't be captured.";
}

To determine if the charge is paid, you may use the isPaid() method:

// Get the entity object
$entity = User::find(1);

// Find the charge
$charge = $entity->charges->find(10);

if (! $charge->isPaid() {
    echo 'The charge is not paid.';
}

To determine if the charge is partially refunded, you may use the isPartialRefunded() method:

// Get the entity object
$entity = User::find(1);

// Find the charge
$charge = $entity->charges->find(10);

if ($charge->isPartialRefunded() {
    echo 'The charge is partially refunded.';
}

To determine if the charge is refunded, you may use the isRefunded() method:

// Get the entity object
$entity = User::find(1);

// Find the charge
$charge = $entity->charges->find(10);

if (! $charge->isRefunded() {
    echo 'The charge is not refunded.';
}

Update a charge

Updating a charge is very easy.

Arguments

The following are the arguments that the update() method accepts

Key Required Type Default Description
$parameters false array [] The charge parameters.
$parameters

The following are the valid parameters that the $parameters argument accepts when being passed as an array.

Key Required Type Default Description
description false string null An arbitrary string which you can attach to a charge object.
metadata false array [] A set of key/value pairs to attach to the charge object.
receipt_email false string null The email address to send this charge's receipt to.
application_fee false string null A fee in pence that will be applied to the charge and transferred to the application owner's Stripe account.
fraud_details false array [] A set of key/value pairs you can attach to a charge giving information about its riskiness.
Usage example
// Get the entity object
$entity = User::find(1);

// Find the charge to be updated
$charge = $entity->charges->find(10);

// Update the charge
$charge->update([
    'description' => 'Purchased Book!',
]);

Capture a charge

Capture the payment of an existing, uncaptured, charge.

Arguments

The following are the arguments that the capture() method accepts

Key Required Type Default Description
$amount false number null The amount to capture, which must be less than or equal to the original amount. Any additional amount will be automatically refunded.
$parameters false array [] The charge parameters.
$parameters

The following are the valid parameters that the $parameters argument accepts when being passed as an array.

Key Required Type Default Description
application_fee false string null An application fee to add on to this charge. Can only be used with Stripe Connect.
receipt_email false string null The email address to send this charge’s receipt to.
statement_descriptor false string null An arbitrary string to be displayed on your customer’s credit card statement.
Usage examples

Capture the entire charge:

// Get the entity object
$entity = User::find(1);

// Find the charge
$charge = $entity->charges->find(10);

// Capture the charge
$charge->capture();

Capture a charge of a given amount:

// Get the entity object
$entity = User::find(1);

// Find the charge
$charge = $entity->charges->find(10);

// Capture the charge
$charge->capture(23.49);

Retrieve all charges

To retrieve all charges that are attached to an entity all you're required to do is to call the charges collection, yeah, that simple.

Usage examples
// Get the entity object
$entity = User::find(1);

// Find the charges
$charges = $entity->charges;

If a more robust search is required, you can use the normal Laravel Eloquent methods like where(), orderBy() etc..

// Get the entity object
$entity = User::find(1);

// Find the charges
$charges = $entity->charges()->orderBy('created_at', 'desc')->get();
Find all uncaptured charges

There are cases where you might need to fetch all the uncaptured charges:

// Get the entity object
$entity = User::find(1);

// Find all the expired charges
$charges = $entity->charges()->uncaptured()->get();
Find all captured charges

You can also retrieve all the captured charges too :)

// Get the entity object
$entity = User::find(1);

// Find all the charges that have not expired
$charges = $entity->charges()->captured()->get();

Synchronization

Often you might have the need to synchronize the data from Stripe with your database, we have an easy way to achieve this.

This method synchronizes all the entity charges from Stripe into the local storage.

// Get the entity object
$entity = User::find(1);

// Synchronize this entity charges
$entity->charge()->syncWithStripe();

Refunds

Refund objects allow you to refund a charge that has previously been created but not yet refunded. Funds will be refunded to the credit or debit card that was originally charged. The fees you were originally charged are also refunded.

Create a refund

Creating a new refund will refund a charge that has previously been created but not yet refunded. Funds will be refunded to the credit or debit card that was originally charged. The fees you were originally charged are also refunded.

Arguments

The following are the arguments that the update() method accepts

Key Required Type Default Description
$amount false number null The amount to refund.
$parameters false array [] The charge parameters.
$parameters

The following are the valid parameters that the $parameters argument accepts when being passed as an array.

Key Required Type Default Description
refund_application_fee false string null Boolean indicating whether the application fee should be refunded when refunding this charge.
reason false boolean false String indicating the reason for the refund. If set, possible values are `duplicate`, `fraudulent`, and `requested_by_customer`.
metadata false array [] A set of key/value pairs to attach to the charge object.
Usage examples

Do a full refund

// Get the entity object
$entity = User::find(1);

// Find the charge
$charge = $entity->charges->find(10);

// Refund the charge
$charge->refund();

Do a partial refund

// Get the entity object
$entity = User::find(1);

// Find the charge
$charge = $entity->charges->find(10);

// Refund the charge
$charge->refund(50.00);

Retrieve a refund

To retrieve an existing charge refund call the find() method and pass the refund id on the refunds collection.

Usage examples
// Get the entity object
$entity = User::find(1);

// Find the charge
$charge = $entity->charges->find(10);

// Find the refund
$refund = $charge->refunds->find(2020);

If a more robust search is required, you can use the normal Laravel Eloquent methods like where() etc..

// Get the entity object
$entity = User::find(1);

// Find the charge
$charge = $entity->charges->find(10);

// Find the refund
$refund = $entity->refunds()->where('stripe_id', 're_15iBdsJvzVWl1WTevOaPONHV')->first();

Update a refund

Updating a refund is very easy.

Arguments

The following are the arguments that the update() method accepts

Key Required Type Default Description
$metadata false array [] The refund metadata.

Note: Only the metadata can be updated on refunds.

Usage example
// Get the entity object
$entity = User::find(1);

// Find the charge
$charge = $entity->charges->find(10);

// Find the refund to be updated
$refund = $charge->refunds->find(2020);

// Update the refund
$refund->update([
    'key' => 'value',
]);

Retrieve all refunds

To retrieve all refunds that are attached to a charge all you're required to do is to call the refunds collection, yeah, that simple.

Usage examples
// Get the entity object
$entity = User::find(1);

// Find the charge
$charge = $entity->charges->find(10);

// Find the refunds
$refunds = $charge->refunds;

If a more robust search is required, you can use the normal Laravel Eloquent methods like where(), orderBy() etc..

// Get the entity object
$entity = User::find(1);

// Find the charge
$charge = $entity->charges->find(10);

// Find the refunds
$refunds = $charge->refunds()->orderBy('created_at', 'desc')->get();

Subscriptions

Subscriptions allow you to charge a customer's card on a recurring basis. A subscription ties a customer to a particular plan you've created.

Create a subscription

Subscribing an entity to a plan:

// Get the entity object
$entity = User::find(1);

// Create the subscription
$entity
    ->subscription()
    ->onPlan('monthly')
    ->create()
;

Subscribing an entity to a plan using a new card:

// Get the submitted Stripe token
$token = Input::get('stripe_token');

// Get the entity object
$entity = User::find(1);

// Create the subscription
$entity
    ->subscription()
    ->onPlan('monthly')
    ->setToken($token)
    ->create()
;

Subscribing an entity to a plan and apply a coupon to this new subscription:

// Get the submitted coupon
$coupon = Input::get('coupon');

// Get the entity object
$entity = User::find(1);

// Create the subscription
$entity
    ->subscription()
    ->onPlan('monthly')
    ->withDiscount($coupon)
    ->create()
;

Create a trial subscription:

// Get the entity object
$entity = User::find(1);

// Create the subscription
$entity
    ->subscription()
    ->onPlan('monthly')
    ->trialFor(Carbon::now()->addDays(14))
    ->create()
;

Retrieve a subscription

To retrieve an existing subscription that is attached to an entity all you're required to do is to call the find() method and pass the subscription id on the subscriptions collection.

Usage examples
// Get the entity object
$entity = User::find(1);

// Find the subscription
$subscription = $entity->subscriptions->find(10);

If a more robust search is required, you can use the normal Laravel Eloquent methods like where() etc..

// Get the entity object
$entity = User::find(1);

// Find the subscription
$subscription = $entity->subscriptions()->where('stripe_id', 'sub_5vp6DX7N6yVJqY')->first();

Check if the entity has active subscriptions

You can check if an entity has active subscriptions by calling the isSubscribed() method on the entity object:

Usage
// Get the entity object
$entity = User::find(1);

// Check if the entity has any active subscription
if ($entity->isSubscribed()) {
    echo 'Entity has at least one active subscription!';
}

Subscription status

To determine if the subscription is on the trial period, you may use the onTrialPeriod() method:

// Get the entity object
$entity = User::find(1);

// Find the subscription
$subscription = $entity->subscriptions->find(10);

if ($subscription->onTrialPeriod()) {
    echo "Subscription is on trial period from {$subscription->trial_starts_at} to {$subscription->trial_ends_at}!";
}

To determine if the subscription is marked as canceled, you may use the isCanceled() method:

// Get the entity object
$entity = User::find(1);

// Find the subscription
$subscription = $entity->subscriptions->find(10);

if ($subscription->isCanceled()) {
    echo "Subscription was canceled on {$subscription->canceled_at}!";
}

To determine if the subscription has expired, you may use the isExpired() method:

// Get the entity object
$entity = User::find(1);

// Find the subscription
$subscription = $entity->subscriptions->find(10);

if ($subscription->isExpired()) {
    echo "Subscription has expired on {$subscription->ended_at}!";
}

To determine if a subscription is still on their "grace period" until the subscription fully expires. For example, if a user cancels a subscription on March 5th that was scheduled to end on March 10th, the user is on their "grace period" until March 10th.

// Get the entity object
$entity = User::find(1);

// Find the subscription
$subscription = $entity->subscriptions->find(10);

if ($subscription->onGracePeriod()) {
    echo "Subscription is on it's grace period until {$subscription->period_ends_at}.";
}

Update a subscription

Swap the current subscription plan to another

// Get the entity object
$entity = User::find(1);

// Find the subscription
$subscription = $entity->subscriptions->find(10);

// Swap the subscription plan
$subscription->swap('new-plan-name');

Apply a trial period on a subscription

// Get the entity object
$entity = User::find(1);

// Find the subscription
$subscription = $entity->subscriptions->find(10);

// Create a new Carbon instance
$trialPeriod = Carbon::now()->addDays(14);

// Set the trial on the subscription
$subscription->applyTrialPeriod($trialPeriod);

Removing the trial period from a subscription

// Get the entity object
$entity = User::find(1);

// Find the subscription
$subscription = $entity->subscriptions->find(10);

// Remove the trial from the subscription
$subscription->removeTrialPeriod();

Apply a coupon to an existing subscription

// Get the submitted coupon
$coupon = Input::get('coupon');

// Get the entity object
$entity = User::find(1);

// Find the subscription
$subscription = $entity->subscriptions->find(10);

// Apply the coupon
$subscription->applyCoupon($coupon);

Remove a coupon from an existing subscription

// Get the entity object
$entity = User::find(1);

// Find the subscription
$subscription = $entity->subscriptions->find(10);

// Remove the coupon
$subscription->removeCoupon();

Cancel a subscription

Cancel an active subscription.

// Get the entity object
$entity = User::find(1);

// Find the subscription
$subscription = $entity->subscriptions->find(10);

// Cancel the subscription
$subscription->cancel();

Cancel a subscription at the end of the billing period

// Get the entity object
$entity = User::find(1);

// Find the subscription
$subscription = $entity->subscriptions->find(10);

// Cancel the subscription
$subscription->cancelAtPeriodEnd();

Resume a subscription

Resume a canceled subscription

// Get the entity object
$entity = User::find(1);

// Find the subscription
$subscription = $entity->subscriptions->find(10);

// Resume the subscription
$subscription->resume();

Resume a canceled subscription and remove its trial period

// Get the entity object
$entity = User::find(1);

// Find the subscription
$subscription = $entity->subscriptions->find(10);

// Skip the trial period and resume the subscription
$subscription->skipTrial()->resume();

Resume a canceled subscription and change its trial period end date

// Get the entity object
$entity = User::find(1);

// Find the subscription
$subscription = $entity->subscriptions->find(10);

// Create a new Carbon instance
$trialPeriod = Carbon::now()->addDays(14);

// Set the trial period and resume the subscription
$subscription->trialFor($trialPeriod)->resume();

Retrieve all subscriptions

To retrieve all subscriptions that are attached to an entity all you're required to do is to call the subscriptions collection, yeah, that simple.

Usage examples
// Get the entity object
$entity = User::find(1);

// Find the subscriptions
$subscriptions = $entity->subscriptions;

If a more robust search is required, you can use the normal Laravel Eloquent methods like where(), orderBy() etc..

// Get the entity object
$entity = User::find(1);

// Find the subscriptions
$subscriptions = $entity->subscriptions()->orderBy('created_at', 'desc')->get();
Find all expired subscriptions

There are cases where you might need to fetch all the expired subscriptions:

// Get the entity object
$entity = User::find(1);

// Find all the expired subscriptions
$subscriptions = $entity->subscriptions()->expired()->get();

Synchronization

Often you might have the need to synchronize the data from Stripe with your database, we have an easy way to achieve this.

This method synchronizes all the entity subscriptions from Stripe into the local storage.

// Get the entity object
$entity = User::find(1);

// Synchronize this entity subscriptions
$entity->subscription()->syncWithStripe();

Invoices

Invoices are statements of what a customer owes for a particular billing period, including subscriptions, invoice items, and any automatic proration adjustments if necessary.

Create an invoice

If you need to invoice your customer outside the regular billing cycle, you can create an invoice that pulls in all pending invoice items, including prorations. The customer's billing cycle and regular subscription won't be affected.

Once you create the invoice, it'll be picked up and paid automatically, though you can choose to pay it right away.

Arguments

The following are the arguments that the create() method of the Invoice Gateway accepts.

Key Required Type Default Description
$parameters false array [] The invoice item parameters.
$parameters

The following are the valid parameters that the $parameters argument accepts when being passed as an array.

Key Required Type Default Description
items false array [] The items to be created with this invoice.
application_fee false string null A fee in pence that will be applied to the invoice and transferred to the application owner's Stripe account.
description false string null An arbitrary string which you can attach to a invoice item object.
metadata false array [] A set of key/value pairs to attach to the invoice object.
statement_descriptor false string null An arbitrary string to be displayed on your customer's credit card statement.
subscription false string null The ID of a subscription to add this invoice item to.
tax_percent false number null The percent tax rate applied to the invoice, represented as a decimal number.
Usage examples
// Get the entity object
$entity = User::find(1);

// Create the invoice
$invoice = $entity->invoice()->create();

Create a new invoice and set the items for this invoice:

// Get the entity object
$entity = User::find(1);

// Create the invoice
$invoice = $entity
    ->invoice()
    ->setItems($items)
    ->create()
;

Create a new invoice and set the currency for the invoice items:

// Get the entity object
$entity = User::find(1);

// Create the invoice
$invoice = $entity
    ->invoice()
    ->setCurrency('usd')
    ->create()
;

Create a new invoice for a specific subscription:

// Get the entity object
$entity = User::find(1);

// Create the invoice
$invoice = $entity
    ->invoice()
    ->setSubcription('sub_5vp6DX7N6yVJqY')
    ->create()
;

Retrieve a invoice

To retrieve an existing invoice that is attached to an entity all you're required to do is to call the find() method and pass the invoice id on the invoices collection.

Usage
// Get the entity object
$entity = User::find(1);

// Find the invoice
$invoice = $entity->invoices->find(10);

If a more robust search is required, you can use the normal Laravel Eloquent methods like where() etc..

// Get the entity object
$entity = User::find(1);

// Find the invoice
$invoice = $entity->invoices()->where('stripe_id', 'in_15kPp3JvzVWl1WTe4KBHXGqK')->first();

Invoice status

To determine if the invoice is closed, you may use the isClosed() method:

// Get the entity object
$entity = User::find(1);

// Find the invoice
$invoice = $entity->invoices->find(10);

if (! $invoice->isClosed() {
    echo 'The invoice is not closed.';
}

To determine if the invoice is paid, you may use the isPaid() method:

// Get the entity object
$entity = User::find(1);

// Find the invoice
$invoice = $entity->invoices->find(10);

if (! $invoice->isPaid() {
    echo 'The invoice is not paid.';
}

Update an invoice

Until an invoice is paid, it is marked as open (closed=false). If you'd like to stop Stripe from automatically attempting payment on an invoice or would simply like to close the invoice out as no longer owed by the customer, you can update the closed parameter.

Arguments

The following are the arguments that the create() method of the Invoice Gateway accepts.

Key Required Type Default Description
$parameters false array [] The invoice item parameters.
$parameters

The following are the valid parameters that the $parameters argument accepts when being passed as an array.

Key Required Type Default Description
application_fee false string null A fee in pence that will be applied to the invoice and transferred to the application owner's Stripe account.
closed false boolean null Boolean representing whether an invoice is closed or not. To close an invoice, pass true.
description false string null An arbitrary string which you can attach to a invoice item object.
forgiven false boolean null Boolean representing whether an invoice is forgiven or not.
metadata false array [] A set of key/value pairs to attach to the invoice object.
statement_descriptor false string null An arbitrary string to be displayed on your customer's credit card statement.
subscription false string null The ID of a subscription to add this invoice item to.
tax_percent false number null The percent tax rate applied to the invoice, represented as a decimal number.
Usage example
// Get the entity object
$entity = User::find(1);

// Find the invoice
$invoice = $entity->invoices->find(10);

// Update the invoice
$invoice->update([
    'closed' => true,
]);

Pay an invoice

Stripe automatically creates and then attempts to pay invoices for customers on subscriptions. We'll also retry unpaid invoices according to your retry settings. However, if you'd like to attempt to collect payment on an invoice out of the normal retry schedule or for some other reason, you can do so.

Usage example
// Get the entity object
$entity = User::find(1);

// Find the invoice
$invoice = $entity->invoices->find(10);

if (! $invoice->isPaid()) {
    // Pay the invoice
    $invoice->pay();
}

Retrieve all invoices

To retrieve all invoices that are attached to an entity all you're required to do is to call the invoices collection, yeah, that simple.

Usage
// Get the entity object
$entity = User::find(1);

// Find the invoices
$invoices = $entity->invoices;

If a more robust search is required, you can use the normal Laravel Eloquent methods like where(), orderBy() etc..

// Get the entity object
$entity = User::find(1);

// Find the invoices
$invoices = $entity->invoices()->orderBy('created_at', 'desc')->get();

Synchronization

Often you might have the need to synchronize the data from Stripe with your database, we have an easy way to achieve this.

This method synchronizes all the entity invoices from Stripe into the local storage.

// Get the entity object
$entity = User::find(1);

// Synchronize this entity invoices
$entity->invoice()->syncWithStripe();

Invoice Items

Sometimes you want to add a charge or credit to a customer but only actually charge the customer's card at the end of a regular billing cycle. This is useful for combining several charges to minimize per-transaction fees or having Stripe tabulate your usage-based billing totals.

Create an invoice item

Adds an arbitrary charge or credit to the customer's upcoming invoice.

Arguments

The following are the arguments that the create() method of the Invoice Item Gateway accepts.

Key Required Type Default Description
$amount true number null The amount to charge.
$parameters false array [] The invoice item parameters.
$parameters

The following are the valid parameters that the $parameters argument accepts when being passed as an array.

Key Required Type Default Description
currency false string USD Currency in which the invoice item will be created.
invoice false string null The ID of an existing invoice to add this invoice item to.
subscription false string null The ID of a subscription to add this invoice item to.
description false string null An arbitrary string which you can attach to a invoice item object.
discountable false boolean false Controls whether discounts apply to this invoice item.
metadata false array [] A set of key/value pairs to attach to the charge object.
Usage examples
// Get the entity object
$entity = User::find(1);

// Create the invoice item
$invoiceItem = $entity->invoiceItem()->create(12.50);

Create a new invoice item for a different currency:

// Get the entity object
$entity = User::find(1);

// Create the invoice item
$invoiceItem = $entity
    ->invoiceItem()
    ->setCurrency('usd')
    ->create(12.50)
;

Create a new invoice item for a specific subscription:

// Get the entity object
$entity = User::find(1);

// Create the invoice item
$invoiceItem = $entity
    ->invoiceItem()
    ->setSubcription('sub_5vp6DX7N6yVJqY')
    ->create(12.50)
;

Retrieve an invoice item

To retrieve an existing invoice item that is attached to an entity all you're required to do is to call the find() method and pass the charge id on the invoiceItems collection.

Usage examples
// Get the entity object
$entity = User::find(1);

// Find the invoice item
$invoiceItem = $entity->invoiceItems->find(10);

If a more robust search is required, you can use the normal Laravel Eloquent methods like where() etc..

// Get the entity object
$entity = User::find(1);

// Find the invoice item
$invoiceItem = $entity->invoiceItems()->where('stripe_id', 'ch_15jaLgJvzVWl1WTeiY8u661R')->first();

Update an invoice item

Updating an invoice item is very easy.

Arguments

The following are the arguments that the update() method accepts

Key Required Type Default Description
$parameteres false array [] The invoice item parameteres.
$parameteres

The following are the valid parameters that the $parameteres argument accepts.

Key Required Type Default Description
amount false number null The amount to charge.
description false string null An arbitrary string which you can attach to a invoice item object.
discountable false boolean false Controls whether discounts apply to this invoice item.
metadata false array [] A set of key/value pairs to attach to the charge object.
Usage example
// Get the entity object
$entity = User::find(1);

// Find the invoice item to be updated
$invoiceItem = $entity->invoiceItems->find(10);

// Update the invoice item
$invoiceItem->update([
    'amount' => 50.99,
]);

Delete an invoice item

Deleting an invoice item couldn't be more simple, just find the invoice item you want to delete, and call the delete() method on the invoice item object.

Usage example
// Get the entity object
$entity = User::find(1);

// Find the invoice item to be deleted
$invoiceItem = $entity->invoiceItems->find(10);

// Delete the invoice item
$invoiceItem->delete();

Retrieve all invoice items

To retrieve all invoice items that are attached to an entity all you're required to do is to call the invoiceItems collection, yeah, that simple.

Usage examples
// Get the entity object
$entity = User::find(1);

// Find the invoice items
$invoiceItems = $entity->invoiceItems;

If a more robust search is required, you can use the normal Laravel Eloquent methods like where(), orderBy() etc..

// Get the entity object
$entity = User::find(1);

// Find the invoice items
$invoiceItems = $entity->invoiceItems()->orderBy('created_at', 'desc')->get();

Events

On this section we have a list of all the events fired by the Stripe Billing for Laravel that you can listen for on your application.

Event Parameters Description
cartalyst.stripe.card.created $entity, $card, $response Event fired when a new credit card is attached to the entity.
cartalyst.stripe.card.updated $entity, $card, $response Event fired when an existing credit card is updated.
cartalyst.stripe.card.deleted $entity, $card Event fired when an existing credit card is deleted.
cartalyst.stripe.charge.created $entity, $charge, $response Event fired when a new charge is created.
cartalyst.stripe.charge.updated $entity, $charge, $response Event fired when an existing charge is updated.
cartalyst.stripe.charge.refund.created $entity, $chargeRefund, $response Event fired when a charge refund is created.
cartalyst.stripe.charge.refund.updated $entity, $chargeRefund, $response Event fired when an existing charge refund is updated.
cartalyst.stripe.invoice.created $entity, $invoice, $response Event fired when a new invoice is attached to the entity.
cartalyst.stripe.invoice.updated $entity, $invoice, $response Event fired when an existing invoice is updated.
cartalyst.stripe.invoice.paid $entity, $invoice, $response Event fired when an existing invoice is paid.
cartalyst.stripe.invoice.item.created $entity, $invoiceItem, $response Event fired when a new invoice item is created.
cartalyst.stripe.invoice.item.updated $entity, $invoiceItem, $response Event fired when an existing invoice item is updated.
cartalyst.stripe.invoice.item.deleted $entity, $invoiceItem Event fired when an existing invoice item is deleted.
cartalyst.stripe.subscription.created $entity, $subscription, $response Event fired when a new subscription is attached to the entity.
cartalyst.stripe.subscription.updated $entity, $subscription, $response Event fired when an existing subscription is updated.
cartalyst.stripe.subscription.canceled $entity, $subscription, $response Event fired when an existing subscription is canceled.
cartalyst.stripe.subscription.resumed $entity, $subscription, $response Event fired when an existing subscription is resumed.

Note: Please refer to the list below for the FQCN event parameter object.

Parameter Response
$entity Cartalyst\Stripe\Billing\Laravel\BillingContract
$response array
$card Cartalyst\Stripe\Billing\Laravel\Card\CardContract
$charge Cartalyst\Stripe\Billing\Laravel\Charge\ChargeContract
$chargeRefund Cartalyst\Stripe\Billing\Laravel\ChargeRefund\ChargeRefundContract
$invoice Cartalyst\Stripe\Billing\Laravel\Invoice\InvoiceContract
$invoiceItem Cartalyst\Stripe\Billing\Laravel\InvoiceItem\InvoiceItemContract
$subscription Cartalyst\Stripe\Billing\Laravel\Subscription\SubscriptionContract

Examples

Whenever a new subscription is attached to an entity.

use Cartalyst\Stripe\Billing\Laravel\BillingContract;
use Cartalyst\Stripe\Billing\Laravel\Subscription\SubscriptionContract;

Event::listen('cartalyst.stripe.subscription.created', function(BillingContract $entity, $response, SubscriptionContract $subscription) {
    // Apply your own logic here
});

Whenever an existing subscription is canceled.

use Cartalyst\Stripe\Billing\Laravel\BillingContract;
use Cartalyst\Stripe\Billing\Laravel\Subscription\SubscriptionContract;

Event::listen('cartalyst.stripe.subscription.canceled', function(BillingContract $entity, $response, SubscriptionContract $subscription) {
    // Apply your own logic here
});

Whenever an existing subscription is resumed.

use Cartalyst\Stripe\Billing\Laravel\BillingContract;
use Cartalyst\Stripe\Billing\Laravel\Subscription\SubscriptionContract;

Event::listen('cartalyst.stripe.subscription.resumed', function(BillingContract $entity, $response, Subscription $subscription) {
    // Apply your own logic here
});

Overriding

If you ever have the need to override a billable model or even a gateway to introduce custom methods or a different workflow, you can achieve that in an extremely easy way as we provide handy methods you can utilise with your entity in case you require extra functionality.

Models

To override a model, you'll need to first create the model you want to override and this model needs to extend the base model to override, here's an example on how to do it:

<?php

namespace App\Models\Card;

use Cartalyst\Stripe\Billing\Laravel\Card\Card as Model;

class Card extends Model
{
    // You can create any new methods here or if
    // required, you can override any existing
    // method to apply your custom features.
}

Note: Please use the list below for a complete list of models namespace paths.

Models list

Model Name FQCN
Card Cartalyst\Stripe\Billing\Laravel\Card\Card
Charge Cartalyst\Stripe\Billing\Laravel\Charge\Charge
ChargeRefund Cartalyst\Stripe\Billing\Laravel\ChargeRefund\ChargeRefund
Invoice Cartalyst\Stripe\Billing\Laravel\Invoice\Invoice
InvoiceItem Cartalyst\Stripe\Billing\Laravel\InvoiceItem\InvoiceItem
Subscription Cartalyst\Stripe\Billing\Laravel\Subscription\Subscription

Set the models

Now that you've the model(s) created, it's time to set them.

This can be done where you see it's more appropriate inside your application, as an example, you can do this through a Service Provider, this is mainly to ensure you only apply these changes once per request!

Note: We recommended that this should be done the earlier as you can on your application.

setCardModel()

This method will change the card model on the entity.

User::setCardModel('App\Models\Card');
setChargeModel()

This method will change the charge model on the entity.

User::setChargeModel('App\Models\Charge');
setChargeRefundModel()

This method will change the charge refunds model on the entity.

User::setChargeRefundModel('App\Models\ChargeRefund');
setInvoiceModel()

This method will change the invoice model on the entity.

User::setInvoiceModel('App\Models\Invoice');
setInvoiceItemModel()

This method will change the invoice items model on the entity.

User::setInvoiceItemModel('App\Models\InvoiceItem');
setSubscriptionModel()

This method will change the subscription model on the entity.

User::setSubscriptionModel('App\Models\Subscription');

Gateways

To override a gateway, you'll need to first create the gateway you want to override and this gateway needs to extend the base gateway to override, here's an example on how to do it:

<?php

namespace App\Models\Card;

use Cartalyst\Stripe\Billing\Laravel\Card\Card as Model;

class Card extends Model
{
    // You can create any new methods here or if
    // required, you can override any existing
    // method to apply your custom features.
}

Note: Please use the list below for a complete list of gateways namespace paths.

Gateways list

Gateway Name FQCN
Card Cartalyst\Stripe\Billing\Laravel\Card\CardGateway
Charge Cartalyst\Stripe\Billing\Laravel\Charge\ChargeGateway
ChargeRefund Cartalyst\Stripe\Billing\Laravel\ChargeRefund\ChargeRefundGateway
Invoice Cartalyst\Stripe\Billing\Laravel\Invoice\InvoiceGateway
InvoiceItem Cartalyst\Stripe\Billing\Laravel\InvoiceItem\InvoiceItemGateway
Subscription Cartalyst\Stripe\Billing\Laravel\Subscription\SubscriptionGateway

Set the gateways

Now that you've the gateway(s) created, it's time to set them.

This can be done where you see it's more appropriate inside your application, as an example, you can do this through a Service Provider, this is mainly to ensure you only apply these changes once per request!

Note: We recommended that this should be done the earlier as you can on your application.

setCardGateway()

This method will change the card gateway on the entity.

User::setCardGateway('App\Gateways\Card');
setChargeGateway()

This method will change the charge gateway on the entity.

User::setChargeGateway('App\Gateways\Charge');
setChargeRefundGateway()

This method will change the charge refunds gateway on the entity.

User::setChargeRefundGateway('App\Gateways\ChargeRefund');
setInvoiceGateway()

This method will change the invoice gateway on the entity.

User::setInvoiceGateway('App\Gateways\Invoice');
setInvoiceItemGateway()

This method will change the invoice items gateway on the entity.

User::setInvoiceItemGateway('App\Gateways\InvoiceItem');
setSubscriptionGateway()

This method will change the subscription gateway on the entity.

User::setSubscriptionGateway('App\Gateways\Subscription');

Webhooks

Listening to Stripe notification events (Webhooks) is incredible easy and you can listen to any notification that Stripe sends.

Setup

First create a new controller somewhere inside your application that extends our Cartalyst\Stripe\Billing\Laravel\Controllers\WebhookController controller.

<?php

namespace App\Controllers;

use Cartalyst\Stripe\Billing\Laravel\Controllers\WebhookController as BaseWebhookController;

class WebhookController extends BaseWebhookController
{

}

Note: The controller name and namespace is just for the example, you can name and place the controller where it fits best inside your application.

Now you need to register a post route that points to your controller:

Route::post('webhook/stripe', [ 'as' => 'stripe.webhook', 'uses' => 'App\Controllers\WebhookController@handleWebhook' ]);

Note: The route URI webhook/stripe and it's name stripe.webhook is just for the example, you can set the route how you see fit, just make sure it uses the handleWebhook method and is a POST route.

Once you have the route registered, you'll need to go into your Stripe.com Dashboard and setup the webhook.

Handling events

Now you just need to create the notification event handlers inside the webhook controller. We have a few examples prepared below:

<?php

namespace App\Controllers;

use Cartalyst\Stripe\Billing\Laravel\Controllers\WebhookController as BaseWebhookController;

class WebhookController extends BaseWebhookController
{
    /**
     * Handles a successful payment.
     *
     * @param  array  $payload
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function handleChargeSucceeded(array $payload)
    {
        $charge = $this->handlePayment($payload);

        // apply your own logic here if required

        return $this->sendResponse('Webhook successfully handled.');
    }

    /**
     * Handles a failed payment.
     *
     * @param  array  $payload
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function handleChargeFailed(array $payload)
    {
        $charge = $this->handlePayment($payload);

        // apply your own logic here if required

        return $this->sendResponse('Webhook successfully handled.');
    }

    /**
     * Handles a payment refund.
     *
     * @param  array  $payload
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function handleChargeRefunded(array $payload)
    {
        $charge = $this->handlePayment($payload);

        // apply your own logic here if required

        return $this->sendResponse('Webhook successfully handled.');
    }

    /**
     * Handles the payment event.
     *
     * @param  array  $charge
     * @return \Cartalyst\Stripe\Billing\Models\IlluminateCharge
     */
    protected function handlePayment(array $charge)
    {
        $entity = $this->getBillable($charge['customer']);

        $entity->charge()->syncWithStripe();

        return $entity->charges()->whereStripeId($charge['id'])->first();
    }
}

Note 1: The examples above are merely for demonstration, you can apply your own logic for each event notification, we're just showing the power of the synchronization methods the Stripe Billing for Laravel has to offer :)

Note 2: Please refer to the list below for all the events that Stripe sends and to know how you should name your handler methods inside your controller.

Types of Events

Below is a complete list of all the webhook type events that Stripe sends.

Note: Please note that we're covering in the list below the proper method name you should use on your webhook controller.

Stripe Event Name Controller Method Name Description
account.updated handleAccountUpdated Occurs whenever an account status or property has changed.
account.application.deauthorized handleAccountApplicationDeauthorized Occurs whenever a user deauthorizes an application. Sent to the related application only.
application_fee.created handleApplicationFeeCreated Occurs whenever an application fee is created on a charge.
application_fee.refunded handleBalanceAvailable Occurs whenever your Stripe balance has been updated (e.g. when a charge collected is available to be paid out). By default, Stripe will automatically transfer any funds in your balance to your bank account on a daily basis.
charge.succeeded handleChargeSucceeded Occurs whenever a new charge is created and is successful.
charge.failed handleChargeFailed Occurs whenever a failed charge attempt occurs.
charge.refunded handleChargeRefunded Occurs whenever a charge is refunded, including partial refunds.
charge.captured handleChargeCaptured Occurs whenever a previously uncaptured charge is captured.
charge.updated handleChargeUpdated Occurs whenever a charge description or metadata is updated.
charge.dispute.created handleChargeDisputeCreated Occurs whenever a customer disputes a charge with their bank (chargeback).
charge.dispute.updated handleChargeDisputeUpdated Occurs when the dispute is updated (usually with evidence).
charge.dispute.closed handleChargeDisputeClosed Occurs when the dispute is resolved and the dispute status changes to won or lost.
customer.created handleCustomerCreated Occurs whenever a new customer is created.
customer.updated handleCustomerUpdated Occurs whenever any property of a customer changes.
customer.deleted handleCustomerDeleted Occurs whenever a customer is deleted.
customer.card.created handleCustomerCardCreated Occurs whenever a new card is created for the customer.
customer.card.updated handleCustomerCardUpdated Occurs whenever a card's details are changed.
customer.card.deleted handleCustomerCardDeleted Occurs whenever a card is removed from a customer.
customer.subscription.created handleCustomerSubscriptionCreated Occurs whenever a customer with no subscription is signed up for a plan.
customer.subscription.updated handleCustomerSubscriptionUpdated Occurs whenever a subscription changes. Examples would include switching from one plan to another, or switching status from trial to active.
customer.subscription.deleted handleCustomerSubscriptionDeleted Occurs whenever a customer ends their subscription.
customer.subscription.trialwillend handleCustomerSubscriptionTrialWillEnd Occurs three days before the trial period of a subscription is scheduled to end.
customer.discount.created handleCustomerDiscountCreated Occurs whenever a coupon is attached to a customer.
customer.discount.updated handleCustomerDiscountUpdated Occurs whenever a customer is switched from one coupon to another.
customer.discount.deleted handleCustomerDiscountDeleted Occurs whenever a customer's discount is removed.
invoice.created handleInvoiceCreated Occurs whenever a new invoice is created. If you are using webhooks, Stripe will wait one hour after they have all succeeded to attempt to pay the invoice; the only exception here is on the first invoice, which gets created and paid immediately when you subscribe a customer to a plan. If your webhooks do not all respond successfully, Stripe will continue retrying the webhooks every hour and will not attempt to pay the invoice. After 3 days, Stripe will attempt to pay the invoice regardless of whether or not your webhooks have succeeded. See how to respond to a webhook.
invoice.updated handleInvoiceUpdated Occurs whenever an invoice changes (for example, the amount could change).
invoice.payment_succeeded handleInvoicePaymentSucceeded Occurs whenever an invoice attempts to be paid, and the payment succeeds.
invoice.payment_failed handleInvoicePaymentFailed Occurs whenever an invoice attempts to be paid, and the payment fails. This can occur either due to a declined payment, or because the customer has no active card. A particular case of note is that if a customer with no active card reaches the end of its free trial, an invoice.payment_failed notification will occur.
invoiceitem.created handleInvoiceitemCreated Occurs whenever an invoice item is created.
invoiceitem.updated handleInvoiceitemUpdated Occurs whenever an invoice item is updated.
invoiceitem.deleted handleInvoiceitemDeleted Occurs whenever an invoice item is deleted.
plan.created handlePlanCreated Occurs whenever a plan is created.
plan.updated handlePlanUpdated Occurs whenever a plan is updated.
plan.deleted handlePlanDeleted Occurs whenever a plan is deleted.
coupon.created handleCouponCreated Occurs whenever a coupon is created.
coupon.deleted handleCouponDeleted Occurs whenever a coupon is deleted.
transfer.created handleTransferCreated Occurs whenever a new transfer is created.
transfer.updated handleTransferUpdated Occurs whenever the description or metadata of a transfer is updated.
transfer.paid handleTransferPaid Occurs whenever a sent transfer is expected to be available in the destination bank account. If the transfer failed, a transfer.failed webhook will additionally be sent at a later time.
transfer.failed handleTransferFailed Occurs whenever Stripe attempts to send a transfer and that transfer fails.

You wont find fancy lifestyle graphics and marketing bravado here. Just cold... hard... code...

Code Well, Rock On!
Processing Payment...