IP事務所向けSaaS「PatentLLM」の課金システムをStripe Checkoutで実装した話
## 導入 米国の特許事務所向けに月額$1,000で提供する「PatentLLM」の商用化に向け、課金システムの実装に取り組みました。既存機能(FTS5検索・Brave Web検索・専門分析プロンプト)は実装済みでしたが、課題は「課金ゲートの構築」「営業リストの整備」「英語UIの微調整」に集中。特に課金システムでは、**カード情報のセキュリティ確保**と**ユーザー体験の最適化**が最大の焦点でした。この記事では、Stripe Checkoutを活用した実装プロセスと工夫した設計方針を、エンジニア視点で振り返ります。
## 本文 ### 課題:課金ゲートの構築 初期段階では、StripeのAPIを直接呼び出して課金処理を行う案も検討しましたが、以下の理由で見送りました。 - **セキュリティリスク**:カード情報をサーバーで管理すると漏洩リスクが高まる - **ユーザー体験の悪化**:支払い中にエラーが発生するとアプリ全体が利用不能に
代わりに**Stripe Checkoutを埋め込む設計**を採用。アプリ内に「Subscribe」ボタンを配置し、ユーザーが直接Stripeの決済画面で入力する仕組みにしました。これにより、以下のメリットを実現しました: - カード情報はStripe側でのみ管理(当サーバーに一切保持しない) - 決済成功時に自動でサブスクリプション状態をローカルSQLiteにキャッシュ - Stripe APIにフォールバックするため、ネットワーク障害時もサブスクリプション確認が可能
### 設計の工夫:Gracefully Degradationとローカルキャッシュ `.env`ファイルに`STRIPE_SECRET_KEY`を設定しない場合やテストキー(`sk_test_xxx`)が入っている場合、**課金ゲートを無効化**するロジックを実装しました。これにより: - 開発環境で動作確認が容易 - 本番環境移行時に設定ミスによるサービス停止を防止
また、サブスクリプション状態をローカルの`subscriptions.db`(SQLite)にキャッシュ。有効期限が切れた場合や未登録の場合にのみStripe APIで再確認する仕組みにしたことで、APIコールの頻度を最小限に抑えました。
### 営業資料の整備:CSVリストとテンプレート 営業活動を効率化するため、**100社の米国IP事務所リスト**(Tier 1〜5に分類)をCSVで生成。Tier 1はFish & Richardsonなど大手16社、Tier 2は中堅24社と、戦略的に優先順位を付けたリストを作成しました。併せて、以下の要素を含む営業テンプレートを用意: - 件名(100文字以内) - 本文(150語以内) - フォローアップのタイミング
特にTier 1企業には、**「他社と差別化できる分析機能」**を強調し、機能一覧ページへの誘導ボタンを配置しました。
### 英語UIの微調整 サブスクリプション未登録ユーザー向けに、以下のUIを追加: - サイドバーに「Subscription」セクション(残り日数表示+Customer Portalリンク) - 「Subscribe」ボタンをメイン画面に配置し、価格・機能一覧ページへ遷移
Stripe Customer Portalを有効化した