🌈

StripeBillingでサブスクサービスやってみた

2023/04/17に公開

こんにちは。バックエンドエンジニアの山本和久です。好きなStripeの機能は「Stripe CLI」です。Webhookをローカルにforwardしてくれる機能便利ですね!
さて、今回のネタは対面診療の分野でStripeBillingを使ってサブスクサービスを構築してみたので、その紹介となります。

StripeBillingを選択した理由

今回開発したのは毎月定額で美容施術・注射・点滴を受けることができる美容サブスクサービスです。
すでにリンクウェルでは薬の定期配送というサービスを行っており、患者目線でいうとサブスクサービスをすでに行っている状態にありました。このサービスの請求の仕組みはRubyのrake taskの定期実行によってStripe APIを叩くことで実現されています。薬の「配送」という物理の業務が絡んでくるため、より柔軟に状態把握できるRubyによる内製を選択した経緯があります。
一方、美容サブスクは「配送」という物理業務が絡まないためStripeBillingに載せやすい背景がありました。
インターネット決済ではなく、リアルに存在するクリニックでStripe決済を使う事に疑問を感じる方がいらっしゃるかもしれません。実はリアルなクリニックでも決済処理はそれなりに負担となっており、StripeBillingを利用することで毎月自動決済が発生するので美容サブスクとのマッチングは良いのです。

決済のフロー

決済用QRコードがクリニックのカウンターに置かれており、これを患者が読み取ることで決済が行われます。決済画面はReactで作られており、バックエンドのRailsとGraphQLを使ってやり取りしています。

Stripeコンソールでの操作

いきなりですが、サブスク決済にはクレジットカードのトラブルがつきものです。

  • 限度額オーバー
  • 有効期限切れ
  • 紛失による無効化

上記の理由により、決済の見送り・現金による決済・決済サイクルの調整が発生します。これらの対応をすべてAPIを発行する側(Railsアプリケーション)に持たせるのは考慮する事項が多すぎるためオススメしません。
これらのイレギュラー対応はStripeの管理コンソールを使って対応しましょう。
たとえば、現金による一時的な決済切り替えは支払いに失敗したインボイスを選択し、支払い済みに変更することで対応できます。

また、プランの変更を行った場合はどうでしょうか? 現在のプランが終了するまで待ってから、プランの変更をリクエストするのは手間ですね。
この場合も、Stripeの管理コンソールを利用してプラン変更できます。

この場合、ライトプランからプレミアムプランに変更しようとしています。右上の「比例配分による調整」にチェックを付けていると、日割り計算にも対応します。

Webhookでrailsアプリケーションと同期する

Stripe管理コンソールでサブスクリプションの設定を変更すると、Railsアプリケーションへの同期が気になります。サブスクサービスを導入しているクリニックでは患者の詳細画面から支払状況を確認しているのですが、Stripe管理コンソールで変更した内容に追随させる必要があります。
この問題に対して、StripeWebhookでStripe側の変更を監視し、Railsアプリケーションに反映する方法を取っています。

StripeWebhookを利用した開発ではStripeCLIを組み合わせることで、本来インターネットから飛んでくるWebhookをローカルで受け取ることができるようになります。つまりlocalhost:3000で起動しているrailsアプリケーションにwebhookを転送できます。
参考: Webhook を使用してアクションをトリガーする

この仕組みにより、Stripe側の決済状況を確実に取得できます。

デバッグにオススメの機能

サブスクサービスのテストは時間の経過に伴う決済を検証する必要があるため、通常の方法では時間がかかります。開発当初は請求サイクルが1日のダミー商品を作って検証していましたが、テストクロックという機能を使えばそんな手間は不要となります!
参考:テストクロックで組み込みをテストする

テストクロックでシミュレーションすることで、サブスク更新時のWebhookの動作を容易に確認できます。

まとめ

  • StripeBillingを使ったサービスはStripe管理コンソールで修正されることを前提に設計しましょう。
  • Webhookを使ってStripeの変更をWebサービスに反映させましょう。
  • テストクロックでサブスクの検証をしましょう。
Linc'well, inc.

Discussion