Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

岡本 秀高 ( @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

Slide 4

Slide 4 text

今日のトピック ● サブスクリプション契約をどう実装するか ● サブスクリプションサービスは、 「契約してから」が本番 ● Webhookを利用した「イベント駆動アーキテクチャ」で、 顧客との関係や契約内容などの「状態変化」を積極的にサポートしよう 4 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会 #jp_stripes

Slide 5

Slide 5 text

サブスクリプション契約は、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'}, ], })

Slide 6

Slide 6 text

https://github.com/pay-rails/pay 6 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会

Slide 7

Slide 7 text

サブスクリプション契約は、どこで管理すべきか? ● 基本的には「SaaSに任せる」方が、開発・運用コストが低い ○ 契約更新や請求などの、スケジュールジョブ ○ 未払いや超過振込などの、イレギュラーイベントへの対応 ○ 配送・請求先住所などの個人情報管理など ● マーケットプレイスSaaSや「EC構築システム」などでは、自社管理も ○ 例: WooCommerce + WooCommerce Subscription ○ 「出店者が、決済プロバイダを選びたい」ケース ○ 決済プロバイダ毎のサブスクAPIをラップするのではなく、 自前で管理して都度都度の決済処理だけ移譲する 7 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会 #jp_stripes

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

契約情報とユーザー情報の紐付け方 ● 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

Slide 10

Slide 10 text

サブスクリプションを組み込む方法 ● 基本的には、利用する決済プロバイダやSaaSのAPIを使おう ○ 決済プロバイダに依存したくない場合は、 自前での請求システム構築も検討する必要がある ● システムのユーザー情報と、Stripeなどの顧客・契約情報を紐づけよう ○ 「システムの外」で契約が変わることもあるため、 Webhookでのsyncを推奨 ● 決済プロバイダ・SaaSの便利機能で開発工数を圧縮しよう 10 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会 #jp_stripes

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

サブスクリプションは、「契約してからが本番」 ● サブスクリプションは、「契約し続けてもらう」必要がある ○ 使わないサブスクサービスは、解約される ■ 競合他社への乗り換え: 「もっと安い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

Slide 13

Slide 13 text

13 令和3年に改正された特定商取引法への対応 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会 令和3年特定商取引法・預託法の改正について https://www.caa.go.jp/policies/policy/consumer_transaction/amendment/2021/ 最終確認画面に 右の6情報を表示する ・トライアル終了後の請求額 ・期間限定商品の販売期間 ・解約方法や医薬品 誤認を与える表示がある場合 申込の撤回が可能になる事も

Slide 14

Slide 14 text

完全に解約したいのか、「今は使いたくない」なのか ● 解約ユーザーには、「今は必要ない(また使うかも)」ケースもある ○ 長期出張が決まったので、ジムや食品の定期注文を解約したい ○ 今期は見たい番組・作品が少ないので、解約したい ○ 花粉症がひどいので、春先だけは利用できない ● 「休会」のオプションで、ユーザーが帰ってきやすい環境を作る ○ 解約 -> 入会はステップが多い ■ カード情報や個人情報などの再入力が必要 ○ 休会で、「請求」と「システムの利用」だけを停止する 14 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会 #jp_stripes

Slide 15

Slide 15 text

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' } }, )

Slide 16

Slide 16 text

Webhookイベントで、休会開始・終了を検知 ● subscription更新のイベントを Webhook APIで受信 ● 休会開始と終了を検知し、 システム側のDB情報を更新 ● 「問い合わせベースでの休会」など APIを通さないケースに備える ● 休会ユーザーは、 「カスタマーポータル」に飛ばす手も 16 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会 https://qiita.com/hideokamoto/items /1a5f8549d862f7fc9d4b

Slide 17

Slide 17 text

17 26% の顧客が、サブスクリプションの 変更やキャンセル (自己管理) をオンラインで実行できない場合、 サブスクリプションの購入を 「思いとどまる」と回答している。 グローバルなサブスクリプション体験で特に改善が可能な項目 From: EC サイトにおける決済フローの現状 アジア太平洋地域 2022 年版 https://go.stripe.global/apac-state-of-checkouts-2022-ja

Slide 18

Slide 18 text

「一度解約したら終わり」じゃない関係づくりを目指す ● 「解約 = 永遠にさようなら」とは限らない ○ 体調・環境などによる、一時的な離脱のケースを考慮 ● 解約からの復帰よりも、休会からの復帰のほうがハードルは低い ○ データの連続性、過去の契約情報の引き継ぎetc.. ● 長く使ってもらうSaaSを目指すためにも、 「今使うのをやめること」を検討している人へのフォローを忘れずに 18 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会 #jp_stripes

Slide 19

Slide 19 text

今日のトピック ● サブスクリプション契約をどう実装するか ● サブスクリプションサービスは、 「契約してから」が本番 ● Webhookを利用した「イベント駆動アーキテクチャ」で、 顧客との関係や契約内容などの「状態変化」を積極的にサポートしよう 19 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会 #jp_stripes

Slide 20

Slide 20 text

休会・解約以外にも、さまざまな状態変化がある ● サブスクリプション = 長期的な顧客との関係構築 ● さまざまなイベントや状態変化が発生する ○ カードの更新忘れや銀行振込の入金忘れ ○ 月額プランユーザーが年単位で契約を継続している ○ 担当者の異動によるアカウント・契約情報の引き継ぎ ○ 運用会社の変更による、契約内容の移譲・移管 ● 「契約や顧客の状態」が変わったことの検知と、 それに対応するフローの自動化が社内の運用コストや顧客体験を改善する 20 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会 #jp_stripes

Slide 21

Slide 21 text

21 Webhookで、決済の「状態変化」を検知する JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会 https://qiita.com/hideokamoto/items/76e7b92416fd9beeff66 システムでの状態変化を 別システムに通知する仕組み 非同期決済の「状態変化」を システムに通知する ・決済の成功 ・振り込み期限の超過 ・入金額の過不足 ・不正利用の疑いを検知 カード決済のみを考慮すると 後からの決済手段追加が hard

Slide 22

Slide 22 text

Webhook活用例1: フリートライアルのフォローアップ ● 「customer.subscription.trial_will_end」イベントを利用 ○ 3日前または手動でトライアルを終了させた場合に発火 ● サブスクリプションデータを確認し、手動終了でないことを確認 ● メールやUIへの通知で、顧客にトライアル終了3日前をお知らせ ○ 本契約に切り替わる場合: 課金が発生することの告知 ○ 自動キャンセルの場合: リソースの削除や停止についての告知 ● 本契約への切り替えなどのCTAを用意しよう 22 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会

Slide 23

Slide 23 text

Webhook活用例2: 長期利用顧客のアップグレード提案 ● シナリオに応じてイベントを変更 ○ 次回請求の前に案内したい場合: invoice.upcoming ○ 今回の請求で条件を満たしたら連絡: customer.subscription.updated ○ etc.. ● サブスクリプションの開始日と現在を比較 ○ 休会期間を除外したい場合は、請求履歴をカウントする方法も ● より長期のプランを取得 or その顧客用にプランを作成 ● CRMツールやメールSaaSなどを利用して、顧客にコンタクト 23 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会

Slide 24

Slide 24 text

未払いや契約更新などの「状態」を監視する ● サブスクリプションは、契約してからが本番 ○ 競合他社への移行や解約、トライアルの途中解約や本契約切り替え ○ 未払いが発生した場合の連絡やアカウントの停止・回復処理 ○ 請求書・領収書の発行、カードの有効期限更新 ● 決済プロバイダやプラグインから送られる「状態変化」を監視する ○ Webhookやメール通知を利用 ○ 「契約・決済がXXしたらYYの処理を行う」 ○ 運用開始後に判明するケースも多いので、拡張・柔軟性が大切 24 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会

Slide 25

Slide 25 text

Webhookで、ユーザーとの関係を構築しよう ● サブスクリプションは、「顧客との関係構築」がとても重要 ● それぞれのWebhookイベントで、 「顧客がなにをしたか」「契約が今どうなっているか」を システムや人間が簡単に把握・対処できるようになる ● ダッシュボードや、 AWSやGCPなどを使ったビジネス分析で、顧客への理解を深めよう 25 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会

Slide 26

Slide 26 text

One more thing 成功施策の「横展開」 26

Slide 27

Slide 27 text

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勉強会

Slide 28

Slide 28 text

Stripe Appsの例: kintoneとStripeで顧客データ連携 28 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会

Slide 29

Slide 29 text

サブスクリプションシステムからDXをはじめよう ● 決済系SaaSを活用して、サブスクリプションの組み込みを効率的に ○ 効率化した分、 「契約し続けてもらうための施策」を決済方面からもトライしよう ● Webhookを活用して、「顧客や契約の状態変化」へ システムや社員がスムーズな対応ができる環境を目指そう ● 成功した施策や企画を抽象化して、 Stripe Appsなどで新しいas a Service化を目指そう 29 JP_Stripes in 岡山 Vol.3 × 岡山Ruby, Ruby on Rails勉強会