Stripeでプラン(サブスクリプション)の変更 with Laravel

Stripe VueJS PHP

意図

  • Freeプラン(無料)
  • Basicプラン(有料)
  • Standardプラン(有料)

があった場合、それらを作成/変更したい。また、Freeプランは、アカウントを作成した段階の状態とする。

サブスクリプションを実装する場合、顧客のデータが必要になる。

  • メールアドレス
  • StripeID
  • paymentMethod

が顧客データに最低限必要なデータになる。また、請求先住所、支払い先住所は任意で紐づけることができる。

Stripeの全体的な支払い機能は、Stripe 支払い
顧客関する情報は、Stripe 顧客
サブスク作成の概要は、Subscriptions with Checkout and the customer portal

作成する機能

  • 領収書発行
  • 次回請求月/キャンセル日の確認
  • カード情報の作成/変更
  • カード情報の削除(unsubscribedの場合のみ)
  • カード番号(下四桁)とカードブランドの確認
  • サブスクリプションの作成/変更
  • サブスクリプションのキャンセル/次回請求月までサービスの利用
  • 決済時にメールアドレスで連絡
  • 引き落とし出来ない場合にメールアドレスで連絡

※サブスクリプションのプラン(商品)は直接Stripeから取得し、表示する

基本的な機能

  • サブスクリプションの作成 -> 顧客の作成/購読中(subscribed)にステータスを変更
  • サブスクリプションの解約 -> キャンセル済(cancelled)に変更
  • サブスクリプションの解約の取り消し -> 購読中(subscribed)にステータスを変更
  • サブスクリプションのプランを変更
  • 顧客のカード情報の更新 -> 顧客のpaymentMethodの変更
  • 顧客のステータスの確認

おそらく、顧客のステータスとプランを確認し、ユーザーにサービスの利用権限を与えるように実装すると思う。また、Stripe Webhookで決済が作成したかなども実行する必要がありそう。(Webhook でイベント通知を受信する)

Vue.js側のTIPS

Subscription.jsというStoreを作り、細かい粒度でデータを分けてcomputedを使いやすくする。また、Vuexの設計に乗っ取り、「ActionsでAPIを呼び出し、MutationsでStateの変更、gettersをcomputedで取得し、描画する」ことを意識する。グローバルに使用するデータに関するものはActionsに記載し、Mutationsまでつなげる。

メリット

  • Store: User.jsの肥大化を避ける。(モジュール分割)
  • ObjectのSetでcomputedがうまく動いてくれない問題を避ける。
const state = {
  status: null,
  planId: null,
  planName: null,
  cardBrand: null,
  cardLastFour: null,
  endDate: null
}

const getters = {
  status: (state) => {
    return state.status
  },
  planId: (state) => {
    return state.planId
  },
  planName: (state) => {
    return state.planName
  },
  cardBrand: (state) => {
    return state.cardBrand
  },
  cardLastFour: (state) => {
    return state.cardLastFour
  },
  endDate: (state) => {
    return state.endDate
  }
}

const mutations = {
  SET_STATUS (state, status) {
    state.status = status
  },
  SET_PLAN_ID (state, planId) {
    state.planId = planId
  },
  SET_PLAN_NAME (state, planName) {
    state.planName = planName
  },
  SET_CARD_BRAND (state, cardBrand) {
    state.cardBrand = cardBrand
  },
  SET_CARD_LAST_FOUR (state, cardLastFour) {
    state.cardLastFour = cardLastFour
  },
  SET_END_DATE (state, endDate) {
    state.endDate = endDate
  }
}

+Actionsに、プロパティを確認し、まとめてMutationsするActionsを作成しておく。

環境

資料