こんにちは。ソウゾウのSoftware Engineerの@napoliです。連載:メルカリShops 開発の裏側 Vol.2の3日目を担当させていただきます。
メルカリShopsはメルペイと連携し、メルペイによる決済システムを提供しています。ここではメルカリShopsはどのようにメルペイのシステムと連携をしているのか、その一部をご紹介させていただきます。
メルカリShopsとメルペイ
メルカリShopsとメルペイは同じメルカリグループに属していますが、両者のシステムは完全に独立しています。これはメルカリグループとソウゾウのValueでもある「Go Bold」「Move Fast」の思想のもと、メルカリShops開発を急速に推進していくための判断でした。
メルカリShopsのシステム全体像に興味がある方は前回の連載の「メルカリShops の技術スタックと、その選定理由」が参考になるかと思います。
完全に独立した、メルペイ側から見ると外部のシステムとどうやってセキュアかつスケーラブルに連携していくかは、開発当時の大きな課題でした。
メルペイ加盟店申込とパートナーID
システム間で通信を行う前に、ショップ運営者様にメルペイの決済機能を利用して頂くには各ショップ運営者様に対して「メルペイパートナーID(以下、パートナーID)」を発行する必要があります。これはメルカリShopsではなくメルペイが発行します。通常、オフライン店舗などの事業者様がメルペイでの決済を行う場合、「メルペイ加盟店申込」という申請を行う必要があります。ある事業者様がこの申し込みを行うとメルペイによる審査が行われ、審査が承認されればその事業者様に対して「パートナーID」が発行されます。このパートナーIDによってメルペイのシステムは事業者様を識別でき、決済機能を提供することが出来るようになります。
メルカリShopsではこの「メルペイ加盟店申込」を代理しています。あるショップ運営者様がメルカリShopsへ「ショップ開設申し込み」を行って頂くと、自動的に「メルペイ加盟店審査申し込み」が行われるようになっています。その後メルペイよる審査が行われ、審査が承認されればメルペイから「パートナーID」が発行されます。
そしてここで「パートナーID」をショップ運営者様に直接お渡しするのではなく、メルカリShopsが(シークレット情報とともに)そのパートナーIDを保持、管理します。メルカリShopsでの決済時にはメルカリShopsのシステムがメルペイ決済に必要なデータを代わりにやりとりするため、ショップ運営者様は「ショップ開設申し込み」以外の手続きなく、簡単にメルペイの決済を利用することが出来るようになっています。
通常、ECサイトを独自で構築する際はメルペイなど各決済事業者が提供するAPIの仕様に沿って開発を行い、アカウントの管理などを自前で行う必要がありますが、メルカリShopsにはそういった煩わしさがありません。
GatewayとAccess Token
では具体的にメルペイはどうやって外部のシステムであるメルカリShopsと通信を行っているのでしょうか。これは主に「メルペイGateway(以下Gateway)」と呼ばれるシステムとAccess Tokenと呼ばれるトークンによって実現されています。
Access Token
メルペイ(メルカリ含む)が外部のシステム(Client)を認証するためのトークンです。メルカリShopsではOAuth 2.0のClient Credentials Flowを用いてトークンを発行します。Client Credentialsを用いてメルカリShopsが各ショップごとにAccess Tokenを発行し、メルペイの機能を利用する際はこのAccess Tokenをリクエストに付与します。メルペイはAccess Tokenに紐付けられた情報から、パートナーIDを識別することが出来るようになります。
より具体的には、GatewayがAccess Tokenを受け取ると、メルペイのシステム内にある認証サーバにAccess Tokenを渡します。認証サーバはAccess Tokenの検証を行い、正しいトークンであればPrivate Access Tokenと呼ばれるトークンを発行します。そしてこのトークンに前述した「パートナーID」情報が含まれています。
Gatewayとアクセスコントロール
Access TokenによりメルペイはパートナーIDを識別することが出来るようになりますが、Access Tokenが付与された外部からのリクエストをすべて許可するわけではありません。
メルペイ全体の機能は多岐にわたりますが、メルカリShopsにおいて利用するのは決済を中心とした一部の機能(API)だけなので、このGatewayによってメルカリShopsが利用できる機能が制限されています。
当然、メルペイのシステム内には非常に重要なデータや、外部からアクセスされるべきでないAPIがたくさんあります。メルカリShopsはメルカリグループ内のプロダクトとはいえ、システム的には独立しているため、Gatewayでのアクセス制限によって安全性を担保しています。
ただし、このGatewayによってアクセスを宣言的に制限するという方式は当時グループ内でもかなり議論がありました。メルカリグループとしては外部サービスとの連携を今後も推進していきたいビジョンもあるため、もっと汎用的かつスケールする仕組みを導入すべきという意見も多くあったのですが、メルカリShopsをMove Fastに立ち上げしていくことも重要だったので、比較的シンプルな仕組みによってアクセス制限を実現することになりました。このあたりはメルカリのプラットフォーム化を推進するにあたっての課題のひとつだと感じます。
Client Secret
では具体的にAccess Tokenをショップ毎にどうやって発行するのでしょうか。
Access Token自体は先に説明した通りClient Credentials Flowにより取得するのですが、そのためにはショップごとのClient IDとClient Secretが必要になります。
当然ですがメルカリShopsのショップは常に増えていきますので、あらかじめすべてのClient IDとClient Secretを用意しておくのは現実的ではありません。
そこでメルペイ側に、OpenID Connect Dynamic Client Registrationの仕組みを実装し、メルカリShopsがそれを利用することで、動的にOIDC Client(つまりClient IDとClient Secret)を生成しています。
Dynamic Client RegistrationとMaster Client
Dynamic Client Registrationの仕組みにより、メルカリShopsのショップが新たに登録されるたびにClient IDとClient Secretを動的に生成し、管理できるようになりました。
しかしこのDynamic Client Registrationの機能(API)はメルペイから見るとあくまでも外部のシステムからCallされることになります。Dynamic Client Registrationで発行できるClient IDとClient Secretは非常に強い権限を持っているため確実にメルカリShopsのシステムだけが利用できるように制限をする必要があります。
Gatewayとアクセスコントロールの説明でGatewayがアクセスできる機能は制限されていると説明しましたが、Dynamic Client RegistrationもメルカリShops側から(つまりメルペイから見ると外部から)Callする必要があるため、Gatewayはリクエスト自体は許可する必要があります。しかしメルカリShopsからのリクエストであればすべて許可するべきではなく、限られた権限を持つリクエストのみ許可するべきです。
そこでメルカリShopsに対して「Master Client」と呼ばれる特別な権限を持つClientをメルペイが発行し、予めメルカリShopsのシステムにセットしています。Dynamic Client Registrationはこの特別な権限を持つClientからのリクエストのみ受け付けるようになっています。先に説明したショップに対して発行したAccess TokenではDynamic Client Registrationを実行することはできません。
当然、この「Master Client」と呼ばれるClientも非常に強い権限を持つことになるので、そのClient IDとClient SecretはメルカリShopsの内部で厳重に管理されています。
決済リクエスト
メルカリShopsからメルペイへの決済リクエストは典型的な通信の例になります。以上を踏まえ、決済リクエスト時にメルカリShopsとメルペイがどういった流れで通信を行っているかを図にすると、大まかに以下のような形になります。
おわりに
独立したシステムであるメルカリShopsがどのようにメルペイと連携を行っているか、その一部をお届けしました。独立したシステムではあるけれど、メルカリShopsのシステムにあらかじめ「Master Client」をセットしておくなど、同じグループ企業であるメリットも活かしつつ連携しています。
組織としては同じであるけれどもスケーラビリティを持たせるために完全に独立したシステムを構築したい、というケースはあるかと思います。そういった際のシステム間連携の一例として参考になれば幸いです。
謝辞
メルカリShopsを完全に独立したシステムで構築するというGo Boldな意思決定をしながらも、メルペイを利用したシームレスな決済機能の提供は必須の要件でした。
決済システムという機密性の非常に高いシステムと、セキュア、かつ短い期間で外部から連携するというのはなかなかチャレンジングなミッションではありました。当初は不安もありましたが、メンバー皆さんの協力のおかげですごいスピードで物事が決まっていきました。特にメルペイのエンジニアの方々は会社が違うにも関わらず非常に協力的かつ積極的にサポートして頂いて、当時とても感動した記憶があります。協力してくださったメンバー全員が「Go Bold」「All for One」「Be a Pro」、さらに「Move Fast」と三拍子どころか四拍子揃った貢献のおかげで、あれだけ急速にメルカリShopsを立ち上げられたのだと思っていますし、まさにメルカリグループのValueをすべて体現したプロジェクトだったなと感じています。この場を借りてみなさんに改めてお礼をさせてもらえればと思います。
一緒に作っていくメンバーを大募集中
メルカリShops(ソウゾウ)ではメンバーを大募集中です。
ソウゾウはまだ設立1年の若い組織です。スタートアップとしての熱量がありつつ、メルカリグループとしてのしっかりした基盤の上で心置きなく思いっきり走れる環境だと思います。エンジニアとして良い意味で高いレベルも求められるので、成長の実感もきっとたくさん得られると思います。
そんなメルカリShopsの開発やソウゾウに少しでも興味を持たれた方がいればぜひこちらも覗いてみてください。
ソウゾウではメンバーを大募集中です。ソウゾウに興味を持った方がいればぜひご応募お待ちしています。各職種についての詳細は以下のページをご覧ください。
- Software Engineer
- Software Engineer, Site Reliability
- Software Engineer, Machine Learning
- Software Engineer, QA Test
- Software Engineer (Internship) – Mercari Group (※新卒採用に応募するにはまずインターンへの参加をお願いしています。)
またカジュアルに話だけ聞いてみたい、といった方も大歓迎です。こちらの申し込みフォームよりぜひご連絡ください!