2024.12.10
“放置系”なのにサイバー攻撃を監視・検知、「統合ログ管理ツール」とは 最先端のログ管理体制を実現する方法
静的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.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
2024.12.09
国内の有名ホテルでは、マグロ丼がなんと1杯「24,000円」 「良いものをより安く」を追いすぎた日本にとって値上げが重要な理由
2024.11.29
「明日までにお願いできますか?」ちょっとカチンとくる一言 頭がいい人に見える上品な言い方に変えるコツ
2024.12.09
10点満点中7点の部下に言うべきこと 部下を育成できない上司の特徴トップ5
2024.12.04
いつも遅刻や自慢話…自分勝手な人にイラっとした時の切り返し 不平等な関係を打開する「相手の期待」を裏切る技
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.12.03
職場の同僚にイライラ…ストレスを最小限に抑える方法 臨床心理士が語る、「いい人でいなきゃ」と自分を追い込むタイプへの処方箋
2024.12.06
嫌いな相手の行動が気になって仕方ない… 臨床心理士が教える、人間関係のストレスを軽くする知恵
2024.12.05
「今日こそやろう」と決めたのに…自己嫌悪でイライラする日々を変えるには
PR | 2024.12.04
攻撃者はVPNを狙っている ゼロトラストならランサムウェア攻撃を防げる理由と仕組み