Laravel Cashierは Laravel公式のパッケージで、Stripe決済に必要なバックエンドの実装を肩代わりしてくれるパッケージです。
今回は、支払い方法の登録、サブスクリプションの作成について紹介します。
はじめに、Stripeでアカウントを作成します。
管理画面で、[開発者]>[APIキー]にある、「公開可能キー」と「シークレットキー」を控えておきます。
composerを使用してインストールします。
$ composer require laravel/cashier
インストール後、必要なマイグレーションファイルが追加されるため、マイグレーションを実施します。
$ php artisan migrate
envファイルに、控えておいたAPIキーを設定します。
STRIPE_KEY=公開可能キー STRIPE_SECRET=シークレットキー
Userモデル、 Billable
トレイトを使用するようにします。
これにより、Webサイトの利用者が、課金・決済することができるようになります。
コントローラから実装していきます。
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class UserController extends Controller { public function getPaymentMethod() { // クレジットカードの登録に必要なシークレットをStripeから取得する return view('users.payment_method', [ 'intent' => Auth::user()->createSetupIntent() ]); } public function postPaymentMethod(Request $request) { // Stripe顧客を作成する $stripeCustomer = Auth::user()->createAsStripeCustomer(); // トークンを受け取り、Stripeに検証した上で、usersテーブルに、支払い情報を登録する。 Auth::user()->updateDefaultPaymentMethod($request->payment_method); return response()->redirectTo('/users/payment_method'); } }
次に、ビューです。
@extends('layouts.app') @section('content') <div class="container"> <h3>支払い方法の登録</h3> カード名義人 <input id="card-holder-name" type="text"> <!-- Stripe要素のプレースホルダ --> <div id="card-element"></div> <button id="card-button" data-secret="{{ $intent->client_secret }}"> 登録する </button> <form method="post" action="/users/payment_method" id="updateForm"> @csrf <input type="hidden" name="payment_method"> </form> // StripeのJS SDKの読み込み <script src="https://js.stripe.com/v3/"></script> <script> const stripe = Stripe('{{ env('STRIPE_KEY') }}'); const elements = stripe.elements(); const cardElement = elements.create('card'); cardElement.mount('#card-element'); const cardHolderName = document.getElementById('card-holder-name'); const cardButton = document.getElementById('card-button'); const clientSecret = cardButton.dataset.secret; cardButton.addEventListener('click', async (e) => { // カード情報の登録 (Stripeとの通信) const { setupIntent, error } = await stripe.confirmCardSetup( clientSecret, { payment_method: { card: cardElement, billing_details: { name: cardHolderName.value } } } ); if (error) { alert(error.message); } else { // クレジットカードの登録に成功したので、Laravel側にトークンをPostする const updateForm = document.getElementById('updateForm'); updateForm.payment_method.value = setupIntent.payment_method; updateForm.submit(); } }); </script> </div> @endsection
Laravelの公式ドキュメントのソースコードをベースに作成しています。
支払い情報を登録する際は、コントローラー側で、 $user->createSetupIntent()
を呼び出し、結果をそのままビューに渡します。
ビュー側の登録ボタンでは、 <button id="card-button" data-secret="{{ $intent->client_secret }}">
となっており、シークレットを設定します。
ビュー側は、基本的にStripe JS SDKを使用します。カード情報はStripe側に登録させて、Laravel側にはトークンのみを受け取るようにします。
支払い情報は、Stripe顧客を作成しないと登録できないため、先に作成した上で、カード情報を登録します。
サブスクリプションを作成するには、 $user->newSubscription()
メソッドを使用して作成します。
コントローラーのコードです。
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class UserController extends Controller { public function postSubscriptions(Request $request) { // 登録済みのデフォルト支払い方法を使用 $paymentMethod = Auth::user()->defaultPaymentMethod()->paymentMethod; Auth::user()->newSubscription('default', 'プランID')->create($paymentMethod); return response()->redirectTo('/users/subscriptions'); } }
newSubscription()
メソッドの第一引数には、サブスクリプション の名前を付けます。この名前は、Laravelアプリ内のsubscriptionテーブルで管理されるもので、後からサブスクリプション の状況を確認するときにも使用します。
プランIDは、Stripeに登録済みのプランIDを指定する必要があります。
Stripe管理画面で商品を登録し、価格を登録すると表示される「API ID」を指定してください。
サブスクリプション状況を確認するには、 $user->subscribed('default')
とすることで、確認することができます。
試用期間を設定したい場合は、サプスクリプション作成時に設定します。
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class UserController extends Controller { public function postSubscriptions(Request $request) { $paymentMethod = Auth::user()->defaultPaymentMethod()->paymentMethod; Auth::user()->newSubscription('default', 'price_id') ->trialDays(7) // 7日間のトライアル ->create($paymentMethod); return response()->redirectTo('/users/subscriptions'); } }
サブスクリプション作成時に、 trialDays()
メソッドを使用することで、試用期間を設定できます。
試用期間を設定すると、Stripe側で請求日が試用期間後の日付となり、その日以降は自動的に請求が発生します。
Laravel Cashierには、Stripe PHP SDKがそのまま入っているため、直接使用することもできます。
例えば、サブスクリプション作成時に必要となる、プランは、Stripe SDKを使用して動的に増やすこともできます。
プランを作成し、そのプランIDを使用してサブスクリプションを作成するサンプルコードです。
// プランの作成 $plan = Plan::create([ 'amount' => 1000, // 1000円 'currency' => 'jpy', // 日本円決済 'interval' => 'month', // サブスクリプション の周期 'product' => ['name' => 'プレミアムプラン'] // 商品情報 ]); // 作成したプランのIDでサプスクリプションを作成する Auth::user()->newSubscription('default', $plan->id) ->create($paymentMethod);
いかがでしたか。Laravel Cashierを使用すると、Stripeの実装に必要なバックエンドの実装が、かなり軽減されることが分かりました。次回は、Laravel CashierのWeb hookや、複数の支払い方法を管理する方法について紹介したいと思います。