Может войдёшь?
Черновики Написать статью Профиль

Laravel Cashier

перевод документация 5.х

  1. 1. Введение
  2. 2. Настройка Stripe
  3. 3. Настройка Braintree
  4. 4. Подписки
    1. 4.1. Создание подписок
    2. 4.2. Проверка статуса подписки
    3. 4.3. Смена тарифа
    4. 4.4. Количество подписки
    5. 4.5. Налог на подписку
    6. 4.6. Отмена подписки
    7. 4.7. Возобновление подписки
  5. 5. Пробные подписки
    1. 5.1. С запросом банковской карты
    2. 5.2. Без запроса банковской карты
  6. 6. Обработка веб-хуков Stripe
    1. 6.1. Неудавшиеся подписки
    2. 6.2. Другие веб-хуки
  7. 7. Обработка веб-хуков Braintree
    1. 7.1. Неудавшиеся подписки
    2. 7.2. Другие веб-хуки
  8. 8. Одиночные платежи
    1. 8.1. Простой платёж
    2. 8.2. Платёж со счётом
    3. 8.3. Без предоплаты
  9. 9. Счета
Этот перевод актуален для англоязычной документации на (ветка 5.2) , (ветка 5.1) и (ветка 5.0). Опечатка? Выдели и нажми Ctrl+Enter.

Введение

Laravel Cashier (кассир — прим. пер.) обеспечивает выразительный и гибкий интерфейс для сервисов биллинговых подписок Stripe и Braintree. Он сам создаст практически весь шаблонный код биллинговых подписок, который вы боитесь писать. В дополнение к основному управлению подписками Cashier может работать с купонами, заменой подписок, «величинами» подписок, отменой льготного периода, и даже генерировать PDF-файлы счетов.

Настройка Stripe

Composer

Сначала добавьте пакет Cashier для Stripe в свой файл composer.json и выполните команду shcomposer update:

  • "laravel/cashier": "~6.0"
+ 5.1 5.0

добавлено в 5.1 () 5.0 ()

Для ранних версий:

  • "laravel/cashier": "~5.0" — для Stripe SDK ≈2.0 и версии Stripe APIs от 2015-02-18 и выше
  • "laravel/cashier": "~4.0" — для версии Stripe APIs от 2015-02-18 и выше
  • "laravel/cashier": "~3.0" — для версии Stripe APIs от 2015-02-16 включительно и выше

Поставщик услуг

Затем зарегистрируйте сервис-провайдер Laravel\Cashier\CashierServiceProvider в вашем файле настроек app.

Миграции базы данных

Перед тем, как начать использовать Cashier, надо подготовить нашу БД.

+ 5.2

добавлено в 5.2 ()

Надо добавить несколько столбцов в таблицу users и создать новую таблицу subscriptions для хранения всех подписок пользователей:

PHP
Schema::table('users', function ($table) {
  
$table->string('stripe_id')->nullable();
  
$table->string('card_brand')->nullable();
  
$table->string('card_last_four')->nullable();
  
$table->timestamp('trial_ends_at')->nullable();
});

Schema::create('subscriptions', function ($table) {
  
$table->increments('id');
  
$table->integer('user_id');
  
$table->string('name');
  
$table->string('stripe_id');
  
$table->string('stripe_plan');
  
$table->integer('quantity');
  
$table->timestamp('trial_ends_at')->nullable();
  
$table->timestamp('ends_at')->nullable();
  
$table->timestamps();
});
+ 5.1 5.0

добавлено в 5.1 () 5.0 ()

Не волнуйтесь, вы можете использовать Artisan-команду shcashier:table для создания миграции, которая добавит необходимые столбцы. Например, чтобы добавить столбец в таблицу пользователей, используйте shphp artisan cashier:table users.

После создания миграции просто выполните команду shmigrate.

Установка модели

+ 5.2

добавлено в 5.2 ()

Далее добавьте типаж Billable в определение вашей модели:

PHP
use Laravel\Cashier\Billable;

class 
User extends Authenticatable
{
  use 
Billable;
}

Ключи провайдера

Далее надо настроить ключ Stripe в файле настроек services.php:

PHP
'stripe' => [
  
'model'  => App\User::class,
  
'secret' => env('STRIPE_SECRET'),
],
+ 5.1 5.0

добавлено в 5.1 () 5.0 ()

Далее добавьте типаж Billable и соответствующие преобразователи даты в определение вашей модели:

PHP
use Laravel\Cashier\Billable;
use 
Laravel\Cashier\Contracts\Billable as BillableContract;

class 
User extends Model implements BillableContract
{
  use 
Billable;

  protected 
$dates = ['trial_ends_at''subscription_ends_at'];
}

Добавление столбцов в свойство модели PHP$dates даёт Eloquent команду вернуть столбцы в виде экземпляров Carbon/DateTime вместо «сырых» строк.

Stripe-ключ

Наконец, внесите ваш Stripe-ключ в конфигурационный файл services.php:

PHP
'stripe' => [
  
'model'  => 'User',
  
'secret' => env('STRIPE_API_SECRET'),
],
+ 5.2

добавлено в 5.2 ()

Настройка Braintree

Преимущества и недостатки Braintree

Для многих операций реализация функций Cashier в Stripe и Braintree одинакова. Оба сервиса предоставляют возможность оплаты подписок банковскими картами, но Braintree также поддерживает оплату через PayPal. Однако, в Braintree нет некоторых возможностей, имеющихся в Stripe. При выборе между ними учитывайте следующее:

  • Braintree поддерживает PayPal, а Stripe нет.
  • Braintree не поддерживает методы PHPincrement и PHPdecrement для подписок. Это ограничение Braintree, а не Cashier.
  • Braintree не поддерживает скидки в процентах. Это ограничение Braintree, а не Cashier.

Composer

Сначала добавьте пакет Cashier для Braintree в ваш файл composer.json и выполните команду shcomposer update:

sh"laravel/cashier-braintree": "~1.0"

Сервис-провайдер

Далее зарегистрируйте сервис-провайдер Laravel\Cashier\CashierServiceProvider в файле настроек app.

Купон на скидку

Перед использованием Cashier с Braintree вам надо определить скидку для плана оплаты в панели настроек Braintree. Эта скидка будет использоваться для пропорционального пересчёта подписок, которые переходят с годовой на ежемесячную оплату, или наоборот с ежемесячной на годовую. Настраиваемый в панели настроек Braintree размер скидки может быть любым, на ваше усмотрение, а Cashier будет просто изменять размер по умолчанию на заданный при каждом применении купона.

Миграции базы данных

Перед использованием Cashier нам также надо подготовить базу данных. Надо добавить несколько столбцов в таблицу users и создать новую таблицу subscriptions для хранения всех подписок пользователей:

PHP
Schema::table('users', function ($table) {
  
$table->string('braintree_id')->nullable();
  
$table->string('paypal_email')->nullable();
  
$table->string('card_brand')->nullable();
  
$table->string('card_last_four')->nullable();
  
$table->timestamp('trial_ends_at')->nullable();
});

Schema::create('subscriptions', function ($table) {
  
$table->increments('id');
  
$table->integer('user_id');
  
$table->string('name');
  
$table->string('braintree_id');
  
$table->string('braintree_plan');
  
$table->integer('quantity');
  
$table->timestamp('trial_ends_at')->nullable();
  
$table->timestamp('ends_at')->nullable();
  
$table->timestamps();
});

После создания миграций просто выполните Artisan-команду shmigrate.

Настройка модели

Далее добавьте типаж Billable в определение вашей модели:

PHP
use Laravel\Cashier\Billable;

class 
User extends Authenticatable
{
  use 
Billable;
}

Ключи провайдера

Далее надо настроить следующие параметры в файле настроек services.php:

PHP
'braintree' => [
  
'model'  => App\User::class,
  
'environment' => env('BRAINTREE_ENV'),
  
'merchant_id' => env('BRAINTREE_MERCHANT_ID'),
  
'public_key' => env('BRAINTREE_PUBLIC_KEY'),
  
'private_key' => env('BRAINTREE_PRIVATE_KEY'),
],

Затем надо добавить следующие вызовы Braintree SDK в метод PHPboot() вашего сервис провайдера AppServiceProvider:

PHP
\Braintree_Configuration::environment(env('BRAINTREE_ENV'));
\
Braintree_Configuration::merchantId(env('BRAINTREE_MERCHANT_ID'));
\
Braintree_Configuration::publicKey(env('BRAINTREE_PUBLIC_KEY'));
\
Braintree_Configuration::privateKey(env('BRAINTREE_PRIVATE_KEY'));

Подписки

Создание подписок

+ 5.2

добавлено в 5.2 ()

Для создания подписки сначала получите экземпляр оплачиваемой модели, который обычно является экземпляром App\User. Когда вы получили модель, вы можете использовать метод PHPnewSubscription() для управления подписками модели:

PHP
$user User::find(1);

$user->newSubscription('main''monthly')->create($creditCardToken);

Первый аргумент метода PHPnewSubscription() — название подписки. Если в вашем приложении используется только одна подписка, то вы можете назвать её main или primary. Второй аргумент — конкретный план Stripe/Braintree, на который подписывается пользователь. Это значение должно соответствовать идентификатору плана в Stripe или Braintree.

Метод PHPcreate() автоматически создаст подписку, а также внесёт в вашу базу данных ID заказчика и другую связанную информацию по оплате.

Дополнительная информация о пользователе

Если вы хотите указать дополнительную информацию о пользователе, передайте её вторым аргументом методу PHPcreate():

PHP
$user->newSubscription('main''monthly')->create($creditCardToken, [
  
'email' => $email,
]);

Подробнее о дополнительных полях, поддерживаемых Stripe и Braintree, читайте в документации по созданию заказчика Stripe и в документации Braintree.

Купоны

Если надо применить купон при создании подписки, используйте метод PHPwithCoupon():

PHP
$user->newSubscription('main''monthly')
     ->
withCoupon('code')
     ->
create($creditCardToken);
+ 5.1 5.0

добавлено в 5.1 () 5.0 ()

Для создания подписки сначала получите экземпляр оплачиваемой модели, который обычно является экземпляром App\User. Когда вы получили модель, вы можете использовать метод PHPsubscription() для управления подписками модели:

PHP
$user User::find(1);

$user->subscription('monthly')->create($creditCardToken);

Метод PHPcreate() автоматически создаст подписку Stripe, а также внесёт в вашу базу данных ID заказчика Stripe и другую связанную информацию по оплате. Если для вашего тарифа настроен пробный период в Stripe, то для записи пользователя автоматически будет задана дата окончания периода.

Если вы хотите использовать пробные периоды, но при этом управлять ими полностью из своего приложения, а не определять их в Stripe, то вам надо задать дату окончания периода вручную:

PHP
$user->trial_ends_at Carbon::now()->addDays(14);

$user->save();

Дополнительная информация о пользователе

Если вы хотите указать дополнительную информацию о пользователе, передайте её вторым аргументом методу PHPcreate():

PHP
$user->subscription('monthly')->create($creditCardToken, [
    
'email' => $email'description' => 'Our First Customer'
]);

Подробнее о дополнительных полях, поддерживаемых Stripe, читайте в документации по созданию заказчика Stripe.

Купоны

Если надо применить купон при создании подписки, используйте метод PHPwithCoupon():

PHP
$user->subscription('monthly')
     ->
withCoupon('code')
     ->
create($creditCardToken);

Проверка статуса подписки

+ 5.2

добавлено в 5.2 ()

Когда пользователь подписан на ваше приложение, вы можете легко проверить статус его подписки при помощи различных удобных методов. Во-первых, метод PHPsubscribed() возвращает true, если подписка пользователя активна, даже если в данный момент она на пробном периоде:

PHP
if ($user->subscribed('main')) {
  
//
}

Метод PHPsubscribed создаёт отличный вариант для посредника маршрута, позволяя вам фильтровать доступ к маршрутам и контроллерам на основе статусов подписок:

PHP
public function handle($requestClosure $next)
{
  if (
$request->user() && ! $request->user()->subscribed('main')) {
    
// Этот пользователь не оплатил подписку...
    
return redirect('billing');
  }

  return 
$next($request);
}

Вы также можете определить, идёт ли до сих пор пробный период у пользователя, с помощью метода PHPonTrial(). Этот метод полезен для предупреждения пользователя о том, что он на пробном периоде:

PHP
if ($user->subscription('main')->onTrial()) {
  
//
}

Метод PHPsubscribedToPlan() используется для определения, подписан ли пользователь на данный тариф, на основе его Stripe/Braintree ID. В этом примере мы определим, подписана ли подписка main пользователя на план monthly:

PHP
if ($user->subscribedToPlan('monthly''main')) {
  
//
}

Статус отменённой подписки

Чтобы определить, был ли пользователь ранее активным подписчиком, но позже отменил подписку, используйте метод PHPcancelled():

PHP
if ($user->subscription('main')->cancelled()) {
  
//
}

Вы можете также определить, отменил ли пользователь подписку, но находится все ещё на «льготном периоде», пока подписка полностью не истекла. Например, если пользователь отменяет подписку 5 марта, которая по плану закончится 10 марта, пользователь будет на «льготном периоде» до 10 марта. Обратите внимание на то, что метод PHPsubscribed() всё ещё возвращает true в это время.

PHP
if ($user->subscription('main')->onGracePeriod()) {
  
//
}
+ 5.1 5.0

добавлено в 5.1 () 5.0 ()

Когда пользователь подписан на ваше приложение, вы можете легко проверить статус его подписки при помощи различных удобных методов. Во-первых, метод PHPsubscribed() возвращает true, если подписка пользователя активна, даже если в данный момент она на пробном периоде:

PHP
if ($user->subscribed()) {
  
//
}

Метод PHPsubscribed создаёт отличный вариант для посредника маршрута, позволяя вам фильтровать доступ к маршрутам и контроллерам на основе статусов подписок:

PHP
public function handle($requestClosure $next)
{
  if (
$request->user() && ! $request->user()->subscribed()) {
    
// Этот пользователь не оплатил подписку...
    
return redirect('billing');
  }

  return 
$next($request);
}

Вы также можете определить, идёт ли до сих пор пробный период у пользователя, с помощью метода PHPonTrial(). Этот метод полезен для предупреждения пользователя о том, что он на пробном периоде:

PHP
if ($user->onTrial()) {
  
//
}

Метод PHPonPlan() используется для определения, подписан ли пользователь на данный тариф, на основе его Stripe ID:

PHP
if ($user->onPlan('monthly')) {
  
//
}

Статус отменённой подписки

Чтобы определить, был ли пользователь ранее активным подписчиком, но позже отменил подписку, используйте метод PHPcancelled():

PHP
if ($user->cancelled()) {
  
//
}

Вы можете также определить, отменил ли пользователь подписку, но находится все ещё на «льготном периоде», пока подписка полностью не истекла. Например, если пользователь отменяет подписку 5 марта, которая по плану закончится 10 марта, пользователь будет на «льготном периоде» до 10 марта. Обратите внимание на то, что метод PHPsubscribed() всё ещё возвращает true в это время.

PHP
if ($user->onGracePeriod()) {
  
//
}

Метод PHPeverSubscribed() используется для определения, подписывался ли пользователь когда-либо на ваше приложение:

PHP
if ($user->everSubscribed()) {
  
//
}

Смена тарифа

+ 5.2

добавлено в 5.2 ()

Когда пользователь подписан на ваше приложение, он может захотеть сменить свой тарифный план. Чтобы переключить пользователя на новую подписку, используйте метод PHPswap(). Например, мы легко можем переключить пользователя на подписку premium:

PHP
$user App\User::find(1);

$user->subscription('main')->swap('provider-plan-id');

Если пользователь был на пробном периоде, то пробный период продолжится. Кроме того, если у подписки есть «количество», то оно тоже применится:

PHP
$user->subscription('main')->swap('provider-plan-id');

Если вы хотите сменить план, но пропустить пробный период нового плана, используйте метод PHPskipTrial():

PHP
$user->subscription('main')
            ->
skipTrial()
            ->
swap('provider-plan-id');
+ 5.1 5.0

добавлено в 5.1 () 5.0 ()

Когда пользователь подписан на ваше приложение, он может захотеть сменить свой тарифный план. Чтобы переключить пользователя на новую подписку, используйте метод PHPswap(). Например, мы легко можем переключить пользователя на подписку premium:

PHP
$user App\User::find(1);

$user->subscription('premium')->swap();

Если пользователь был на пробном периоде, то пробный период продолжится. Кроме того, если у подписки есть «количество», то оно тоже применится. При смене тарифа вы можете использовать метод PHPprorate(), чтобы указать, что стоимость должна быть пересчитана пропорционально. Вдобавок, вы можете использовать метод PHPswapAndInvoice() для того, чтобы выставить счёт за смену тарифа немедленно:

PHP
$user->subscription('premium')
            ->
prorate()
            ->
swapAndInvoice();

Количество подписки

+ 5.2

добавлено в 5.2 ()

Количество подписки поддерживается только версией Cashier для Stripe. В Braintree нет эквивалента «количества» Stripe.

Иногда подписки зависят от «количества». Например, ваше приложение стоит $10 в месяц с одного пользователя учётной записи. Чтобы легко увеличить или уменьшить количество вашей подписки, используйте методы PHPincrementQuantity() и PHPdecrementQuantity():

PHP
$user User::find(1);

$user->subscription('main')->incrementQuantity();

// Добавить 5 к текущему количеству подписок...
$user->subscription('main')->incrementQuantity(5);

$user->subscription('main')->decrementQuantity();

// Вычесть 5 от текущего количества подписок...
$user->subscription('main')->decrementQuantity(5);

Или вы можете задать конкретное количество с помощью метода PHPupdateQuantity():

PHP
$user->subscription('main')->updateQuantity(10);
+ 5.1 5.0

добавлено в 5.1 () 5.0 ()

Иногда подписки зависят от «количества». Например, ваше приложение стоит $10 в месяц с одного пользователя учётной записи. Чтобы легко увеличить или уменьшить количество вашей подписки, используйте методы PHPincrement() и PHPdecrement():

PHP
$user User::find(1);

$user->subscription()->increment();

// Добавить 5 к текущему количеству подписок...
$user->subscription()->increment(5);

$user->subscription()->decrement();

// Вычесть 5 от текущего количества подписок...
$user->subscription()->decrement(5);

Или вы можете задать конкретное количество с помощью метода PHPupdateQuantity():

PHP
$user->subscription()->updateQuantity(10);

Более подробная информация о количествах подписок в документации Stripe.

Налог на подписку

+ 5.2

добавлено в 5.2 ()

С помощью Cashier можно легко изменить значение tax_percent, посылаемое в Stripe/Braintree. Чтобы указать процент налога, который пользователь платит за подписку, реализуйте метод PHPtaxPercentage() в своей модели, и верните числовое значение от 0 до 100 с не более, чем двумя знаками после запятой.

PHP
public function taxPercentage() {
  return 
20;
}
+ 5.1 5.0

добавлено в 5.1 () 5.0 ()

С помощью Cashier можно легко изменить значение tax_percent, посылаемое в Stripe. Чтобы указать процент налога, который пользователь платит за подписку, реализуйте метод PHPgetTaxPercent() в своей модели, и верните числовое значение от 0 до 100 с не более, чем двумя знаками после запятой.

PHP
public function getTaxPercent() {
  return 
20;
}

Это позволяет вам использовать разные налоговые ставки по-модельно, что будет полезно при наличии пользователей из разных стран.

Отмена подписки

+ 5.2

добавлено в 5.2 ()

Отменить подписку можно методом PHPcancel():

PHP
$user->subscription('main')->cancel();

При отмене подписки Cashier автоматически задаст столбец ends_at в вашей базе данных. Этот столбец используется, чтобы знать, когда метод PHPsubscribed() должен начать возвращать false. Например, если клиент отменит подписку 1 марта, но срок подписки по плану до 5 марта, то метод PHPsubscribed() будет продолжать возвращать true до 5 марта.

Вы можете определить то, что пользователь отменил подписку, но находится на «льготном периоде», при помощи метода PHPonGracePeriod ():

PHP
if ($user->subscription('main')->onGracePeriod()) {
  
//
}
+ 5.1 5.0

добавлено в 5.1 () 5.0 ()

Отменить подписку можно методом PHPcancel():

PHP
$user->subscription()->cancel();

При отмене подписки Cashier автоматически задаст столбец subscription_ends_at в вашей базе данных. Этот столбец используется, чтобы знать, когда метод PHPsubscribed() должен начать возвращать false. Например, если клиент отменит подписку 1 марта, но срок подписки по плану до 5 марта, то метод PHPsubscribed() будет продолжать возвращать true до 5 марта.

Вы можете определить то, что пользователь отменил подписку, но находится на «льготном периоде», при помощи метода PHPonGracePeriod ():

PHP
if ($user->onGracePeriod()) {
  
//
}

Возобновление подписки

+ 5.2

добавлено в 5.2 ()

Если подписка была отменена пользователем, и вам надо её возобновить, используйте метод PHPresume(). Пользователь должен быть по-прежнему на льготном периоде, чтобы возобновить подписку:

PHP
$user->subscription('main')->resume();
+ 5.1 5.0

добавлено в 5.1 () 5.0 ()

Если подписка была отменена пользователем, и вам надо её возобновить, используйте метод PHPresume():

PHP
$user->subscription('monthly')->resume($creditCardToken);

Если пользователь отменит подписку и затем возобновит её до того, как она полностью истекла, тогда не произойдет моментального расчёта оплаты. Его подписка будет просто повторно активирована, и расчёт оплаты будет происходить по изначальному циклу.

+ 5.2

добавлено в 5.2 ()

Пробные подписки

С запросом банковской карты

Если вы хотите предлагать клиентам пробные периоды, но при этом сразу собирать данные о способе оплаты, используйте метод PHPtrialDays() при создании подписок:

PHP
$user User::find(1);

$user->newSubscription('main''monthly')
            ->
trialDays(10)
            ->
create($creditCardToken);

Этот метод задаст дату окончания пробного периода в записи БД о подписке, а также проинструктирует Stripe/Braintree о том, что не нужно начинать считать оплату для клиента до окончания этого периода.

Если подписка клиента не будет отменена до окончания пробного периода, ему будет выставлен счёт, как только истечёт этот период, поэтому вы должны уведомлять своих пользователей о дате окончания их пробного периода.

Вы можете определить,
Вы можете определить, идёт ли до сих пор пробный период у пользователя, с помощью метода PHPonTrial() экземпляра пользователя или с помощью метода PHPonTrial() экземпляра подписки. Эти два примера выполняют одинаковую задачу:

PHP
if ($user->onTrial('main')) {
  
//
}

if (
$user->subscription('main')->onTrial()) {
  
//
}

Без запроса банковской карты

Если вы хотите предлагать клиентам пробные периоды, не собирая данные о способе оплаты, вы можете просто задать значение столбца trial_ends_at в записи пользователя равное дате окончания пробного периода. Например, это обычно делается во время регистрации пользователя:

PHP
$user User::create([
  
// Заполнение других свойств пользователя...
  
'trial_ends_at' => Carbon::now()->addDays(10),
]);

Cashier относится к пробным периодам такого типа, как к «общим пробным периодам», поскольку они не прикреплены к какой-либо из существующих подписок. Метод PHPonTrial() на экземпляре User вернёт PHPtrue, если текущая дата не превышает значение trial_ends_at:

PHP
if ($user->onTrial()) {
  
// Пользователь на пробном периоде...
}

Если вы хотите узнать, что пользователь именно на «общем» пробном периоде и ещё не создал настоящую подписку, используйте метод PHPonGenericTrial():

PHP
if ($user->onGenericTrial()) {
  
// Пользователь на "общем" пробном периоде...
}

Когда вы готовы создать для пользователя настоящую подписку, используйте метод PHPnewSubscription() как обычно:

PHP
$user User::find(1);

$user->newSubscription('main''monthly')->create($creditCardToken);

Обработка веб-хуков Stripe

Неудавшиеся подписки

Что если срок действия банковской карты клиента истёк? Никаких проблем — Cashier включает в себя контроллер PHPWebhook, который может легко отменить подписку клиента. Просто укажите путь к контроллеру:

+ 5.2

добавлено в 5.2 ()

PHP
Route::post(
  
'stripe/webhook',
  
'\Laravel\Cashier\Http\Controllers\WebhookController@handleWebhook'
);
+ 5.1 5.0

добавлено в 5.1 () 5.0 ()

PHP
Route::post('stripe/webhook''\Laravel\Cashier\WebhookController@handleWebhook');

Вот и всё! Неудавшиеся платежи будут перехвачены и обработаны контроллером. Контроллер отменит подписку клиента, если Stripe определит, что подписка не удалась (обычно после трёх неудавшихся платежей). URI Stripe/webhook в этом примере взят просто для примера. Вам надо настроить URI в параметрах вашего Stripe.

Поскольку веб-хуки Stripe должны идти в обход CSRF проверок Laravel, не забудьте включить URI в список исключений вашего посредника VerifyCsrfToken или разместить маршрут вне группы посредников web (для версии 5.2 и выше):

PHP
protected $except = [
    
'stripe/*',
];

Другие веб-хуки

Если у вас есть дополнительные webhook-события для Stripe, которые вы хотели бы обработать, просто наследуйте контроллер PHPWebhook. Ваши имена методов должны соответствовать принятому в Cashier соглашению, в частности, методы должны быть снабжены префиксом handle и именем того webhook-события Stripe, которое вы хотите обработать, в стиле «CamelCase». Например, если вы хотите обработать webhook PHPinvoice.payment_succeeded, вы должны добавить метод PHPhandleInvoicePaymentSucceeded() в контроллер.

PHP
<?php

namespace App\Http\Controllers;

use 
Laravel\Cashier\Http\Controllers\WebhookController as BaseController;
//для версии 5.1 и ранее:
//use Laravel\Cashier\WebhookController as BaseController;

class WebhookController extends BaseController
{
  
/**
   * Обработка веб-хука Stripe.
   *
   * @param  array  $payload
   * @return Response
   */
  
public function handleInvoicePaymentSucceeded($payload)
  {
    
// Обработка события
  
}
}
+ 5.2

добавлено в 5.2 ()

Обработка веб-хуков Braintree

Неудавшиеся подписки

Что если срок действия банковской карты клиента истёк? Никаких проблем — Cashier включает в себя контроллер PHPWebhook, который может легко отменить подписку клиента. Просто укажите путь к контроллеру:

PHP
Route::post(
  
'braintree/webhook',
  
'\Laravel\Cashier\Http\Controllers\WebhookController@handleWebhook'
);

Вот и всё! Неудавшиеся платежи будут перехвачены и обработаны контроллером. Контроллер отменит подписку клиента, если Braintree определит, что подписка не удалась (обычно после трёх неудавшихся платежей). Не забудьте: вам надо настроить URI веб-хука на панели настроек вашего Braintree.

Поскольку веб-хуки Braintree должны идти в обход CSRF проверок Laravel, не забудьте включить URI в список исключений вашего посредника VerifyCsrfToken или разместить маршрут вне группы посредников web:

PHP
protected $except = [
  
'braintree/*',
];

Другие веб-хуки

Если у вас есть дополнительные webhook-события для Braintree, которые вы хотели бы обработать, просто наследуйте контроллер PHPWebhook. Ваши имена методов должны соответствовать принятому в Braintree соглашению, в частности, методы должны быть снабжены префиксом handle и именем того webhook-события Braintree, которое вы хотите обработать, в стиле «CamelCase». Например, если вы хотите обработать веб-хук PHPdispute_opened, вы должны добавить метод PHPhandleDisputeOpened() в контроллер.

PHP
<?php

namespace App\Http\Controllers;

use 
Braintree\WebhookNotification;
use 
Laravel\Cashier\Http\Controllers\WebhookController as BaseController;

class 
WebhookController extends BaseController
{
  
/**
   * Обработка веб-хука Braintree.
   *
   * @param  WebhookNotification  $webhook
   * @return Response
   */
  
public function handleDisputeOpened(WebhookNotification $notification)
  {
    
// Обработка события
  
}
}

Одиночные платежи

+ 5.2

добавлено в 5.2 ()

Простой платёж

При использовании Stripe метод PHPcharge() принимает сумму, которую необходимо оплатить, с наименьшим знаменателем используемой в вашем приложении валюты. А при использовании Braintree вы должны передавать в метод PHPcharge() полную сумму в долларах.

Если вы хотите сделать «одноразовый» платёж вместо использования банковской карты подписанного пользователя, используйте метод PHPcharge() для экземпляра оплачиваемой модели.

PHP
// Stripe принимает сумму в центах...
$user->charge(100);

// Braintree принимает сумму в долларах...
$user->charge(1);

Метод PHPcharge() принимает вторым аргументом массив, позволяя вам передавать любые необходимые параметры для создания основного Stripe/Braintree-платежа:

PHP
$user->charge(100, [
  
'custom_option' => $value,
]);

Метод PHPcharge() выбросит исключение при ошибке платёжа. Если платёж пройдёт успешно, метод вернёт полный ответ Stripe/Braintree:

PHP
try {
  
$response $user->charge(100);
} catch (
Exception $e) {
  
//
}

Платёж со счётом

Иногда бывает необходимо сделать одноразовый платёж и сгенерировать счёт-фактуру для него, чтобы вы могли предоставить клиенту PDF-квитанцию. Именно для этого служит метод PHPinvoiceFor(). Например, давайте выставим клиенту счёт $5.00 «разовой оплаты» («One Time Fee»):

PHP
// Stripe принимает сумму в центах...
$user->invoiceFor('One Time Fee'500);

// Braintree принимает сумму в долларах...
$user->invoiceFor('One Time Fee'5);

Счёт будет немедленно оплачен банковской картой пользователя. Метод PHPinvoiceFor() также принимает третьим аргументом массив, позволяя вам передавать любые параметры для создания платежа Stripe/Braintree:

PHP
$user->invoiceFor('One Time Fee'500, [
  
'custom-option' => $value,
]);

Метод PHPinvoiceFor() создаст счёт Stripe, который будет повторять проваленные попытки оплаты. Если вы не хотите повторять проваленные платежи, вам необходимо закрывать их с помощью Stripe API после первого неудачного платежа.

+ 5.1 5.0

добавлено в 5.1 () 5.0 ()

Если вы хотите сделать «одноразовый» платёж вместо использования банковской карты подписанного пользователя, используйте метод PHPcharge() для экземпляра модели. Метод PHPcharge() принимает сумму, которую необходимо оплатить, с наименьшим знаменателем используемой в вашем приложении валюты. Например, в этом примере будет списано 100 центов, или $1, с банковской карты пользователя:

PHP
$user->charge(100);

Метод PHPcharge() принимает в качестве второго аргумента массив, позволяя вам передавать любые необходимые параметры для создания основного Stripe-платежа:

PHP
$user->charge(100, [
  
'source' => $token,
  
'receipt_email' => $user->email,
]);

Метод PHPcharge() вернёт false, если платёж не пройдёт. Обычно это значит, что платёж был отклонён:

PHP
if ( ! $user->charge(100)) {
  
// Платёж был отклонён...
}

Если платёж прошёл успешно, метод возвратит полный Stripe-ответ.

+ 5.0

добавлено в 5.0 ()

Без предоплаты

Если в вашем приложении будет бесплатный пробный период, не требующий предварительного предъявления банковской карты, установите свойство cardUpFront вашей модели в false:

PHP
protected $cardUpFront false;

При создании аккаунта не забудьте установить дату окончания пробного периода в модели:

PHP
$user->trial_ends_at Carbon::now()->addDays(14);

$user->save();

Счета

Вы можете легко получить массив счетов пользователя, используя метод PHPinvoices():

PHP
$invoices $user->invoices();

При просмотре счетов клиента вы можете использовать эти вспомогательные методы, чтобы вывести на экран соответствующую информацию о счёте. Например, вам может понадобиться просмотреть каждый счёт в таблице, позволив пользователю легко скачать любой из них:

+ 5.2

добавлено в 5.2 ()

PHP
<table>
  @foreach (
$invoices as $invoice)
    <
tr>
      <
td>{{ $invoice->date()->toFormattedDateString() }}</td>
      <
td>{{ $invoice->total() }}</td>
      <
td><a href="/user/invoice/{{ $invoice->id }}">Download</a></td>
    </
tr>
  @endforeach
</
table>
+ 5.1 5.0

добавлено в 5.1 () 5.0 ()

PHP
<table>
  @foreach (
$invoices as $invoice)
    <
tr>
      <
td>{{ $invoice->dateString() }}</td>
      <
td>{{ $invoice->dollars() }}</td>
      <
td><a href="/user/invoice/{{ $invoice->id }}">Download</a></td>
    </
tr>
  @endforeach
</
table>

Создание PDF-файлов счетов

Перед созданием PDF-файлов счетов вам необходимо установить PHP-библиотеку dompdf:

shcomposer require dompdf/dompdf

Используйте метод PHPdownloadInvoice() в маршруте или контроллере, чтобы cгенерировать PDF-файл счёта. Этот метод автоматически сгенерирует нужный HTTP-отклик чтобы отправить загрузку в браузер:

PHP
Route::get('user/invoice/{invoice}', function ($invoiceId) {
  return 
Auth::user()->downloadInvoice($invoiceId, [
    
'vendor'  => 'Your Company',
    
'product' => 'Your Product',
  ]);
});

Написать комментарий

Разметка: ? ?

Авторизуйся, чтобы прокомментировать.