iD決済を支える技術 / #merpay_techtalk

iD決済を支える技術 / #merpay_techtalk

2295fec4d38f59366f983d38628e6ca0?s=128

Hiraku NAKANO

March 27, 2019
Tweet

Transcript

  1. @hiraku iD決済を支える技術(server side) ※「iD」は株式会社NTTドコモの商標です

  2. @hiraku (中野 拓) • 2015年12月 メルカリにPHPエンジニアとしてJoin ◦ Composerを速くする趣味 • 2018年2月

    メルペイに異動 ◦ 最初はPHPコードの改修をやってた ◦ 4月~ bank-service(銀行接続) ◦ 9月~ nfc-serviceほぼ専属に • 2019年2月 iD決済リリース!!
  3. リリースした今なら言える ネタばらし色々

  4. 目次 1. iD決済(メルペイ電子マネー) 2. システム構成 3. フレームワーク談義 4. microservicesのつらいところ

  5. iD決済(メルペイ電子マネー)

  6. None
  7. • メルカリの売上金を使って買い物できる • iOS→Apple Pay • Android→おサイフケータイ ◦ iDがauのスマホでも使えるという熱々 ポイント

    • バックエンド側の開発がうちのチーム
  8. NFC決済の特徴 • Pros ◦ 全国80万箇所+で使える!(iDとの提携) ◦ 決済体験のスムーズさ ◦ Apple Payを経由するとSuicaチャージやアプリ内決済にも

    ◦ 3大キャリア x iOS/Android 全部使える • Cons ◦ 加盟店側にNFCリーダーが必要 ◦ 加盟店側に決済手数料が… (※コード払いとの比較) ◦ スマホがFeliCa対応でないと使えない
  9. NFC決済を使うまでの道のり 1. Virtual Cardを発行する a. クレカではなくプリペイドカードの扱い b. 発行自体は三井住友カード社のシステムで行う 2. Device-PANを発行して端末のチップに書き込む

    1. レジ端末にピッとかざすと、店舗側のネットワークから経由して メルペイに通信が来る 2. 残高が足りていればOKを返して、決済が成功する
  10. 電子マネーのタイプ • サーバー管理型プリペイドのバーチャルカード(物理板はない) • メルペイ側で全てのvalue(売上金 or ポイント)を管理 ◦ 決済ごとにメルペイに通信して、相当額を「チャージ」して即座 に使っている

    ◦ 自動販売機やガソリンスタンドなど、店舗の端末がオフラインだ と使えない ◦ 逆にiPhone/Androidは機内モードやオフラインでもOK
  11. システム構成

  12. "メルペイがmicroservicesを採用し たのは、他に選択肢がなかったから" by @kazegusuri (merpay architect)

  13. メルペイのシステムの前提 • 多くのシステムを同時に作る必要があった ◦ コード払い ◦ あと払い ◦ メルカリ内決済 ...etc

    • microservicesを採用して、各チームで試行錯誤するしかなかった →NFC決済システムも、専用serviceとして作成することに
  14. NFC決済を実現するために必要だったもの • 主な機能はSMCC社のシステムで実現できた • 登録系 1. メルカリ会員 ⇔ カード の管理

    2. 端末プロビジョニングに必要なAPIをproxyして、ユーザー認証を 正しく実装する • 決済利用系 1. SMCC社から来る承認リクエストを受けて、即座に結果を返す
  15. nfc-service merpay-gateway registration / provisioning nfc-serviceが不要な一部機能の実装 関係するmicroservices merpay-gateway nfc-api merpay-api

    payment, balance, etc charge (決済利用) SMCC (カード発行& 管理) POS casher registration (登録) user_id ⇔ cardのDB保持 リクエストの翻訳 アクセス元の認証 mercari-api SMS認証 電話番号参照
  16. nfc-serviceの中身 DB (Cloud Spanner) Kubernetes • コンテナイメージは一種類、Goのビルド結果が入ってる ◦ grpc-server +

    Pub/Subのsubscriber ◦ batch • k8s Deployment ... grpc-server + subscriber ◦ Autoscalerも有効にしてある • k8s CronJob ... batch • k8s ConfigMap ... 他serviceのアドレスなどの設定 • k8s Secret ... 秘匿性の高い鍵など • DataDogでメトリクス収集、監視 Cloud Pub/Sub
  17. nfc-serviceのk8s.yaml $ grep 'kind:' k8s.yaml kind: Deployment kind: ConfigMap kind:

    Service kind: CronJob kind: CronJob kind: CronJob kind: CronJob kind: CronJob kind: CronJob kind: CronJob kind: CronJob kind: CronJob
  18. バッチ…

  19. バッチ度の高いkubernetesアプリケーション • カードのバッチ発行 ◦ リアルタイムには発行済のカードから割り当てるだけにする • 発行依頼→発行→取り込み (全部バッチ…) • 売上の日次確定処理

    • microservice同士の不整合の検知と修復batch • etc... • etc... • でも何とかなってるのでKubernetesすごい
  20. デプロイの関係 • 「バッチが動いてるときにデプロイして良いんだっけ?」 →CronJobはPodを生成して動きはじめるので、Deploymentを上書 きしても支障はない • その他のデプロイ時の細かい問題はSpinnakerが吸収している ◦ ConfigMapに自動でversion切るとか

  21. フレームワーク談義

  22. "フレームワークはプロジェクトの初 期の段階では便利ですが、フレーム ワークに付加された複雑さにより 長期の保守が難しくなります" プログラミング言語Go P223より

  23. gRPCサーバーを作る必要があったので • google.golang.org/grpc を素朴に使って実装していく • interceptorを使って抽象化 ◦ Webフレームワークだとmiddlewareって呼ばれるような機構 ◦ 内製interceptorがいっぱいある

    ◦ 認証 ◦ ログ ◦ DataDog • ロガーは zap が実質標準
  24. ソースツリー雰囲気 • cmd/server/main.go • grpc/server.go ... gRPCサーバーのinterceptor組み立て • grpc/charge/ ...

    決済系のgRPCサービスコード • grpc/registration/ ... 登録系のgRPCサービスコード • usecase/ ... ドメインロジック本体色々 • model/ ... Entity. DBに記録される構造 • repository/ ... DB操作色々
  25. 困ったこと • grpc-serverは割と作法が固まってて悩みにくかった ◦ エラーコードがHTTPと違うのには未だ慣れないが… • batchとpubsubのsubscriberは、自己流… • batch系とserver系でコードの重複があるけど、うまく抽象化できて いない

  26. microservicesのつらいところ

  27. 他serviceとの整合性

  28. こういうタイムアウトが困る nfc payment 決済処理して nfc payment ...返事がない 打ち切ろう 実は成功して ました

  29. 不整合はどこにでも起きうる • nfcとpayment ◦ 「決済失敗したって返したけど、実は成功してました」 →クライアントが失敗を受けてリトライすると、 二重決済になる! • nfcとSMCCシステム •

    etc... • microservicesはDBを共有しない = DBトランザクションが使えない
  30. こうやって解決 nfc payment 決済処理して nfc payment ...返事がない 打ち切ろう 実は成功して ました

    決済指示を 記録 打ち切りを 記録 nfc repairer payment側の最終状態を確認 不整合は取り消しを実行、自動修復
  31. いわゆるジャーナリングと冪等性によるリトライ • 全ての処理は一意なidを振り、なるべく冪等になるように作る • いつでも気軽にリトライできるようにする • 不整合は別プロセスが復旧していく • 泥臭いけど、仕方ない •

    これって、一般的なDB製品が備えているトランザクションの基礎技術 そのものだよね…? • 最終的に問題のない状態へ収束するように作る
  32. まとめと総括

  33. この一年どうだった? • 4月になるまでGoもk8sもガッ ツリ開発に使ったことなかった ◦ 手探りで進まない無力感 • チームメンバー、SREや Architectに圧倒的感謝 •

    珉珉六本木店のチャーハン餃子 セット