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

Laravel Cashier

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

  1. 1. Введение
  2. 2. Настройка
    1. 2.1. Stripe
    2. 2.2. Braintree
    3. 2.3. Настройка валюты
  3. 3. Подписки
    1. 3.1. Создание подписок
    2. 3.2. Проверка статуса подписки
    3. 3.3. Смена тарифа
    4. 3.4. Количество подписки
    5. 3.5. Налог на подписку
    6. 3.6. Отмена подписки
    7. 3.7. Возобновление подписки
    8. 3.8. Изменение банковской карты
  4. 4. Пробные подписки
    1. 4.1. С запросом банковской карты
    2. 4.2. Без запроса банковской карты
  5. 5. Обработка веб-хуков Stripe
    1. 5.1. Определение обработчиков веб-хук событий
    2. 5.2. Неудавшиеся подписки
  6. 6. Обработка веб-хуков Braintree
    1. 6.1. Определение обработчиков веб-хук событий
    2. 6.2. Неудавшиеся подписки
  7. 7. Одиночные платежи
    1. 7.1. Простой платёж
    2. 7.2. Платёж со счётом
    3. 7.3. Без предоплаты
  8. 8. Счета
    1. 8.1. Создание PDF-файлов счетов
Этот перевод актуален для англоязычной документации на (ветка 5.3) , (ветка 5.2) , (ветка 5.1) и (ветка 5.0). Опечатка? Выдели и нажми Ctrl+Enter.

Введение

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

Если вы обрабатываете только разовые платежи и не предлагаете людям подписки, вам не стоит использовать Cashier. Используйте SDK Stripe и Braintree напрямую.

Настройка

Stripe

Composer

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

  • "laravel/cashier": "~7.0"
+ 5.2 5.1 5.0

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

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

  • "laravel/cashier": "~6.0" — для Laravel 5.2
  • "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 в вашем файле настроек config/app.

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

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

+ 5.3 5.2

добавлено в 5.3 () 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.

Модель Billable

+ 5.3 5.2

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

Далее добавьте типаж Billable в определение вашей модели. Этот типаж предоставляет различные методы для выполнения основных задач по оплате, таких как создание подписок, применение купонов, обновление информации о банковской карте:

PHP
use Laravel\Cashier\Billable;

class 
User extends Authenticatable
{
  use 
Billable;
}

Ключи API

Наконец, надо настроить ключ Stripe в файле настроек services.php. Получить свои ключи Stripe API можно в панели управления Stripe:

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.3 5.2

добавлено в 5.3 () 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": "~2.0"

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

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

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

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

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

Перед использованием 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

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

PHP
use Laravel\Cashier\Billable;

class 
User extends Authenticatable
{
  use 
Billable;
}

Ключи API

Далее надо настроить следующие параметры в файле настроек 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(config('services.braintree.environment'));
\
Braintree_Configuration::merchantId(config('services.braintree.merchant_id'));
\
Braintree_Configuration::publicKey(config('services.braintree.public_key'));
\
Braintree_Configuration::privateKey(config('services.braintree.private_key'));

Для версии 5.2:

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.3

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

Настройка валюты

Стандартная валюта Cashier — доллар США (USD). Вы можете изменить валюту, вызвав метод PHPCashier::useCurrency() из метода PHPboot() одного из ваших сервис-провайдеров. Метод PHPuseCurrency() принимает два строковых параметра: валюту и символ валюты:

PHP
use Laravel\Cashier\Cashier;

Cashier::useCurrency('eur''€');

Подписки

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

+ 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.3 5.2

добавлено в 5.3 () 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.3 5.2

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

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

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

$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.3 5.2

добавлено в 5.3 () 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.3 5.2

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

Чтобы указать процент налога, который пользователь платит за подписку, реализуйте метод 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;
}

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

Метод PHPtaxPercentage() применяется только к оплате подписок. Если вы используете Cashier для разовых платежей, то в таких случаях вам надо указывать размер налога вручную.

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

+ 5.3 5.2

добавлено в 5.3 () 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.3

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

Для немедленной отмены подписки вызовите метод PHPcancelNow() на подписке пользователя:

PHP
$user->subscription('main')->cancelNow();
+ 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.3 5.2

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

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

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

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

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

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

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

+ 5.3

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

Изменение банковской карты

Метод PHPupdateCard() служит для изменения информации о банковской карте клиента. Этот метод принимает Stripe-токен и назначает новую банковскую карту в качестве источника оплаты по умолчанию:

PHP
$user->updateCard($creditCardToken);
+ 5.3 5.2

добавлено в 5.3 () 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),
]);

Не забудьте добавить преобразователь дат для trial_ends_at в определении вашей модели.

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

Stripe и Braintree могут уведомлять ваше приложение о различных событиях через веб-хуки. Для обработки веб-хуков Stripe определите маршрут для контроллера веб-хуков Cashier. Этот контроллер будет обрабатывать все входящие веб-хук запросы и отправлять их в нужный метод контроллера:

+ 5.3 5.2

добавлено в 5.3 () 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');

После регистрации маршрута не забудьте настроить URL веб-хука в панели настроек Stripe.

По умолчанию этот контроллер будет автоматически обрабатывать отмену подписок, для которых произошло слишком много неудачных попыток оплаты (это число задаётся в настройках Stripe); но вскоре мы рассмотрим, что можно наследовать этот контроллер для обработки любых необходимых веб-хук событий.

Веб-хуки и CSRF-защита

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

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

Определение обработчиков веб-хук событий

Cashier автоматически обрабатывает отмену подписки при неудачной оплате, но если у вас есть дополнительные 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 CashierController;
//для версии 5.1 и ранее:
//use Laravel\Cashier\WebhookController as CashierController;

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

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

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

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

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

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

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

Stripe и Braintree могут уведомлять ваше приложение о различных событиях через веб-хуки. Для обработки веб-хуков Stripe определите маршрут для контроллера веб-хуков Cashier. Этот контроллер будет обрабатывать все входящие веб-хук запросы и отправлять их в нужный метод контроллера:

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

По умолчанию этот контроллер будет автоматически обрабатывать отмену подписок, для которых произошло слишком много неудачных попыток оплаты (это число задаётся в настройках Braintree); но вскоре мы рассмотрим, что можно наследовать этот контроллер для обработки любых необходимых веб-хук событий.

Веб-хуки и CSRF-защита

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

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

После регистрации маршрута не забудьте настроить URI веб-хука в панели настроек Braintree.

Определение обработчиков веб-хук событий

Cashier автоматически обрабатывает отмену подписки при неудачной оплате, но если у вас есть дополнительные 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 CashierController;

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

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

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

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

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

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

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

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

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

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

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

Метод PHPcharge() принимает вторым аргументом массив, позволяя вам передавать любые необходимые параметры для создания основного Stripe/Braintree-платежа. О доступных при создании платежей опциях читайте в документации 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();

// Включить отложенные счета в результаты...
$invoices $user->invoicesIncludingPending();

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

+ 5.3 5.2

добавлено в 5.3 () 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
use Illuminate\Http\Request;

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

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

Разметка: ? ?

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