BackEnd

Laravel Cashier サブスクリプションに使用するテーブルを理解する

投稿日:

はじめに

以前、Laravel Cashierを使用してサブスクリプションを実装する方法について説明しました。しかし、Laravel Cashierは単純なStripeのラッパークラスではありません。そのため、例えばクレジットカードの決済に失敗したとき、どのようにハンドリングされるのか、しっかりと把握しておく必要があります。
そこで、今回はLaravel Cashierが実際にどのようなテーブルを持ち、またStripeでサブスクリプションの自動更新が失敗した場合の仕組みについて説明したいと思います。

Laravel Cashierのテーブル

Laravel CashierはStripeのラッパーではありますが、自分でテーブルも持っています。Laravel Cashierのインストール後に、 php artisan migrate を実行すると、 vendor/larave/cashier/database/migrations 配下にあるマイグレーションが実行されます。
Subscriptionの作成時はStripeのAPIをコールしますが、課金状況のチェックなどは、基本的にテーブルの内容を見にいきます。
そのため、Laravel Cashierで使用されるテーブルが、どのような動きをするのか、把握しておくことが大切です。

usersテーブル

ユーザテーブルには、次のように追加されます。

これらのカラムは、ユーザがSubscriptionに課金し、申し込んだときに作成されます。

  • stripe_id: string
    Stripeの顧客ID ( cus_**** )が入ります。
  • card_brand: string
    支払い方法に使用するカードブランドが入ります。
  • card_last_four: string
    支払い方法に使用するカードの下4桁がはいります。
  • trial_ends_at: timestamp
    支払い情報を登録せずに、試用させる場合に、試用終了時の日付が入ります。
    例えば、機能制限無しの期間限定試用版を実装する場合に使うことができます。

subscriptionsテーブル

subscriptionsテーブルは、ユーザがSubscriptionに課金し、申し込まれる度に作成されます。

  • user_id: unsigned big integer
    ユーザIDです。 ( User クラスが、 Billable トレイトを使用すると、 $user->subscriptions で取得できます。)
  • name: サブスクリプション名
    課金後に、サブスクリプションの状況などを取得するときに使用する名前です。サブスクリプション作成時に指定します。
    $user->subscribed('サブスクリプション名') といった形で使用します。(この場合は、サブスクリプション中であるかどうかをbooleanで返します。)
  • stripe_id: string
    StripeのサブスクリフションIDが入ります。( sub_*** の形式です。)
  • stripe_status: string
    Stripeの課金状況が入ります。 $subscription->active() など、課金状況を確認するときに使用されるカラムです。
  • stripe_plan: string
    StripeのプランIDもしくは料金IDがあります。 ( plan_*** もしくは price_*** の形式です。)
  • quantity: integer
    サブスクリプションの数量です。
  • trial_ends_at: timestamp
    試用期間の終了日時です。
  • ends_at: timestamp
    課金の終了日時です。キャンセルすると、ここにサブスクリプションの最終日時が入ります。 cancelNow() メソッドでキャンセルした場合は、現在日時が入ります。

supscription_itemsテーブル

サブスクリプションに紐づく課金アイテムが入ります。

注意点としては、複数のアイテムがある場合は、 subscriptions テーブルの、 stripe_plan カラムと quantity プランはnullになります。

  • subscription_id: unsigned big integer
    subscriptionテーブルのidです。
  • stripe_id: string
    Stripeの定期支払いアイテムIDです。 ( si_*** 形式です。)
  • stripe_plan: string
    StripeのプランIDもしくは料金IDがあります。 ( plan_*** もしくは price_*** の形式です。)
  • quantity: integer
    数量が入ります。

課金情報の更新方法

実際には、利用者のクレジットカードのエラーにより、うまく自動更新できないことがあります。その場合は、Webhookを使用して、Stripe側からコールしてもらいます。
Laravel Cashierインストールすると、次のルーティングが追加されます。

このパスで、以下のWebhookを受け取ることができます。

  • customer.subscription.updated
  • customer.subscription.deleted
  • customer.updated
  • customer.deleted
  • invoice.payment_action_required

Stripeの管理画面で、これらのイベントを送信されるように設定します。
[Stripe管理画面]>[開発者]>[Webhook]>[アカウントからイベントを受信するイベント]>[+エンドポイントを追加] を開き、実際のアプリケーションのURLに、イベントが送信されるように設定します。

また、このWebhookはwebのルーティングに追加されるため、CSRF保護の対象外に設定する必要があります。 VerifyCsrfToken クラスで、対象外に設定します。

これで完了です。Stripeから決済失敗のWebhookが3回連続で届くと、先ほどの subscriptions テーブルが更新され、課金が無効になります。

さいごに

いかがでしたか。課金情報の問い合わせのために、何度もStripeにAPIリクエストすることなく、Laravel Cashierは動作しますが、Webhookをしっかり実装しないと、自動更新の失敗を検知することができません。
Laravel Cashierを使用するときは、必ずWebhookもセットで設定しましょう。

おすすめ書籍

PHPフレームワークLaravel入門 第2版 PHPフレームワーク Laravel実践開発 PHPフレームワーク Laravel Webアプリケーション開発 バージョン5.5 LTS対応 よくわかるPHPの教科書 【PHP7対応版】

blog-page_footer_336




blog-page_footer_336




-BackEnd
-, ,

執筆者:

免責事項

このブログは、記事上部に記載のある投稿日時点の一般的な情報を提供するものであり、投資等の勧誘・法的・税務上の助言を提供するものではありません。仮想通貨の投資・損益計算は複雑であり、個々の取引状況や法律の変更によって異なる可能性があります。ブログに記載された情報は参考程度のものであり、特定の状況に基づいた行動の決定には専門家の助言を求めることをお勧めします。当ブログの情報に基づいた行動に関連して生じた損失やリスクについて、筆者は責任を負いかねます。最新の法律や税務情報を確認し、必要に応じて専門家に相談することをお勧めします。


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


関連記事

rails

Railsで複合主キーのテーブルを扱う

1 はじめに1.1 前提条件2 実装例2.1 config2.2 マイグレーション2.3 モデル3 さいごに はじめに RailsでWebサービスを開発する際のDB設計では基本的にidが主キーになると ...

Go言語

FSMを使った状態管理をGoで実装する

1 はじめに2 FSMとは3 基本的な実装3.1 実装する状態管理の概要3.2 状態管理を実装する4 structを定義した応用的な実装5 FSMの可視化6 さいごに7 おすすめ書籍 はじめに 一般的 ...

aws

Amazon API Gatewayざっくり概要

1 はじめに2 Amazon API Gatewayとは?2.1 なにができる?2.2 作成できるAPIの種類2.3 REST APIとHTTP APIの違い3 Amazon API Gatewayの ...

rails

Rails 6の変更点と新機能

1 はじめに2 概要3 Rubyのサポートバージョン4 Webpacker4.1 Webpackerの設定4.2 Webpackerでのビルド4.3 ビルドしたJavaScriptファイルを読み込む4 ...

laravel logo

Laravelの基礎知識

1 はじめに2 Laravelの概要2.1 学習コストが低い2.2 Symfonyがベース2.3 DIを積極的に活用している3 ディレクトリ構成3.1 app3.2 bootstrap3.3 conf ...

フォロー

blog-page_side_responsive

2020年8月
 1
2345678
9101112131415
16171819202122
23242526272829
3031  

アプリ情報

私たちは無料アプリもリリースしています、ぜひご覧ください。 下記のアイコンから無料でダウンロードできます。