Upgrade to Pro — share decks privately, control downloads, hide ads and more …

サブスクリプション決済入門 Stripeでの実装方法と、要件定義時のポイント/jp_stripes_okayama_vol3

サブスクリプション決済入門 Stripeでの実装方法と、要件定義時のポイント/jp_stripes_okayama_vol3

Hidetaka Okamoto (Stripe)

November 12, 2022
Tweet

More Decks by Hidetaka Okamoto (Stripe)

Other Decks in Technology

Transcript

  1. サブスクリプション決済入門 Stripeでの実装方法と、要件定義時のポイント JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on

    Rails勉強会 @hidetaka_dev Npv 2022 1
  2. 今日のトピック • サブスクリプション契約をどう実装するか • サブスクリプションサービスは、 「契約してから」が本番 • Webhookを利用した「イベント駆動アーキテクチャ」で、 顧客との関係や契約内容などの「状態変化」を積極的にサポートしよう 2

    JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会 #jp_stripes
  3. 岡本 秀高 ( @hidetaka_dev ) • Stripe Developer Advocate (ex-developer

    in Digitalcube) • JavaScript / TypeScript developer ◦ AWS Lambda / CDK ◦ Next.js / React ◦ WordPress / Alexa / etc • AWS Samurai 2017 / AWS Community Day APAC 2017 • QiitaでStripeに関する Dev blogを週2/3本で更新中 ◦ https://qiita.com/hideoka moto ◦ 年間120記事ペース 3 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会 #jawsdays2022
  4. 今日のトピック • サブスクリプション契約をどう実装するか • サブスクリプションサービスは、 「契約してから」が本番 • Webhookを利用した「イベント駆動アーキテクチャ」で、 顧客との関係や契約内容などの「状態変化」を積極的にサポートしよう 4

    JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会 #jp_stripes
  5. サブスクリプション契約は、SaaS API呼び出しで作れる • Stripeをはじめとする さまざまな決済プロバイダ • Shopifyなど、 サブスク系APIを持つSaaS • 顧客の情報(メアドなど)と

    契約内容(プラン・期間)を システムに渡して契約作成 • 決済は決済手段や契約フロー によってタイミングが異なる 5 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会 Stripe::Subscription.create({ customer: 'cus_MmSiMyF3vDdf1v', items: [ {price: 'price_1KP0LPB9L6GiXTODpIaMZnUr'}, ], })
  6. https://github.com/pay-rails/pay 6 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on

    Rails勉強会
  7. サブスクリプション契約は、どこで管理すべきか? • 基本的には「SaaSに任せる」方が、開発・運用コストが低い ◦ 契約更新や請求などの、スケジュールジョブ ◦ 未払いや超過振込などの、イレギュラーイベントへの対応 ◦ 配送・請求先住所などの個人情報管理など •

    マーケットプレイスSaaSや「EC構築システム」などでは、自社管理も ◦ 例: WooCommerce + WooCommerce Subscription ◦ 「出店者が、決済プロバイダを選びたい」ケース ◦ 決済プロバイダ毎のサブスクAPIをラップするのではなく、 自前で管理して都度都度の決済処理だけ移譲する 7 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会 #jp_stripes
  8. SaaSによっては、API以上の機能提供も 8 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on

    Rails勉強会 Stripeがホストする顧客マイページ 埋め込み型の料金表 https://twitter.com/rdlabo/status/1585532646859358209 https://stripe.com/docs/customer-management/activate-no-code-customer-p ortal <script async src="https://js.stripe.com/v3/pricing-table.js" ></script> <stripe-pricing-table pricing-table-id="prctbl_xxxxx" publishable-key="pk_test_xxxxx" ></stripe-pricing-table>
  9. 契約情報とユーザー情報の紐付け方 • Stripeの場合、「同一メールアドレス」で「複数のCustomer」が作れる -> メールアドレスをキーにStripeデータを検索する方法はお勧めしない • ユーザーDBにcustomer.idを保存できるようにするのがベター • SQLでの検索などで取りたい情報がある場合、 Stripe

    Webhookで新しい情報を取得してUPDATEが理想 • 管理やバッチ目的なら、StripeのSearch APIを使って検索するのも手 9 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会 #jp_stripes
  10. サブスクリプションを組み込む方法 • 基本的には、利用する決済プロバイダやSaaSのAPIを使おう ◦ 決済プロバイダに依存したくない場合は、 自前での請求システム構築も検討する必要がある • システムのユーザー情報と、Stripeなどの顧客・契約情報を紐づけよう ◦ 「システムの外」で契約が変わることもあるため、

    Webhookでのsyncを推奨 • 決済プロバイダ・SaaSの便利機能で開発工数を圧縮しよう 10 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会 #jp_stripes
  11. 今日のトピック • サブスクリプション契約をどう実装するか • サブスクリプションサービスは、 「契約してから」が本番 • Webhookを利用した「イベント駆動アーキテクチャ」で、 顧客との関係や契約内容などの「状態変化」を積極的にサポートしよう 11

    JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会 #jp_stripes
  12. サブスクリプションは、「契約してからが本番」 • サブスクリプションは、「契約し続けてもらう」必要がある ◦ 使わないサブスクサービスは、解約される ▪ 競合他社への乗り換え: 「もっと安いor便利なサービスにしよう」 ▪ 需要の消失:

    「子どもが成長したので、もう使わない」 ◦ 物理的に「解約させない」のは、特商法違反になる恐れ ▪ 令和4年6月1日施行 ▪ トライアルから有料への移行に関する情報や、 キャンセル・解約フローに関する条項の事前告知が必須に ▪ https://www.caa.go.jp/policies/policy/consumer_transaction/specified_commercial_t ransactions/assets/consumer_transaction_cms202_220601_05.pdf 12 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会 #jp_stripes
  13. 13 令和3年に改正された特定商取引法への対応 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on

    Rails勉強会 令和3年特定商取引法・預託法の改正について https://www.caa.go.jp/policies/policy/consumer_transaction/amendment/2021/ 最終確認画面に 右の6情報を表示する ・トライアル終了後の請求額 ・期間限定商品の販売期間 ・解約方法や医薬品 誤認を与える表示がある場合 申込の撤回が可能になる事も
  14. 完全に解約したいのか、「今は使いたくない」なのか • 解約ユーザーには、「今は必要ない(また使うかも)」ケースもある ◦ 長期出張が決まったので、ジムや食品の定期注文を解約したい ◦ 今期は見たい番組・作品が少ないので、解約したい ◦ 花粉症がひどいので、春先だけは利用できない •

    「休会」のオプションで、ユーザーが帰ってきやすい環境を作る ◦ 解約 -> 入会はステップが多い ▪ カード情報や個人情報などの再入力が必要 ◦ 休会で、「請求」と「システムの利用」だけを停止する 14 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会 #jp_stripes
  15. Stripeを利用して、休会機能を組み込む • “Subscriptionの更新”で処理 • 契約自体は残るため、 DB側のID更新などは不要 • 請求書そのものは 継続して発行される点に注意 ◦

    請求書を発行後、 「無効」として処理 • 再開時は、pause_collection をnilにするだけ • 休会期間の指定も可能 15 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会 https://qiita.com/hideokamoto/items /1a5f8549d862f7fc9d4b Stripe::Subscription.update( 'sub_123456789', { pause_collection: { behavior: 'void' } }, )
  16. Webhookイベントで、休会開始・終了を検知 • subscription更新のイベントを Webhook APIで受信 • 休会開始と終了を検知し、 システム側のDB情報を更新 • 「問い合わせベースでの休会」など

    APIを通さないケースに備える • 休会ユーザーは、 「カスタマーポータル」に飛ばす手も 16 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会 https://qiita.com/hideokamoto/items /1a5f8549d862f7fc9d4b
  17. 17 26% の顧客が、サブスクリプションの 変更やキャンセル (自己管理) をオンラインで実行できない場合、 サブスクリプションの購入を 「思いとどまる」と回答している。 グローバルなサブスクリプション体験で特に改善が可能な項目 From:

    EC サイトにおける決済フローの現状 アジア太平洋地域 2022 年版 https://go.stripe.global/apac-state-of-checkouts-2022-ja
  18. 「一度解約したら終わり」じゃない関係づくりを目指す • 「解約 = 永遠にさようなら」とは限らない ◦ 体調・環境などによる、一時的な離脱のケースを考慮 • 解約からの復帰よりも、休会からの復帰のほうがハードルは低い ◦

    データの連続性、過去の契約情報の引き継ぎetc.. • 長く使ってもらうSaaSを目指すためにも、 「今使うのをやめること」を検討している人へのフォローを忘れずに 18 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会 #jp_stripes
  19. 今日のトピック • サブスクリプション契約をどう実装するか • サブスクリプションサービスは、 「契約してから」が本番 • Webhookを利用した「イベント駆動アーキテクチャ」で、 顧客との関係や契約内容などの「状態変化」を積極的にサポートしよう 19

    JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会 #jp_stripes
  20. 休会・解約以外にも、さまざまな状態変化がある • サブスクリプション = 長期的な顧客との関係構築 • さまざまなイベントや状態変化が発生する ◦ カードの更新忘れや銀行振込の入金忘れ ◦

    月額プランユーザーが年単位で契約を継続している ◦ 担当者の異動によるアカウント・契約情報の引き継ぎ ◦ 運用会社の変更による、契約内容の移譲・移管 • 「契約や顧客の状態」が変わったことの検知と、 それに対応するフローの自動化が社内の運用コストや顧客体験を改善する 20 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会 #jp_stripes
  21. 21 Webhookで、決済の「状態変化」を検知する JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on

    Rails勉強会 https://qiita.com/hideokamoto/items/76e7b92416fd9beeff66 システムでの状態変化を 別システムに通知する仕組み 非同期決済の「状態変化」を システムに通知する ・決済の成功 ・振り込み期限の超過 ・入金額の過不足 ・不正利用の疑いを検知 カード決済のみを考慮すると 後からの決済手段追加が hard
  22. Webhook活用例1: フリートライアルのフォローアップ • 「customer.subscription.trial_will_end」イベントを利用 ◦ 3日前または手動でトライアルを終了させた場合に発火 • サブスクリプションデータを確認し、手動終了でないことを確認 • メールやUIへの通知で、顧客にトライアル終了3日前をお知らせ

    ◦ 本契約に切り替わる場合: 課金が発生することの告知 ◦ 自動キャンセルの場合: リソースの削除や停止についての告知 • 本契約への切り替えなどのCTAを用意しよう 22 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会
  23. Webhook活用例2: 長期利用顧客のアップグレード提案 • シナリオに応じてイベントを変更 ◦ 次回請求の前に案内したい場合: invoice.upcoming ◦ 今回の請求で条件を満たしたら連絡: customer.subscription.updated

    ◦ etc.. • サブスクリプションの開始日と現在を比較 ◦ 休会期間を除外したい場合は、請求履歴をカウントする方法も • より長期のプランを取得 or その顧客用にプランを作成 • CRMツールやメールSaaSなどを利用して、顧客にコンタクト 23 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会
  24. 未払いや契約更新などの「状態」を監視する • サブスクリプションは、契約してからが本番 ◦ 競合他社への移行や解約、トライアルの途中解約や本契約切り替え ◦ 未払いが発生した場合の連絡やアカウントの停止・回復処理 ◦ 請求書・領収書の発行、カードの有効期限更新 •

    決済プロバイダやプラグインから送られる「状態変化」を監視する ◦ Webhookやメール通知を利用 ◦ 「契約・決済がXXしたらYYの処理を行う」 ◦ 運用開始後に判明するケースも多いので、拡張・柔軟性が大切 24 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会
  25. Webhookで、ユーザーとの関係を構築しよう • サブスクリプションは、「顧客との関係構築」がとても重要 • それぞれのWebhookイベントで、 「顧客がなにをしたか」「契約が今どうなっているか」を システムや人間が簡単に把握・対処できるようになる • ダッシュボードや、 AWSやGCPなどを使ったビジネス分析で、顧客への理解を深めよう

    25 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会
  26. One more thing 成功施策の「横展開」 26

  27. Stripe Appsで、自動化・効率化の「横展開」 • Webhookを利用した「仕組み化」に成功すると、 成功施策の横展開やパッケージ化が可能になることも • Stripe Appsで、 StripeとWebhookの処理システムとの連携や配布が簡単に ◦

    必要なもの ▪ Webhookを処理するAPIシステム(AWSやGCP・Vercelで構築) ▪ React + TypeScript + 専用UI FWでダッシュボードウィジェット 27 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会
  28. Stripe Appsの例: kintoneとStripeで顧客データ連携 28 JP_Stripes in 岡山 Vol.3 × 岡山Ruby,

    Ruby on Rails勉強会
  29. サブスクリプションシステムからDXをはじめよう • 決済系SaaSを活用して、サブスクリプションの組み込みを効率的に ◦ 効率化した分、 「契約し続けてもらうための施策」を決済方面からもトライしよう • Webhookを活用して、「顧客や契約の状態変化」へ システムや社員がスムーズな対応ができる環境を目指そう •

    成功した施策や企画を抽象化して、 Stripe Appsなどで新しいas a Service化を目指そう 29 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会