ボクココ

個人開発に関するテックブログ

月額課金モデルの Web サービスの設計方法

ども、@kimihom です。

今回は月額課金モデルの Web サービスを実現したい企業向けに設計の参考になる情報を提供できればと思う。こういう情報は割と自分なりに設計して実装するっていうパターンが多いかと思うが、とても大事なことなので慎重に検討していこう。

決済サービスの選択

まずは決済サービスをどれにするかって話。ここで一番大事なのは、扱うカード提供会社の種類だ。 Visa, Master は当然として、その他のクレジットカード会社が使えるのかどうか。ここは顧客のカード登録の自由度を決めるので、実は決済手数料よりもよっぽど大事な項目になる。要チェックだ。

あとは企業によっては収益が出た後の支払いフローも確認しておいたほうがいいかもしれない。収益の確定はいつで、支払いはいつなのか。黒字倒産するほど急成長することは稀だとは思うが、そのあたりのキャシュフローも事前に把握しておく必要がある。

あとは最低限クレジットカードの登録と、そのカード情報をトークン化して決済ができる仕組みがあれば大丈夫だ。

最終的にどのクレジットカード決済サービスを使うべきかは自らの意思で判断していただきたい。

決済フローの設計

さて、月額課金モデルと一口に言えど色々な方法が存在する。以下のようなバリエーションを考えなければならない。

有料プランは単一か複数か

当然単一の課金プランであればシンプルで実装しやすい。途中のプランアップグレードを考える必要はないし、プランごとに機能を出し分けたりする必要もないからだ。

プランを複数用意するケースってのは、使って欲しいターゲットがそれぞれいて、そのターゲットに向けた特別な機能を上位プランでは提供したいという場合になるだろう。ということで、最初のローンチでは単一プランしかなかったとしても、今後利用の想定ユーザーが増えていくにつれて、単一プランから複数プランに変わることも十分にあり得る。だから単一プランを選んだとしても今後複数プランが出てきた時にどうすべきかはあらかじめ考えておいたほうがいい。

ひとまずデータベースには plan が作られ、id, price, name が最低限必要になるだろう。

毎月いつの決済となるか (ユーザーがアップグレードした日なのか、全ユーザーが每月末、每月初なのか)

いつのタイミングで決済するのがベストなのだろうか。代表的な2つの方法を紹介する。

まずユーザーが10日にアップグレードしたら毎月10日に課金が走るパターン。これはユーザーにとってわかりやすいし、料金の計算も毎月固定額だからイメージしやすい利点がある。ただし、ユーザーごとに決済の日時が変わってしまうので、運用する側は常に毎日何かしらの決済コードを走らせ続ける or API 側で実行しなければならない。これは例えばメンテナンスをしたいという時もとても慎重になる必要があったり、コードの修正などもリリース前とリリース後でユーザーに不備が出ないように慎重になる必要がある。つまり、この方法はよほどプランや料金体系が固定化されていない限り、やがて困難を伴うことになるだろう。

私のオススメは月末や月初に企業毎に逐次決済していく方法だ。これであれば、基本的に決済は毎月末だけ集中すれば良いのでメンテナンス的にも気持ち的にもありがたい。決済はできる限りシンプルにさせることでトラブルを防ぐことができる。ただこの方法の問題を挙げるなら、有料にしたその日から月末までの料金をどうするかという話だ。この場合、次回課金日時までの日割り料金を決済させるか、思い切ってそこは無料にするかのどちらかになるだろう。おそらくどのサービスもトライアル期間を設けるだろうから、そのトライアルの期間が 3か月みたいな長めに設定できるサービスであれば、初月は日割りをなくして無料にするという方法がいいかもしれない。トライアルが2週間で切れるようなサービスであれば反対に日割り料金で初月は決済するような流れになるだろう。

基本的にはユーザーには先払いの仕組みとなるだろう。ユーザーが料金を支払っていただいたら、その後の1か月もしくは1年使える権利を買ったことにする方法である。ただし、従量課金制にした場合にはそのようにはいかない。従量課金制の場合は前月いくら使ったのかを計算して、月末や月初でそれを請求するか、キャッシュフローを考慮してポイントとして購入していただくかどちらかの方法を選ぶことになるだろう。

うちの場合は月末に来月のシステム利用料と、当月の利用実費(従量) を足し合わせた金額を請求する実装にしている。

このように決済方法は今後どんどん変わっていく可能性があるから、決済サービスで提供される Subscription の仕組みはできる限り自前で実装した方がいいと思う。

私の場合、 bill_history テーブルを用意し、target_month, plan_id, price, charge_id, contract_id を指定している。特に大事なのが charge_id。決済に成功した場合に、その戻り値である charge_id を保存するようにしよう。これは後述する決済失敗の判断材料になる。

また bill_history にも price を入れているのは、プラン以外の毎月変動する合計としての金額をここに保存するためだ。例えばライセンス数に応じて料金が変わったり、アドオンを追加して料金が加わったり、従量課金を追加して料金が加わったり。そんなパターンを合計した金額を bill_historyprice に入れよう。

プランが複数の場合、ユーザーが途中でアップグレードした時にその決済をどうするか

有料プランから有料プランのアップグレードは地味に計算が大変だ。既に今月分の A プランを支払っていて、アップグレードしたらさらに B プランの料金も支払ってもらうことにしてしまうと、ユーザーは余計に料金を支払わなければならない。A - B の日割り額を差分として頂くか、来月初からプランアップグレードが適用になるかのどちらかの設計になるだろう。

来月初からプラン適用、という設計の場合、あらかじめ bill_historyに来月分のレコードを1つ追加してあげて、定期決済時に来月分の bill_history が既に作られていたら、そのプランでの料金を請求する実装にすれば良い。

プラン以外での課金が発生するか。その課金はどのタイミングで決済されるか

これは例えば毎月末に全ユーザーの決済をすると決めた場合、その他の決済が行われるタイミングも考慮する必要があるということだ。

例えばトライアルから有料へアップグレードした瞬間、その日から月末までの日割り料金を請求する場合はその時点で課金が発生する。またプランアップグレードで当日からプランのアップグレードを適用する場合にも日割り料金が発生するだろう。

従量課金制の場合、退会時にも既に使っていた料金分を請求する必要がある。

これらあらゆるパターンで決済が発生する可能性があるので、自社サービスに最適な決済フローを設計しよう。

決済に失敗した時にどのように対応するか

そして定期課金で最も厄介なのが決済に失敗した企業へのアプローチだ。

決済に失敗することは実は非常によく起こる。50社いたら2,3 社は毎月失敗すると考えてよい。その場合、即退会だとか使えなくするだとかはあまりに厳しすぎるので、一時的に支払ったことにして使える状態にしなければならない。

ここで先ほどの bill_history に保存した charge_id が活躍する。決済に失敗した場合は charge_id に値を保存できないので、charge_id が空の状態の bill_history が作られる。 月末課金だとしたら、 毎月 3, 8, 15 日に再決済のスケジュールを立てて、当月の bill_hisotrycharge_id が空のレコードを取得し、そこで保存された前月請求額の price を再決済するようにすれば良い。もし成功すれば charge_id を保存しておくということになる。

クレジットカード起因で決済に失敗した場合、対象ユーザーへカード変更の依頼を促すメールを送る実装をすれば、毎月の決済フローをほぼ自動化できる。最終トライの時にカード決済が失敗したら そのユーザーをどうするかってのはサービス次第で決めよう。経験上、3回リトライの仕組みを実装すれば、少なくとも2回目でほぼ全ユーザーの決済は成功する。3回目でも失敗する場合は明らかにその企業が退会を決意したくらいしか起き得ない。

月額課金を自前で作るか、Webサービスに任せるか

改めて月額課金の仕組みを自前で作るか Web サービス側に任せるかを検討したい。

まず自前で月額課金の仕組みを作るのは、実はさほど難しくはない (テストは大変だが)。多少の手間をかけて、今後のサービスの料金体系変更に強くさせるのは良いことだと私は考えている。決済に失敗した時の課金まで実装できれば、基本的に Web サービス側で提供する月額課金 (Subscription) の仕組みと同じものを作れる。

反対に Web サービス側で提供されている定額課金 (Subscription) の仕組みを使うべきはどんな時か。これは私の思うことに過ぎないけども、今後のサービスにおいてプラン変更や料金変更がほとんどなく確定されたものであり、かつその決済サービスが(どこかの決済サービスとは違って)残り続けるという確証が持てる場合は選択しても良いだろう。その条件を飲み込めば、月額課金の仕組みをとても素早く構築に、そして確実に実装できる利点が手に入れられる。また、年額決済のサポートなども決済サービスによっては対応しているところもあり、これらの仕組みをささっと導入できる魅力は大きい。自前で月額と年額をそれぞれ実装するのはなかなか大変だ。

両者どちらもトレードオフがあるので、最終的に決めるのは開発者自身である。

終わりに

月額決済の仕組みはしっかりと設計する能力が求められる。ビジネス的なキャッシュフロー、そしてそれに伴う決済のタイミングや料金の計算方法。どれも念入りにあらゆるパターンを考慮した上で実装していこう。

最近は各クレジットカード決済会社がテスト環境と本番環境を完全に分離して開発及びテストをしやすくさせてくれている。そのため入念にテストをすれば、自信を持ってユーザーに決済サービスを提供できることだろう。

これから月額課金モデルのサービスを作る方に有意義になれば幸いだ。