無料で使われ続けることの怖さ

StayFlowは民泊・ゲストハウスの管理SaaSだ。予約管理、清掃スケジュール、ゲスト対応の自動化。2025年の秋にリリースしてから、ありがたいことに500を超える施設に使ってもらっている。月間1,860ユニークビジター。

でも、全部無料だった。

無料ユーザーが増えるほどサーバーコストは増える。Supabaseの無料枠はとっくに超えていた。「いつか課金を入れなきゃ」と思いながら4ヶ月が過ぎた。

3月1日、ついにStripe Live Modeを有効にした。

2つのプランを決めるまで

料金設計は悩んだ。安すぎると運用コストをカバーできない。高すぎると離脱する。他の民泊管理ツール(Beds24、Hospitable、Guesty)の価格を調べた上で、こう決めた:

  • Starter: 月額2,900円 — 施設5件まで、基本機能すべて、メールサポート
  • Pro: 月額7,900円 — 施設無制限、AI自動応答、優先サポート、API連携

ポイントは「Starterで十分使える」こと。Proは本当に規模が大きいオーナー向け。無料プランは残さなかった。代わりに14日間のトライアルを設けた。

Supabaseから自前認証への移行

Stripe導入と同時に、もう1つ大きな変更をした。認証基盤をSupabase AuthからStayFlow自前の認証に切り替えたのだ。

理由は3つある:

  1. Supabaseの料金 — 認証ユーザーが増えるとSupabaseの有料プランが必要になる。二重課金を避けたかった
  2. カスタマイズの限界 — Supabase Authのメールテンプレートやフロー制御に制約が多かった
  3. Stripe連携 — Customer ID、Subscription ID、利用量をユーザーテーブルに直接紐づけたかった

移行はReact+Viteのフロントエンドとバックエンドの両方に手を入れる必要があった。JWTの発行・検証、パスワードリセットフロー、セッション管理。丸2日かかったが、結果的にSupabaseへの依存が認証部分からなくなり、月額コストが下がった。

Stripe統合の実装

Stripe側の設定はシンプルだった:

  1. Product + Priceの作成 — StarterとProの月額サブスクリプション
  2. Checkout Session — ユーザーがプラン選択→Stripeの決済画面→コールバック
  3. Webhookinvoice.paidcustomer.subscription.deletedで状態を同期
  4. カスタマーポータル — プラン変更・解約はStripeのホスト型ポータルに任せた

一番ハマったのはWebhookの署名検証だった。ローカルでstripe listen --forward-toを使ってテストしていたが、本番のWebhookシークレットを設定し忘れて最初の数件の決済通知を取りこぼした。幸い、Stripeのダッシュボードからリトライできたので大事には至らなかった。

初日の結果

3月1日にLive Modeを有効化して、既存ユーザーにメールを送った。「14日間の無料トライアル期間中に、ぜひお試しください」と。

初日にStarterプランに3件、Proプランに1件の申し込みがあった。月額で計算すると16,600円。サーバーコストの大部分をカバーできる金額だ。

正直、「無料だから使ってただけで、有料になったら全員離脱するんじゃないか」と怖かった。でも500施設のうち、トライアル開始から1週間で解約したのは12施設だけだった。残りはトライアルを継続している。

お金を払ってもらえるということは、プロダクトに価値があるということだ。それを数字で確認できた日だった。

技術的な詳細(自前認証の実装、Stripe Webhook設計、Supabase移行手順)はこちらにまとめている。