{{TOC}} {{DOCVER 4.2=d7b13440c003218ed79e9d508706eca01990122f 4.12.2014 5:01:15}} == Введение == Laravel Cashier (!!(tl_note) кассир!!) обеспечивает выразительный и гибкий интерфейс для сервисов биллинговых подписок ((https://stripe.com Stripe)). Он сам создаст практически весь шаблонный код биллинговых подписок, который вы боитесь писать. В дополнение к основному управлению подписками Cashier может работать с купонами, заменой подписок, "величинами" подписок, отменой льготного периода, и даже генерировать PDF-файлы счетов. == Настройка == === Composer === Сначала добавьте пакет Cashier в свой файл %%(t)composer.json%%: %%(t) "laravel/cashier": "~2.0" %% === Поставщик услуг === Затем зарегистрируйте %%(t)Laravel\Cashier\CashierServiceProvider%% в вашем файле настроек %%(t)app%%. === Миграция === Перед тем как начать использовать Cashier, надо добавить несколько столбцов в БД. Не волнуйтесь, вы можете использовать Artisan-команду %%(sh)cashier:table%% для создания миграции, которая добавит необходимые столбцы. Например, чтобы добавить столбец в таблицу пользователей, используйте %%(sh)php artisan cashier:table users%%. После создания миграции просто выполните команду %%(sh)migrate%%. === Установка модели === Далее добавьте %%(t)BillableTrait%% и соответствующий мутатор даты в определение вашей модели: %% use Laravel\Cashier\BillableTrait; use Laravel\Cashier\BillableInterface; class User extends Eloquent implements BillableInterface { use BillableTrait; protected $dates = ['trial_ends_at', 'subscription_ends_at']; } %% === Stripe-ключ === Наконец, внесите ваш Stripe-ключ в один из своих загрузочных файлов: %% User::setStripeKey('stripe-key'); %% == Подписка на план == Когда у вас есть экземпляр модели, вы легко можете подписать пользователя на данный Stripe-план: %% $user = User::find(1); $user->subscription('monthly')->create($creditCardToken); %% Если надо применить купон при создании подписки, используйте метод %%withCoupon%%: %% $user->subscription('monthly') ->withCoupon('code') ->create($creditCardToken); %% Метод %%subscription%% автоматически создаст Stripe-подписку, а также внесёт в базу данных ID Stripe-клиента и другую необходимую биллинговую информацию. Если для вашего плана в Stripe настроен пробный период, то дата окончания этого периода будет также автоматически задана для пользователя. Если пробный период вашего плана **не** настроен в Stripe, вам надо вручную задать дату окончания после применения подписки: %% $user->trial_ends_at = Carbon::now()->addDays(14); $user->save(); %% === Указание дополнительной информации о пользователе === Если вы хотите указать дополнительную информацию о клиенте, вы можете передать её в качестве второго аргумента в метод %%create%%: %% $user->subscription('monthly')->create($creditCardToken, [ 'email' => $email, 'description' => 'Our First Customer' ]); %% Прочитайте ((https://stripe.com/docs/api#create_customer документацию по созданию клиентов)), чтобы узнать больше о дополнительных полях, поддерживаемых в Stripe. == Без предоплаты == Если в вашем приложении будет бесплатный пробный период, не требующий предварительного предъявления кредитной карты, установите свойство %%cardUpFront%% вашей модели в %%false%%: %% protected $cardUpFront = false; %% При создании аккаунта не забудьте установить дату окончания триальной версии в модели: %% $user->trial_ends_at = Carbon::now()->addDays(14); $user->save(); %% == Подключение к подпискам == Чтобы переключить пользователя на новую подписку, используйте метод %%swap%%: %% $user->subscription('premium')->swap(); %% Если у пользователя была триальная подписка, он будет переключен на обычную. Кроме того, если у подписки есть "количество", то оно тоже применится. == Количество подписок == Иногда подписки зависят от "количества". Например, ваше приложение стоит 10$ в месяц с одного пользователя учётной записи. Чтобы легко увеличить или уменьшить количество вашей подписки, используйте методы %%increment%% и %%decrement%%: %% $user = User::find(1); $user->subscription()->increment(); // Добавить 5 к текущему количеству подписок... $user->subscription()->increment(5); $user->subscription->decrement(); // Вычесть 5 от текущего количества подписок... $user->subscription()->decrement(5); %% == Отмена подписки == Отменить подписку проще пареной репы: %% $user->subscription()->cancel(); %% При отмене подписки Cashier автоматически задаст столбец %%(t)subscription_ends_at%% в вашей базе данных. Этот столбец используется, чтобы знать, когда метод %%subscribed%% должен начать возвращать %%(t)false%%. Например, если клиент отменит подписку 1 марта, но срок подписки по плану до 5 марта, то метод %%subscribed%% будет продолжать возвращать %%(t)true%% до 5 марта. == Возобновление подписки == Если подписка была отменена пользователем, и вам надо её возобновить, используйте метод %%resume%%: %% $user->subscription('monthly')->resume($creditCardToken); %% Если пользователь отменит подписку и затем возобновит её до того, как она полностью истекла, тогда не произойдет моментального расчёта оплаты. Его подписка будет просто повторно активирована, и расчёт оплаты будет происходить по изначальному циклу. == Проверка статуса подписки == Чтобы проверить, что пользователь подписан на ваше приложение, используйте метод %%subscribed%%: %% if ($user->subscribed()) { // } %% Метод %%subscribed%% создает отличный вариант для фильтра маршрута: %% Route::filter('subscribed', function() { if (Auth::user() && ! Auth::user()->subscribed()) { return Redirect::to('billing'); } }); %% Вы также можете определить, идёт ли до сих пор триальный период у пользователя (для подходящего пользователя) с помощью метода %%onTrial%%: %% if ($user->onTrial()) { // } %% Чтобы определить, был ли пользователь ранее активным подписчиком, но позже отменил подписку, используйте метод %%cancelled%%: %% if ($user->cancelled()) { // } %% Вы можете также определить, отменил ли пользователь подписку, но находится все ещё на "льготном периоде", пока подписка полностью не истекла. Например, если пользователь отменяет подписку 5 марта, которая по плану закончится 10 марта, пользователь будет на "льготном периоде" до 10 марта. Обратите внимание на то, что метод %%subscribed%% всё ещё возвращает %%(t)true%% в это время. %% if ($user->onGracePeriod()) { // } %% Метод %%everSubscribed%% используется для определения, подписывался ли пользователь когда-либо на ваше приложение: %% if ($user->everSubscribed()) { // } %% Метод %%onPlan%% используется для определения, подписан ли пользователь на данный план на основе его ID: %% if ($user->onPlan('monthly')) { // } %% == Обработка неудавшихся платежей == Что если кредитная карта клиента искекла? Никаких проблем - Cashier включает в себя контроллер Webhook, который может легко отменить подписку клиента. Просто укажите путь к контроллеру: %% Route::post('stripe/webhook', 'Laravel\Cashier\WebhookController@handleWebhook'); %% Вот и всё! Неудавшиеся платежи будут перехвачены и обработаны контроллером. Контроллер отменит подписку клиента после трёх неудавшихся платежных попыток. URI %%(t)Stripe/webhook%% в этом примере взят просто для примера. Вам надо настроить URI в параметрах вашего Stripe. == Обработка других webhook'ов Stripe == Если у вас есть дополнительные webhook-события для Stripe, которые вы хотели бы обработать, просто наследуйте контроллер Webhook. Ваши имена методов должны соответствовать принятому в Cashier соглашению, в частности, методы должны быть снабжены префиксом %%(t)handle%% и именем того webhook-события Stripe, которое вы хотите обработать. Например, если вы хотите обработать webhook %%invoice.payment_succeeded%%, вы должны добавить метод %%handleInvoicePaymentSucceeded%% в контроллер. %% class WebhookController extends Laravel\Cashier\WebhookController { public function handleInvoicePaymentSucceeded($payload) { // Обработка события } } %% .(alert) Кроме обновления информации о подписке в вашей базе данных, контроллер Webhook также отменит подписку через Stripe API. == Счета == Вы можете легко получить массив счетов пользователя, используя метод %%invoices%%: %% $invoices = $user->invoices(); %% При просмотре счетов клиента вы можете использовать эти вспомогательные методы, чтобы вывести на экран соответствующую информацию о счёте: %% {{ $invoice->id }} {{ $invoice->dateString() }} {{ $invoice->dollars() }} %% Используйте метод %%downloadInvoice%%, чтобы cгенерировать PDF-файл счёта. Да, это действительно так просто: %% return $user->downloadInvoice($invoice->id, [ 'vendor' => 'Your Company', 'product' => 'Your Product', ]); %%