Laravel Cashier (Stripe)
Introduction
Laravel Cashier Stripe provides an expressive, fluent interface to Stripe's subscription billing services. It handles almost all of the boilerplate subscription billing code you are dreading writing. In addition to basic subscription management, Cashier can handle coupons, swapping subscription, subscription "quantities", cancellation grace periods, and even generate invoice PDFs.
Upgrading Cashier
When upgrading to a new version of Cashier, it's important that you carefully review the upgrade guide.
To prevent breaking changes, Cashier uses a fixed Stripe API version. Cashier 13 utilizes Stripe API version 2020-08-27
. The Stripe API version will be updated on minor releases in order to make use of new Stripe features and improvements.
Installation
First, install the Cashier package for Stripe using the Composer package manager:
composer require laravel/cashier
To ensure Cashier properly handles all Stripe events, remember to set up Cashier's webhook handling.
Database Migrations
Cashier's service provider registers its own database migration directory, so remember to migrate your database after installing the package. The Cashier 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:
php artisan migrate
If you need to overwrite the migrations that ship with Cashier, you can publish them using the vendor:publish
Artisan command:
php artisan vendor:publish --tag="cashier-migrations"
If you would like to prevent Cashier's migrations from running entirely, you may use the ignoreMigrations
method provided by Cashier. Typically, this method should be called in the register
method of your AppServiceProvider
:
use Laravel\Cashier\Cashier;
/**
* Register any application services.
*
* @return void
*/
public function register()
{
Cashier::ignoreMigrations();
}
Stripe recommends that any column used for storing Stripe identifiers should be case-sensitive. Therefore, you should ensure the column collation for the stripe_id
column is set to utf8_bin
when using MySQL. More information regarding this can be found in the Stripe documentation.
Configuration
Billable Model
Before using Cashier, add the Billable
trait to your billable model definition. Typically, this will be the App\Models\User
model. This trait provides various methods to allow you to perform common billing tasks, such as creating subscriptions, applying coupons, and updating payment method information:
use Laravel\Cashier\Billable;
class User extends Authenticatable
{
use Billable;
}
Cashier assumes your billable model will be the App\Models\User
class that ships with Laravel. If you wish to change this you may specify a different model via the useCustomerModel
method. This method should typically be called in the boot
method of your AppServiceProvider
class:
use App\Models\Cashier\User;
use Laravel\Cashier\Cashier;
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Cashier::useCustomerModel(User::class);
}
If you're using a model other than Laravel's supplied App\Models\User
model, you'll need to publish and alter the Cashier migrations provided to match your alternative model's table name.
API Keys
Next, you should configure your Stripe API keys in your application's .env
file. You can retrieve your Stripe API keys from the Stripe control panel:
STRIPE_KEY=your-stripe-key
STRIPE_SECRET=your-stripe-secret
Currency Configuration
The default Cashier currency is United States Dollars (USD). You can change the default currency by setting the CASHIER_CURRENCY
environment variable within your application's .env
file:
CASHIER_CURRENCY=eur
In addition to configuring Cashier's currency, you may also specify a locale to be used when formatting money values for display on invoices. Internally, Cashier utilizes PHP's NumberFormatter
class to set the currency locale:
CASHIER_CURRENCY_LOCALE=nl_BE
In order to use locales other than en
, ensure the ext-intl
PHP extension is installed and configured on your server.
Tax Configuration
Thanks to Stripe Tax, it's possible to automatically calculate taxes for all invoices generated by Stripe. You can enable automatic tax calculation by invoking the calculateTaxes
method in the boot
method of your application's App\Providers\AppServiceProvider
class:
use Laravel\Cashier\Cashier;
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Cashier::calculateTaxes();
}
Once tax calculation has been enabled, any new subscriptions and any one-off invoices that are generated will receive automatic tax calculation.
For this feature to work properly, your customer's billing details, such as the customer's name, address, and tax ID, need to be synced to Stripe. You may use the customer data synchronization and Tax ID methods offered by Cashier to accomplish this.
Unfortunately, for now, no tax is calculated for single charges or single charge checkouts. In addition, Stripe Tax is currently "invite-only" during its beta period. You can request access to Stripe Tax via the Stripe Tax website.
Logging
Cashier allows you to specify the log channel to be used when logging fatal Stripe errors. You may specify the log channel by defining the CASHIER_LOGGER
environment variable within your application's .env
file:
CASHIER_LOGGER=stack
Exceptions that are generated by API calls to Stripe will be logged through your application's default log channel.
Using Custom Models
You are free to extend the models used internally by Cashier by defining your own model and extending the corresponding Cashier model:
use Laravel\Cashier\Subscription as CashierSubscription;
class Subscription extends CashierSubscription
{
// ...
}
After defining your model, you may instruct Cashier to use your custom model via the Laravel\Cashier\Cashier
class. Typically, you should inform Cashier about your custom models in the boot
method of your application's App\Providers\AppServiceProvider
class:
use App\Models\Cashier\Subscription;
use App\Models\Cashier\SubscriptionItem;
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Cashier::useSubscriptionModel(Subscription::class);
Cashier::useSubscriptionItemModel(SubscriptionItem::class);
}
Customers
Retrieving Customers
You can retrieve a customer by their Stripe ID using the Cashier::findBillable
method. This method will return an instance of the billable model:
use Laravel\Cashier\Cashier;
$user = Cashier::findBillable($stripeId);
Creating Customers
Occasionally, you may wish to create a Stripe customer without beginning a subscription. You may accomplish this using the createAsStripeCustomer
method:
$stripeCustomer = $user->createAsStripeCustomer();
Once the customer has been created in Stripe, you may begin a subscription at a later date. You may provide an optional $options
array to pass in any additional customer creation parameters that are supported by the Stripe API:
$stripeCustomer = $user->createAsStripeCustomer($options);
You may use the asStripeCustomer
method if you want to return the Stripe customer object for a billable model:
$stripeCustomer = $user->asStripeCustomer();
The createOrGetStripeCustomer
method may be used if you would like to retrieve the Stripe customer object for a given billable model but are not sure whether the billable model is already a customer within Stripe. This method will create a new customer in Stripe if one does not already exist:
$stripeCustomer = $user->createOrGetStripeCustomer();
Updating Customers
Occasionally, you may wish to update the Stripe customer directly with additional information. You may accomplish this using the updateStripeCustomer
method. This method accepts an array of customer update options supported by the Stripe API:
$stripeCustomer = $user->updateStripeCustomer($options);
Balances
Stripe allows you to credit or debit a customer's "balance". Later, this balance will be credited or debited on new invoices. To check the customer's total balance you may use the balance
method that is available on your billable model. The balance
method will return a formatted string representation of the balance in the customer's currency:
$balance = $user->balance();
To credit a customer's balance, you may provide a negative value to the applyBalance
method. If you wish, you may also provide a description:
$user->applyBalance(-500, 'Premium customer top-up.');
Providing a positive value to the applyBalance
method will debit the customer's balance:
$user->applyBalance(300, 'Bad usage penalty.');