イントロダクション

Laravelキャッシャーは、Stripeによる購読(定期課金)サービスの読みやすく、スラスラと記述できるインターフェイスを提供します。これにより、書くことが恐ろしくなるような、購読支払いのための決まりきったコードのほとんどが処理できます。基本的な購読管理に加え、キャッシャーはクーポン、購読の変更、購入数、キャンセル猶予期間、さらにインボイスのPDF発行まで行います。

設定

Composer

最初に、composer.jsonファイルに、Cashierパッケージを追加します。

"laravel/cashier": "~5.0"(2015年2月18日以降のStripe API、およびStripe SDK 2.0まで)
"laravel/cashier": "~4.0"(2015年2月18日以降のStripe API)
"laravel/cashier": "~3.0"(2015年2月16日までのStripe API)

サービスプロバイダー

次に、app設定ファイルへ、Laravel\Cashier\CashierServiceProviderを登録します。

マイグレーション

キャッシャーを使用する前に、データベースにいくつかカラムを追加する必要があります。心配ありません。cashier:table Artisanコマンドで、必要なカラムを追加するマイグレーションが生成されます。例えば、usersテーブルにカラムを追加するには、php artisan cashier:table usersを実行します。マイグレーションを生成したら、後はmigrateコマンドを実行するだけです。

モデルの準備

次に、Billableトレイトと適切な日付ミューテターをモデルで定義してください。

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'];

}

Stripeキー

最後に、services.php設定ファイルへStripeキーを設置します。

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

初期設定(bootstrap)ファイルや、AppServiceProviderのようなサービスプロバイダーで指定する方法もあります。

User::setStripeKey('stripe-key');

プランの購読

モデルインスタンスを取得したら、そのユーザーに指定したStripeプランを簡単に購読してもらえます。

$user = User::find(1);

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

購読の作成時に、クーポンを適用したい場合は、withCouponメソッドを使用してください。

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

subscriptionメソッドは、自動的にStripeの購読を作成すると同時に、StripeのカスタマーIDと関連する支払い情報をデータベースに保存します。Stripeでプランの試用期間を設定している場合、試用終了日も自動的に、ユーザーのレコードに設定されます。

Stripeで、プランの試用期間を指定していない場合でも、購読後に手動で終了日を指定することもできます。

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

$user->save();

ユーザーの詳細情報を指定する

ユーザーに関する詳細情報を追加したい場合は、createメソッドの第2引数に渡すことができます。

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

Stripeがサポートしている追加のフィールドについては、顧客の作成に関するドキュメントをご覧ください。

一回だけの課金

定期購読している顧客のクレジットカードに対し、「一回限り」の課金を行いたい場合は、chargeメソッドを使用してください。

$user->charge(100);

chargeメソッドは通過の最低単位の課金を引数に取ります。ですから、上記の例は100セント(1ドル)をクレジットカードへ課金します。

chargeメソッドは配列で2つ目の引数も取り、Stripの課金に用意されているオプションを渡すことができます。

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

chargeメソッドがfalseを返した場合、課金失敗です。通常、これは課金が拒否されたことを意味します。

if ( ! $user->charge(100))
{
    // 課金が拒否された…
}

課金が成功したら、メソッドから完全なStripeレスポンスがメソッドから返されます。

カードの前払いなし

アプリケーションで、カードによる前払いなしの試用期間を提供する場合、モデルのcardUpFrontプロパティーをfalseに設定してください。

protected $cardUpFront = false;

アカウント作成時に、試用期間の最終日をモデルへセットするのをお忘れなく。

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

$user->save();

購読の変更

ユーザーの購読を新しいものへ変更する場合、swapメソッドを使用してください。

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

ユーザーが試用期間中の場合、試用期間は通常通りに続きます。また、その購読に"quantity"(購読数)が存在する場合、その個数も維持されます。

購読数

購読数により、購読が影響を受けることがあります。例えば、あなたのアプリケーションで、一つのアカウントごとに一月10ドル課金しているとしましょう。incrementdecrementメソッドで、簡単に購読数を増減できます。

$user = User::find(1);

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

// 現在の購読数に5つ加える…
$user->subscription()->increment(5);

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

// 現在の購読数から5つ減らす…
$user->subscription()->decrement(5);

購読の税金

キャッシャーでは、Stripeに送る「税率(tax_percent)」を上書きするのも簡単です。購読に対する顧客の支払いの税率を指定するには、モデルにgetTaxPercentメソッドを実装し、小数点以下の桁数が2桁以内で0から100までの数値を返します。

public function getTaxPercent()
{
    return 20;
}

これによりモデルごとに税率を適用できるため、多くの州や国に渡りユーザーが存在する場合に便利です。

購読のキャンセル

購読のキャンセルも、お茶の子さいさいです。

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

購読がキャンセルされると、キャッシャーは自動的に、データベースのsubscription_ends_atカラムをセットします。このカラムはいつからsubscribedメソッドがfalseを返し始めればよいのか、判定するために使用されています。例えば、顧客が3月1日にキャンセルしたが、その購読が3月5日に終了するようにスケジュールされていれば、subscribedメソッドは3月5日になるまで、trueを返し続けます。

購読の再開

ユーザーがキャンセルした購読を、再開したいときには、resumeメソッドを使用してください。

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

ユーザーが購読をキャンセルし、それからその購読を再開する場合、その購読の有効期日が完全に切れていなければ、すぐに課金されません。その購読はシンプルに再度有効になり、元々の支払いサイクルにより課金されます。

購読状況のチェック

ユーザーがアプリケーションで購入しているかを調べるには、subscribedメソッドを使います。

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

subscribedメソッドは、ルートミドルウェアにとても便利でしょう。

public function handle($request, Closure $next)
{
    if ($request->user() && ! $request->user()->subscribed())
    {
        return redirect('billing');
    }

    return $next($request);
}

また試用期間を採用している場合、そのユーザーが試用期間中であるかを判定するために、onTrialメソッドが使用できます。

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

そのユーザーが一度購読し、その後キャンセルしたかを判定するためには、cancelledメソッドが使用できます。

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

また、ユーザーが購読をキャンセルしているが、まだ完全に期限が切れる前の「猶予期間」中であるかを調べることもできます。例えば、ユーザーが3月5日に購読をキャンセルし、3月10日に無効になる場合、そのユーザーは3月10日までは、「猶予期間」中です。subscribedメソッドは、この期間中、まだtureを返すことに注目して下さい。

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

everSubscribedメソッドにより、そのユーザーがアプリケーションの、永久購読プランを持っているかを決定することができます。

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

onPlanメソッドにより、そのユーザーが指定されたIDのプランを購入しているかを判定できます。

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

購読不能時の処理

顧客のクレジットカードが、有効期限切れだったら? キャッシャーは、顧客の購読を簡単にキャンセルする、Webフックコントローラーを用意しています。コントローラーへのルートを指定するだけです。

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

これだけです! 課金の失敗は、コントローラーにより捉えられ、処理されます。コントローラーはStripeにより購入が不能だと判断されると(通常は課金に3回失敗時)、その顧客の購読をキャンセルします。この場合のURI、stripe/webhookはただの例にすぎません。Stripe設定でURIを設定する必要があります。

他のStripe Webフックの処理

処理したい追加のStripe Webフックイベントがある場合、シンプルにWebフックコントローラーを拡張してください。メソッド名はCashierが期待する命名規則に従う必要があります。つまり、メソッド名はhandleで始まり、取り扱いたいStripeのWebフックを続けます。例えば、invoice.payment_succeeded Webフックを使用したいのなら、コントローラーにはhandleInvoicePaymentSucceededメソッドを追加しなければなりません。

class WebhookController extends Laravel\Cashier\WebhookController {

    public function handleInvoicePaymentSucceeded($payload)
    {
        // Handle The Event
    }

}

注意:データベースの中の購読情報を追加で更新すると、WebフックコントローラーはStripe APIを使用し、その購読をキャンセルしようとします。

インボイス

invoicesメソッドにより、ユーザーのインボイスの配列を簡単に取得できます。

$invoices = $user->invoices();

顧客に対し、インボイスを一覧表示する場合、そのインボイスに関連する情報を表示するために、以下のヘルパーメソッドが使用できます。

{{ $invoice->id }}

{{ $invoice->dateString() }}

{{ $invoice->dollars() }}

downloadInvoiceメソッドで、そのインボイスのPDFダウンロードを生成できます。そうです、これも本当に簡単です。

return $user->downloadInvoice($invoice->id, [
    'vendor'  => 'Your Company',
    'product' => 'Your Product',
]);