2024.10.01
自社の社内情報を未来の“ゴミ”にしないための備え 「情報量が多すぎる」時代がもたらす課題とは?
静的MPM決済を支える技術(全1記事)
提供:PayPay株式会社
リンクをコピー
記事をブックマーク
susho氏:こんばんは。「静的MPM決済を支える技術」ということでsushoが発表させていただきます。
最初に自己紹介です。
社内ではsushoと呼ばれているので、ここでもそうさせていただいております。Twitterは@susho0220でやっています。バックエンドエンジニアで、メルペイのCode Paymentチームに所属しています。Go歴は4年ぐらいです。僕も2018年までYahoo! JAPANに在籍していまして、そこでオブジェクトストレージ「Dragon」の開発に従事していました。
今日のアジェンダです。
最初に「静的MPMとは」というお話をさせていただいて、そのあとは静的MPMを使ったマイクロサービスアーキテクチャについてお話します。最後は、マイクロサービスアーキテクチャで実装する上での不整合対策についてお話できればと思います。
まず「静的MPMとは」です。
静的MPMとは、店舗で紙などに印刷された固定のQRコードを提示して、それをお客様が読み込んで決済するというものです。メリットは、店舗側はQRコードを配置するだけで導入可能なので、CPMなどの他のQRコード決済の仕組みと違い、POSなどが不要なので導入コストが非常に安いです。
考えれるデメリットとしては、QRコードが改ざんされる恐れがあります。これは昔の話ですが、改ざん防止のために固定のQRコードをガラスに貼ったり、特殊なステッカーに印刷したり、決済時に強制的に音を出させたり、結果を店舗のメールアドレスに通知することで改ざん防止しています。
6月27日に「メルペイ」のお客さま読み取り式コード決済機能をリリースしました(プレスリリース)。現在順次利用店舗を拡大していっています。
メルペイの静的MPMの仕様ですが、JCBやVisa、Mastercardなどの国際ブランド6社からなる技術団体「EMVCo」というものがあり、そこで策定された共通規格「EMV」を採用しています。
また、QRコードのエンコードとデコードでは自社で開発したOSSのライブラリ「go-emv-code」というものを使っています。
続いて、この静的MPMのマイクロサービスアーキテクチャについて説明したいと思います。概要になってしまいますが、順を追って説明をしていきたいと思います。
メルペイでは各マイクロサービスがGCPのGKE上に構成されています。
これは静的MPMのざっくりしたシーケンスですが、まずはGoogle Cloud Load BalancerからMerpay GatewayというAPIゲートウェイにHTTP+JSONやHTTP+ProtocolBuffersのリクエストがきて、そこで内部通信に使っているgRPCへのプロトコル変換やルーティング、認証を行っています。
この認証にはAuthority Serviceというマイクロサービスがあり、ここで認証トークンを生成しています。この認証トークンはすべてのマイクロサービスが検証をする必要があり、各マイクロサービスはAuthority Serviceとバックグラウンドで通信をして、トークンの鍵を取得しています。
その他の処理が行われたあと、Merpay APIにリクエストが飛んできます。ここはいわゆるBFFの機能を担っています。
そしてMerpay APIからStaticMPM Serviceという、今回主に実装したマイクロサービスにリクエストが飛んできます。ここではまずQRコードの解釈を行います。QRコードの中に入っている店舗情報のキーになるIDを取ってきて、Partner Serviceから店舗情報を取得し、実際の決済処理のために決済共通の処理を行うTransaction Serviceにリクエストを投げ、決済基盤であるPayment Serviceにリクエストが投げられます。
これが成功したら、通知処理を担うNotification Serviceにリクエストを飛ばして通知を行います。だいぶざっくりですが、こんな感じになっています。
続いて決済シーケンスについて、もう少し踏み込んだ部分を説明したいと思います。最初のメルカリアプリ内でQRコードを読み取り、Mercari AppからMerpay APIにQRコードと一緒にセッション生成リクエストが投げられます。
そこからStaticMPM Serviceにリクエストがきて、StaticMPM ServiceがQRコードの解釈・店舗情報の取得・セッショントークンの生成を行います。セッショントークンについては後述します。
そこから店舗情報とセッショントークンを返し、Mercari App内で購入画面が表示され、金額入力、購入ボタンを押し、また決済リクエストが飛んできて、StaticMPM Serviceではセッショントークンの検証と決済処理、通知処理を行い、お客様のアプリに完了画面が表示されるというシーケンスになっています。
StaticMPM Serviceについてどんな機能があるのかを説明します。
静的MPM決済のドメインに関するマイクロサービスでQRコード解釈では、go-emv-codeを使っています。アプリでQRコードを解釈することも考えたんですが、今後のさまざまなQRコードの仕様に対応する必要があり、拡張性を高くしたかったのでバックエンド側で処理をしています。
ここで出てきたセッショントークンなんですが、アプリでQRコードを読み取ったあとに一定期間のみ決済可能にする仕組みです。これは何のために実装したかというと、お客様がQRコードを読み取ってそのあと画面を一定期間放置して、そのあとに間違って購入ボタンを押してしまった場合にも決済ができてしまうので、一定期間放置されたセッションは弾くような実装をしています。
決済処理ですが、いろいろなマイクロサービスでやり取りをして、静的MPM決済のドメインに沿った各処理を実行しています。ここの決済処理の設計をミスすると容易に不整合が発生してしまうので難しいです。先月、弊社のエンジニアが「マイクロサービスにおける決済トランザクション管理」というブログを出していたので、読んでいない人は読んでみてください。
不整合対策が難しいということがあったので、それについてざっくりと説明したいと思います。不整合対策をする上で、僕らが考えているキーポイントです。
まず冪等性、Write repair、Asynchronous repairが大事だと考えています。冪等性に関しては、クライアントは同じリクエストを繰り返し呼ぶことができ、かつ同じレスポンスが返ってくるという状態です。
メルペイでは、クライアントがIdempotency Keyという、各々が発行したUUIDをリクエストに付与しています。
続いてWrite repairです。通信先のマイクロサービスやネットワークに一時的な障害があった場合、クライアントは同じリクエストをリトライすることで不整合をオンデマンドに修復できます。タイムアウトとリトライを使ってやっています。
そのためにGoのgRPCのInterceptorのライブラリであるgrpc_retryを利用しています。
Asynchronous repairですが、Write repairでリトライしても修復できなかった場合に、非同期でマイクロサービス間の最終的な状態をチェックして、仮に不整合が発生した場合はあるべき状態に修復します。今はバッチによる定期実行をしていますが、今後の予定としてはCloud Pub/Subなどを使ってイベント駆動な設計にして、よりスケールするように修正する予定です。
では、ここで新たにでてきたWrite repairとAsynchronous repairについてざっくりと説明します。
まずはWrite repairについてです。StaticMPM Serviceが決済リクエストを投げるときに、Idempotency Key XXXというものを付与してTransaction Serviceにリクエストをします。Transaction Serviceは、そこからYYYというIdempotency Keyを作って一旦データベースにトランザクションとともにログとして書き込みます。このときはステータスをinitialとしています。
そこから決済リクエストをPayment Serviceに投げて、このときにIdempotency KeyのYYYを付与して投げます。
ここでPayment Serviceが高負荷であったり、ネットワークの分断があったりして決済がうまくいかなかったと仮定した場合、クライアントがタイムアウトを検知して、同じIdempotency Keyでリトライして、Transaction Serviceがログとして書き込んだIdempotency Keyを取得し、同じようにリトライをすることで不整合を解消できます。
続いてAsynchronous repairです。
ここは簡単で、ステータスが一定時間経過してもinitialなままだったトランザクションをデータベースが定期的にスキャンして、その対象の状態をPayment Serviceに確認しにいきます。仮にAuthorizedだった場合、決済の取り消しリクエストを実行して、対象のトランザクションをキャンセルします。そしてNot FoundだったりAuthorizedではないステータスだった場合は、そのままトランザクションを破棄します。
現状の課題です。これらの各機能をマイクロサービスそれぞれのアプリケーションコードに実装しなければならないということと、通信元や通信先のネットワーク遅延や分断状態を再現してテストをするのがとても難しいです。例えばiptablesで疑似的にパケット遅延を発生させたりしてテストをすることはできるんですが、けっこう大変で、etcdという分散キーバリューストアでGoでごりごりテストをしているんですが、なかなか大変です。
これから試してみたいことは、Envoyを使ってサービスメッシュの導入をしていきたいと考えています。これにはタイムアウトやリトライのテストをしやすくするためのFault Injectionという機能があるので、それを使ってもう少し信頼性が高く開発しやすい基盤を使っていきたいと思います。
まとめです。go-emv-codeを使うとEMV規格のQRコードのエンコードやデコードができるので、使っていただけるとありがたいです。サービスメッシュの登場で、マイクロサービス間の不整合対策の実装やテストがやりやすくなっていきそうな気がしているので、導入して試していきたいと思っています。
以上です。ご清聴ありがとうございました。
(会場拍手)
PayPay株式会社
関連タグ:
2024.10.29
5〜10万円の低単価案件の受注をやめたら労働生産性が劇的に向上 相見積もり案件には提案書を出さないことで見えた“意外な効果”
2024.10.24
パワポ資料の「手戻り」が多すぎる問題の解消法 資料作成のプロが語る、修正の無限ループから抜け出す4つのコツ
2024.10.28
スキル重視の採用を続けた結果、早期離職が増え社員が1人に… 下半期の退職者ゼロを達成した「関係の質」向上の取り組み
2024.10.22
気づかぬうちに評価を下げる「ダメな口癖」3選 デキる人はやっている、上司の指摘に対する上手な返し方
2024.10.24
リスクを取らない人が多い日本は、むしろ稼ぐチャンス? 日本のGDP4位転落の今、個人に必要なマインドとは
2024.10.23
「初任給40万円時代」が、比較的早いうちにやってくる? これから淘汰される会社・生き残る会社の分かれ目
2024.10.23
「どうしてもあなたから買いたい」と言われる営業になるには 『無敗営業』著者が教える、納得感を高める商談の進め方
2024.10.28
“力を抜くこと”がリーダーにとって重要な理由 「人間の達人」タモリさんから学んだ自然体の大切さ
2024.10.29
「テスラの何がすごいのか」がわからない学生たち 起業率2年連続日本一の大学で「Appleのフレームワーク」を教えるわけ
2024.10.30
職場にいる「困った部下」への対処法 上司・部下間で生まれる“常識のズレ”を解消するには