【前編】Laravel Cashier + Stripeで月額サブスクを実装する

Laravel + Reactのシングルページアプリケーション(SPA)に Laravel CashierとStripeで月額サブスクを実装する手順を記事にしてみます。実装を含めると長くなったため、記事を分けました、Laravel Cashier導入とStripeの事前設定について書きます。
全体を通して言えることとして、Laravel Cashierに関しては公式ドキュメント(日本語訳)1に使い方が網羅されています。機能が多いためボリュームがあるのですが、使い方はこちらを抜粋しながら進めます。
また、実装のやり方はいくつもあるかと思いますが、最もシンプルな方法のうちの一つを説明します。

目次

前提

Stripeアカウントが準備できていること

Stripeのテスト環境で設定を行います。
テスト環境ならどんな設定をしても料金の徴収が発生することはありません。

Laravel + Inertiajs + React のプロジェクトが作成済みであること

今回フロントエンドはReactをベースに構成されたプロジェクトで説明していきます。LaravelとStripeの連携が中心となるため、別のフレームワークをご利用でも読み替えれば実装は可能です。

Laravel Cashierのインストール

手順としては上記の公式ドキュメントに従ってインストールを進めればOKです。少し補足があるため記載します。

パッケージの導入
composer require laravel/cashier

Laravel Cashierを導入します。このパッケージは Stripe公式のPHP向けライブラリ stripe/stripe-php をラップしたものです。

パッケージファイルの公開
# マイグレーションファイル
php artisan vendor:publish --tag="cashier-migrations"

# 設定ファイル
php artisan vendor:publish --tag="cashier-config"

設定ファイルは後で少し編集しますので、公開しておきます。

マイグレーションの実行
php artisan migrate

users テーブルに紐付いた以下のテーブルが作成されます。

テーブル名概要
subscriptionsStripeの商品と対応してレコードが作成される
subscription_items商品を購入するとレコードが作成される
Stripe関連テーブル

Stripe関連設定

Stripe側の設定を行った後にLaravelプロジェクトと繋ぎ込めるように各種キーなどを設定していきます。
ドキュメントそのままのところは割愛します。

Stripe Taxの有効化

プロジェクトの設定を行う前に、Stripe Tax を有効にして、税金の自動計算・徴収をできるようにします。
以下のStripeドキュメントに従い設定を行ってください。

最後にコードを追加して、実際に税計算が実行されるようにします。プロジェクトへの実装に関しては、以下をそのまま実施すればOKです。

カスタマーポータルの有効化

カスタマーポータルとは、以下のようなユーザーが選択中のプランを確認だったり、キャンセルや請求書のダウンロードが行える画面のことです。後半ではフロントからこの画面を開けるように実装しますので、この機能を有効にしておきましょう。

設定に関しては有効にするだけで利用を開始できますので、取り立てて書くことはありません。
文言やアイコン変更といった、見た目のカスタマイズ機能が充実していますので、サービスに合わせて変更すると良いと思います。

サブスクリプションを1つに制限

サービス内容によるのでお好みですが、今回はシンプルにするためにも1つのサブスクしか選べないようにします。

Stripeの設定と繋ぎ込み

Stripe管理画面でリソースの作成を行い、それらをLaravelプロジェクトに設定していきます。

Billableモデルの実装

ドキュメントに従いUser クラスを請求可能なモデルとするためにトレイトを追加します。そしてAppServiceProviderクラスのbootメソッドで呼び出すことで初期設定をして利用できるように準備します。

環境変数の追加

環境変数の設定を行なって、Stripeと繋ぎこみをします。

# 基本設定
STRIPE_KEY={Stripeアクセスキー | pk_test_xxx}
STRIPE_SECRET={Stripeシークレットキー | sk_test_xxx}
STRIPE_WEBHOOK_SECRET={Stripe webhook接続のシークレットキー | whsec_xxx}

# プラン関連
STRIPE_PROFESSIONAL_PLAN={Stripeで作成した商品ID | price_xxx}

# cashier関連
CASHIER_CURRENCY=ja_JP
CASHIER_CURRENCY_LOCALE=ja_JP
CASHIER_LOGGER=stack

Stripeの基本設定、プラン関連は管理画面から以下の手順で各種キーが取得できます。

補足事項

  • webhookのローカルテストに関しては後述するCLIコマンドで可能です。
  • 商品IDは作成した商品に対応して設定します。
    今回はテスト用にprofessionalプランを作成して、そのIDを記載しています。
設定の追加
[
    // 以下を追加
    'stripe' => [
        'professional_plan' => env('STRIPE_PROFESSIONAL_PLAN')
    ]
]

先ほど追加した環境変数から商品IDを取得をして、設定からアクセスできるようにしておきます。

動作確認

Stripeの顧客を作成して、前の手順で作成をした professionalプランを購入してみます。
以下の手順で動作確認しましょう。

  • テストユーザーを一件作成する
  • tinkerを起動して、以下のコードをコピペ
  • Stripeから支払いが作成されていることが確認できたら完了
$user = App\Models\User::first();
$paymentMethod = 'pm_card_visa';

$user->createAsStripeCustomer([
    'address' => [
        'line1' => '青葉町3-12-7',
        'city' => '新宿区',
        'postal_code' => '160-0023',
        'state' => '東京都',
        'country' => 'JP',
    ],
]);

$user->newSubscription('default', config('stripe.professiona_plan'))->create($paymentMethod);

顧客の作成には複数の方法があります

支払いの確認はこちらが参考になります

終わりに

Stripeを使って月額サブスクを実装するための準備を行いました。機能がたくさんあるため、実現したいことによって設定内容やどのように設計・実装していくのか、迷うポイントだと思います。なので本記事ではよくあるユースケースの一つの実装を通して諸々の機能を理解することで、サービスの開発に活かして貰えるように書いてみたつもりです。
とはいえLaravel Cashier, Stripeどちらもまだ知らない機能があると感じています。また、これからも機能追加されるはずなので、もっと良いやり方があれば改善していきたいところです。

以上、ここまでお読みいただき、ありがとうございました。

  1. 11.x Laravel Cashier (Stripe) Laravel ↩︎
目次