エンジニア、PM、デザイナーの副業・転職サービス「Offers」、開発組織の生産性を最大化する「Offers MGR」
我々が提供するサービスは、1つ目がエンジニア、PM、デザイナーの副業・転職サービス「Offers(オファーズ)」で、もう1つが開発組織のパフォーマンスの可視化とインサイトの提供などを行っている「Offers MGR(オファーズ マネージャー)」です。
Offersは約4年前、Offers MGRは約1年前にリリースされ、いずれも決済機能を導入しました。2つのプロダクトの開発を経ての全体像や決済サービスとの関わり方を共有させていただきます。
アーキテクチャーに関しては、基本的にバックエンドはOffers、Offers MGR共にRuby on Railsで、フロントエンドはTypeScriptを使用して、Offers側がVue.js、Offers MGR側はNext.jsを使用してます。これらの構成で作られたサービスに対して、Stripeを利用して決済サービスを組み込んで提供しています。
「Offers」では、サービス利用開始時のフォームに外部決済サービス「Stripe」を組み込み決済処理を実行
まずOffersでStripeを使って何をしているのかというところですが、 新規でご契約いただく際に最初にStripeが出てきます。
流れ的にはまず商談がSalesforceで作成されて、それをOffers側で取り込んでクラウドサインを作成します。その契約データを同時に作成して、クラウドサインが締結された後に送信した利用開始フォームを送信いただくことで利用開始、という流れです。
実際に利用開始いただくフォームの中に、サービスの利用にあたって必要な企業名などの情報に加えて決済情報を入力してもらう形を取っていて、そこでStripeの決済情報を入力するフォームのコンポーネントをそのまま利用できるElementを使用して、自社で実装している実際のUIにあるサービスのフォーム内に決済フォームを組み込んで、そこからStripeにデータを作成する、ということをやっております。
Salesforce < > Offers < > Strip 間でのデータ連携
実際に企業データや契約データ、後はSalesforceに商談データを持っていて、実際にやり取りが行われているというか、相互に同期が行われているのはプランデータです。
サービス側にプランマスターを持っていて、それでSalesforceやStripeに同期します。請求データについて、サブスクリプションの作成・更新・削除はAPIで行って、あとは決済ステータスなど、Stripe側で変更があったものをサービス側で受け取って、そのデータを保存して使うということをやっておりました。
「Stripe」を導入することで、開発コストをかけずにサブスクリプション決済への対応が可能に
上記のような構成でStripeを使って、開発コストをかけずに6ヶ月・12ヶ月単位など複数か月のサブスクリプションの決済が簡単に導入できました。
あとは、企業様向けにサービスを提供してお金をいただいてる側面もあって、クレジットカード払いと請求書払いの併用についても柔軟に対応ができました。
ビジネス要件の変化に対して柔軟に対応できるような構成が作れていなかった
逆に、 変化するビジネス要件に即座に柔軟に対応できる構成ではなかったです。
新しい料金プランや新たな期間プラン(6か月、12か月のプランに5カ月プランを追加するなど)を導入するタイミングで、すぐに変更して提供できる状態にはなっていませんでした。
これは、ビジネスのインパクト上でも軽視できません。特に成長するプロダクトを0から作っていると、爆速で色んな機能開発が行われていて、半年前の商品の状態と今の商品の状態は変わっていますし、提供するサービスの質や量も変わりますので、料金変更も必然だと思っております。
あとは、料金自体もどれが最適かというのは企業も探っていますので、気軽に思いついた時に簡単に検証できるような柔軟な構成を、開発側で制限をつけない状態で皆さんに提供できる状態にはできていませんでした。
データ同期に関してこのような状態になったのは、基本的にサービス側にコードを書きすぎたことが原因です。このプランバージョンのこの商品はこの機能を解放するとか、そういった処理が無数にいろんなところに存在していました。
1つ商品を追加したら、ここもチェックしなきゃというのは、(ユニットテストでカバーしてる範囲もありましたが)いろんなところに影響を与えるような相互に依存し合っていて良くない状態でした。
1個プランを追加するにも気軽に行えず、特定のドメイン知識を持つエンジニアしか対応できずに時間がかかるという状況でしたね。
あとはプランデータのやり取りもAPI・Webhookなどで双方向に多くなっていて、そちらの通信に関しても複雑で、結果的に気軽に商品を追加して何かを試そうという構成からは若干遠くなってしまいました。
サービス側に決済に関するコードを書く設計にすべきではない
ここまで運用してきて、とにかく薄く作るべきだと学びました。
薄く作るというのは、サービス側に決済に関するコードを書かないで、Stripeが提供してるものを使えるだけ使うように意識して設計することです。これは設計が破綻しないようにサービスを運営していくにあたって必要なことだと実感しました。
具体的には、決済ステータスや決済情報に基づく認可は、サービス側で行ってもStripeさんに持たせて、Stripeさんが提供してるものがある場合はできるだけそちらを使うようにします。サービス側でいろんな処理があって簡単には変更できないという状態は避けられる形です。
「Offers MGR」では、StripeのCheckoutを活用
Offersでの課題を踏まえた上で2つ目のサービス、Offers MGRはStripeを使って何をしているのかを紹介します。
基本的にはシンプルなフローで、Hubspotが今回出てきますが、商談を取り込んでフォームを送信するところまでは全く一緒です。Offersでは、フォーム内にStripeのElementを使って組み込みましたが、今回はStripeのCheckoutを使用しています。
登録フォームに入力する段階で企業情報などの基本情報を入れた後に、決済情報の入力段階でStripeのCheckoutが提供する決済ページに遷移して、そこからサブクリプションの作成や顧客情報の作成を行い、別ページに飛ばして、そこで決済情報を入れるという流れです。
Checkoutは非常に便利で、パラメーター付きで遷移先のurlを発行できまして、そのurlに遷移すると、あらかじめ情報が入った状態で決済のあとは情報を入れていくだけでStripeに情報が作られるという仕組みになっています。
あとはStripeとの接点ですが、これもStripeが提供しているものは全部使う方針です。支払い方法の変更でもStripeのCheckoutを使用したり、トライアルから有料プランへ切り替えていただく際にクレジットカード情報を提供いただく必要がありますが、そこでStripeのElementを使用しています。
Stripeのカスタマーポータルでクレジットカードや請求先情報の変更、今までの支払履歴の確認を行うことで、自分たちでフロントエンドからバックエンドまで実装・・保守をせずに、Stripeさんの提供機能を使って運用コスト0で実装やリリースができます。これによって他の機能開発に集中できる状態をより作れています。
データ同期に関しても非常に薄く作り、 基本的には決済ステータスを受け取ってサービス内で管理している状態です。
Offersの運用から学んで変わった部分は、とにかく薄く作ろうという意識です。
むやみにAPIを叩かない。APIを叩こうとしてる時は、まずStripeさんが提供するものでそれを実装できないかと考えて、形にして提供していくことが初期は大事だと思っております。
「Offers MGR」ではむやみにAPIを叩かないようにしたことで、スムーズな運用が可能になった
うまく行った点としては、とにかく早くクレジットカード決済とトライアルが導入できたことです。
StripeのCheckoutを使用しているので、パラメーターを1つ追加するだけでトライアル用の決済情報の入力に飛ばすこともできますし、そこからトライアル用のサブスクリプションが作成されて始められるところも、Stripeさんが用意しているフローに乗るだけで実装ができたので、かなり低コストで実装してお客さんに提供できました。
プラン変更対応にもコストをかけずに今のところ対応ができています。
Offers MGR単体では、今のところうまくいかなかった点は無いと思います。用意されているものに乗っかって使えるものを全部使った結果、今のところ非常にスムーズに運用できています。
困っているのが、Offersとの共通の決済基盤を作りたかった、今もなお作りたいというところです。もう少し詳細に言いますと、一つの共通の顧客のIDで複数サービスの商品の管理、支払い手段の編集や確認ができる状態を作りたいと思っております。
Stripeでは、1つ目のサービスのアカウントがある状態で2つ目のアカウントを作るときの選択肢が2つあります。
1つ目は、現在運用中のアカウントに新しく商品を追加してそれを使うというもので、もう1つは完全別々のアカウントを作るというパターンです。 最初は1つのサービスに普通の商品を追加して管理していくことで、共通の顧客idで管理できる状態を作ろうとしていましたが、結局しなかったです。
なぜしなかったかというと、最初に作ったサービスでStripeとサービスが密に結合している部分があったので、サービスの商品をいきなり追加した時に、お客様に過剰の請求を行ったり、存在しないはずの請求を行うリスクを考えると、この選択肢は取れなかったです。
今後はプロダクト共通の決済基盤の提供を行っていきたい
先ほど挙げたうまくいかなかったことを改善する形で、シンプルで便利な決済基盤の提供をしていきたいと思っております。
同じ会社の別のプロダクトをそれぞれ契約管理するより、1つのサービスを契約して管理できる方が圧倒的に便利だと思うので、そういった構造を作ることもこれからやっていきます。