B/43 サービス立ち上げ時の技術選定について(サーバサイド編)
今回は自分たちが作っている B/43 というプロダクトの立ち上げ時においてどんな形で技術選定を行なってリリースに至ったかについて記載しようと思います。 Fintech サービスの裏側の話は意外と世に出ていないことが多く、また採用の機会において候補者の方に聞かれることも多いので改めてエントリーとしてまとめておこうと思います。
前置き
B/43 は事業の着想を経て準備をしつつ、何だかんだでリリースまでを含めると約2年掛かっています。現在はローンチして数ヶ月経過し、PMF しているかどうかをユーザーの動向を確認しつつ、さらなる機能追加や UI /UX の見直しを行なっています。
開発メンバーは創業者含めると8名で下記のような構成になっています。
- PM & デザイナー: 1名
- エンジニア: 7名
- インフラ: 1名
- サーバサイド: 5名
- クライアントサイド: 1名
メンバーの増加は段階的に進んでいったので、最初は3名から始まり徐々にメンバーが増えていった形になります。
提供しているサービスは現在は iOS アプリのみで、Android 版は絶賛開発中です。
リリース時点の求められる要件
事業サイドやプロダクトサイドとリリース時点の機能を整理して、必要になってきた開発要件としては大体下記のようなものでした。
Visa の決済ネットワークである VisaNet と接続して、カード決済ができること
- 決済電文をオンタイムで処理する必要があり、高いパフォーマンスが求められる
- 部分的に Windows 環境で動かす必要あり
物理プリペイドカードの発行 / 管理 ができること
- PCI DSS に準拠する必要があり、 インフラ / アプリ両方で高いセキュリティ要件を満たす必要あり
サービス内で法律 / ガイドラインに準拠した本人確認(eKYC)を実施できること
- 身分証画像を預かって、社内で管理 / 閲覧できること
- 本人画像と身分証画像の一致度を判定し、本人と特定できるような仕組みの構築
ユーザーのお金を預かって残高管理ができること
- シンプルに高い信用性が求められるのとトランザクションに気をつけて実装する必要あり
外部サービスと連携して入金 / 出金 ができること
- 入金 / 出金の方法ごとに外部ベンダー数社とのシステム連携が必要
その他
- パスワード無しで、安全な方法で会員登録 / ログインできること
- 会員登録時や決済時等、必要なタイミングでユーザーにプッシュ通知が送れること
- AML / ASF 対策として、会員情報の定期的なスクリーニングができること
- 各オペレーションに沿った操作が可能な社内用管理画面の作成
正直なところ、決済やカードにまつわる部分の開発は、仕様がクリアになるまで時間がかかったこともあり、開発の流れとしては、勘定系や会員登録周りなどから着手し始めて、その後決済やカード部分の開発を行うといった形で進めていくことになりました。
技術選定
各コンポーネント毎の技術を話す前にシステムの構成を説明しておきます。 現在は下記のように、モバイルアプリが使用する業務ロジックを扱う API 群と PCI DSS に準拠し、VisaNetとの繋ぎ込みやカード情報の管理を司るシステムと大きく2つのコンポーネントに分かれています。
※ PCI DSS (クレジットカード業界の国際セキュリティ基準。カードを発行するために必要で審査機関による認定を受ける必要有り)
当初は全てのサービスが単一のリポジトリに収まるモノリシックなシステムを想定していましたが、仕様の全体像や PCI DSS に準拠するための制約が明らかになるにつれて、設計を見直してコンポーネントを大きく2つに分けました。
PCI DSS への準拠対象を全てにすると、今後の開発スピードに著しく関わってくるので、そこだけは避けて限定的にしつつ、決済やカード発行という境界が分かりやすく分離できそうな箇所を切り出した形です。
決済API / カード発行基盤
開発言語は Golang を採用しています。以下のような点が採用したポイントでした。
- Windows 環境向けにクロスコンパイルができる
- VisaNet の電文仕様や、カード発行における印刷会社との連携データフォーマットは事前にステークホルダーと詳細を詰めて開発を進めたため、連携項目ごとにデータを定義でき型安全な開発ができる
- 以前開発していた、Golang 製 API でパフォーマンス面での信頼性もあったので採用もしやすかった
シンプルに net/http を使って API サーバを構築しており、ルーティング部分に Echo を使っています。
カード発行基盤はカード情報を操作する API と複数のバッチ群で構成されています。 バッチは urfave/cli を使って、CLI を使って呼び出せる様になっており、カード発行用のコマンド、決済調査用のコマンドなど用途に分けて実装されています。
モバイル向け API
開発言語は Ruby を採用しています。 業務ロジックを扱う API が集約されており、最も機能追加、修正の機会が多いのでライブラリが豊富で手慣れた開発スピードの出る言語、フレームワーク(Ruby on Rails)で開発しています。
認証や入出金、タイムラインなどの各情報の閲覧 / 更新を司る API 群が Rails の API モードを使って実装されています。
認証
SMS認証部分に Vonage API (旧Nexmo)を使っています。 Vonage の優れている所は gem でシュッと導入できる所もそうですが、課金体系が認証時のみなので、ユーザーが実際に SMS 認証を完了するまでは SMS を何度送っても料金がかからない所かなと思います。
また、日本法人のサポートも手厚く、依頼すればきちんと国内ルートでの配信設定をお願いできたり、送信元の電話番号も管理画面経由でサクッと入手できるのも良い所です。
本人確認(eKYC)
B/43 の eKYC はユーザーに身分証画像やライブネスチェック用の本人画像を複数枚送ってもらい、画像の顔検出や身分証画像との一致、ドキュメントと入力情報の一致などいくつかのチェックポイントを設けて確認を行なっています。
目視確認もオペレーターが行っていますが、画像の顔判定や身分証画像との一致は AWS Rekognition を使い、判定したスコアリングを評価の参考にするなど、サービスをうまく使ってオペレーションコストを減らすようにしています。
プッシュ通知
プッシュ通知は専用の通知を送る API として切り出して実装されています。 各API サーバやバッチサーバでプッシュ通知を送らずにサービスとして切り出したのは以下の理由からです。
- 複数のサービスからプッシュ通知を送りたい
- 特定の処理後(決済後、会員登録後、カード発行後、etc...)任意の箇所から呼ばることが想定される
- 一斉多量配信など、決まった日時に多量の通知を送りたいシーンがある
- 通知の配信タイミングをコントロールしたい
以前もプッシュ通知を大量に送るサービスを運用していたのですが、バッチサーバ単体で動かすとネットワークレイテンシの問題で配信に時間がかかる、また一斉配信後にユーザーからの大量アクセスがあり、DBが高負荷になるなどの経験をしてきたので、プッシュAPI自体は別サービスとして切り出しつつメッセージキューとジョブワーカーを内包したHTTPサーバとして実装されています。
実装としてはシンプルで決済APIと同等の構成で通知処理には firebase を、キューイングの仕組みとして goworker を利用して実装されています。
通知のリクエストを受け取ったプッシュAPIは一度配信用データとして、データをDBに保存、非同期キューにエンキューし、即座に結果をクライアントに返します。 その後、goworker がデキューし、プッシュを配信、結果はクライアント側に webhook として通知されるようになっています。
まとめ
B / 43 で行ってきた主だった技術選定について、紹介しました。 改めて見てみると、割と手堅くチームの使い慣れた技術で技術選定をしてきたように思います。
管理画面や AML / ASF、バッチ処理のタスクスケジュールなど紹介しきれていない部分があるので、各コンポーネント毎にどういった技術を採用して開発を進めているかは、また別のエントリーにして情報発信していきたいと思います。
簡単な技術スタックは、それぞれの求人職種欄にのせているので、参考にしてください。
このエントリーが何かの役に立つと幸いです。