Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Settlement simulation testing to ensure correct settlement processing

Settlement simulation testing to ensure correct settlement processing

23e9a5be8e46efd1cf6a07694a047237?s=128

Takashi Matsuyuki

August 04, 2022
Tweet

More Decks by Takashi Matsuyuki

Other Decks in Technology

Transcript

  1. 2022/08/04 Tech Meetup 〜Goで作る決済サービス〜 takashi matsuyuki (@applepine1125) "正しい”決済処理を実現する 決済シミュレーションテスト

  2. 自己紹介 BASE, inc. (2020/09~) BASE BANK Section Dev Group /

    BASE Card Team Group Manager/EPM*1/Fullcycle Engineer Goとカード決済領域を生業としています Twitter: @applepine1125 *1: https://devblog.thebase.in/entry/bank-epm takashi matsuyuki 2
  3. 目次 1 2 3 BASEカードのシステムアーキテクチャ “正しい”決済処理とはなにか 3 決済シミュレーションテストを支える技術

  4. BASEについて 4 BASE株式会社 個人やスモールチームをエンパワーメントする ネットショップ作成サービス「BASE」 誰でもかんたんにネットショップを 無料で作れるネットショップ作成サービス 開設ショップ数180万ショップ突破 個人・スモールチーム等のショップ向け

  5. BASE BANK Section/BASEカードについて 5 BASE BANK Section "銀行をかんたんにし、全ての人が挑戦できる 世の中に" 個人やスモールチームのキャッシュフローに

    おける課題解決に取り組んでいる BASEカード BASEのショップオーナー向けプリペイドカード “ネットショップの売上がすぐに使える” 遍歴 2021/09 リリース 2022/04 リアルカードリリース BASE株式会社 BASE BANK紹介資料 https://speakerdeck.com/base/basebank
  6. BASEカードの システムアーキテクチャ 6

  7. BASEカードのシステムアーキテクチャ 7 主要部を抜粋 ショップオーナーにサービス提供 - ショップオーナーとのタッチポイントは BASEの管理画面 - コアロジックを司るアプリケーションはGoを 使用

    - 開発の際はBASE BANK管掌のアプリケー ションとBASEのシステム両方に手を入れる BASE BANKチームの技術選定と歴史 https://speakerdeck.com/budougumi0617/how-to-decide-technology-selection-for-startup
  8. BASEカードのシステムアーキテクチャ 8 独立したシステム構成 - BASE BANKのプロダクトは基本BASE BANK 用のAWSアカウント上に構築しているが、 非機能要件を加味しBASEアカウント上に構築 →TerraformでIaC化し、少数精鋭のチーム

    で効率よく管理、改善できるように - BASEcardDBはBASEカードアプリケーショ ンからのみアクセスできるようにし、 BASECard MicroServiceとして稼働 →チーム内で極力開発の意思決定ができるよ うに疎結合に 主要部を抜粋
  9. BASEカードのシステムアーキテクチャ 9 主要部を抜粋 外部企業と連携しカード決済を実現 - 決済ネットワークとは直接接続せず、PAN 管理、割り当てやプロセシングを行う外部企 業と連携 →BASE BANK側でPCI

    DSS取得が不要に - 提携企業側で電文の情報をよしなに抽象化 してくれたり、オーソリと決済確定処理(ク リアリング)はやってくれている
  10. “正しい”決済処理とはなにか 10

  11. そもそもカード決済ってどういう仕組みなの 1 1 1 1 決済(オーソリ) 決済確定(クリアリング) オーソリのキャンセル 決済確定のキャンセル 商品を買うぞ!

    今日は閉店!締め処理だ! やっぱ返品するわ! やっぱ返品するわ! カード決済業務のすべて―ペイメントサービスの仕組みとルール https://store.kinzai.jp/public/item/book/B/12122/ 決済サービスとキャッシュレス社会の本質 https://store.kinzai.jp/public/item/book/B/13552/ 主なカード決済のフロー 決済確定前に返品する場合・・・ 決済確定後に返品する場合・・・
  12. カード決済の大変なところ 1 2 1 2 うちシステム的には OKしたけど結果的に 失敗したら?? 複数商品買って1点だけキャンセル?? 確定のキャンセルの

    キャンセル?? オーソリ受けてないのに 確定がいきなり飛んできた?? 有効性確認オーソリ?? オーソリは1つなのに商品ごとに 確定がバラバラ?? プリペイドだと使え ない加盟店がある?? 確定に紐付かない キャンセル?? 決済(オーソリ) 決済確定(クリアリング) オーソリのキャンセル 決済確定のキャンセル 商品を買うぞ! 今日は閉店!締め処理だ! やっぱ返品するわ! やっぱ返品するわ!
  13. エッジケースがいっぱい

  14. “正しい”決済処理とは n*10年モノの歴史的経緯が詰まった仕様を基にした決済を 1. 正しく処理できること 2. 正しく(かつ、わかりやすく)表示できること これを “正しい”決済処理 とこの発表では定義します

  15. 決済シミュレーションテスト を支える技術 15

  16. なぜシミュレーションテストを行うのか 1. 正しく処理できること -> 残高変動など 2. 正しく表示できること -> 決済履歴の作成、更新 -

    BASEカードの最重要フィーチャである決済処理の正確性を担保するために行う - もちろんユニットテストも手厚く書いている前提 - シミュレーションテストが最終防衛ラインというより、更にプロダクトの質を高めるため の一手というイメージ - なぜテストしたいのか?をちゃんと考えよう testingパッケージを使った Webアプリケーションテスト 単体テストからE2Eテストまで https://speakerdeck.com/budougumi0617/gocon2022spring
  17. なぜシミュレーションテストを行うのか 1 7 もうちょっと具体的にテストに対する期待や要件を書くと・・・ - 決済の流れに沿って作成、変更された決済レコードや残高変動の正当性を確認したい - テスト対象が状態を持つのでUTでは担保できない - メンテナビリティはそこまで重要視しない。テストケースの追加がしやすければよい

    - 決済の仕様が大きく変わることはないため - 決済のデグレを防ぐためにエッジケースまで対応したい - 安心して開発したい! → E2Eテストを実装する
  18. シミュレーションテストのポイント 1. 実現手段 2. テストケース

  19. シミュレーションテストの実現手段 1 9 シナリオベースのE2Eテスト APIリクエストを行い、出力結果としてDBのレコードを確認する 1. テスト用DB立ち上げ、マイグレーション、テストデータinsert実行 2. *httptest.Serverを使ってサーバ起動 3.

    Table Drivenでテストシナリオ実行 4. DBから結果を取得し残高変動が正しいか、決済情報を正しく格納できているかを 期待値と比較
  20. シミュレーションテストの実現手段 2 0 E2Eテストのコード(一部省略)

  21. シミュレーションテストの実現手段 2 1 net/http/httptest パッケージを使ったサーバの起動 - goroutineで*http.Serverを起動し、リッスンするまで別goroutineで待機し、テスト終 了時にサーバを適切に閉じる・・・といったことを考えなくていい -> テストの記述に集中できる

    実DBを使ったテスト実行 - テスト用のDBコンテナを用意 - docker-composeで管理 - マイグレーション - sql-migrateを使用 net/http/httptest https://pkg.go.dev/net/http/httptest sql-migrate https://github.com/rubenv/sql-migrate
  22. シミュレーションテストの実現手段 2 2 余談: handlerのテストでもhttptest pkgを使用 Advanced Testing with Go

    https://speakerdeck.com/mitchellh/advanced-testing-with-go httptest.NewRequest() で擬似的な リクエストを作成できる httptest.NewRecorder() で http.ResponseWriterを満たすオブジェクト を取得し、戻り値を検証する事ができる リクエスト、レスポンスはGolden fileを用意 しテスト
  23. シミュレーションテストのテストケース 2 3 ケース例 (ケース実行前の残高は1000円) - シンプルなケース input (数字はリクエスト順序) 1.

    決済: 100円 2. 決済確定:100円 output - 残高: 900円 - 決済履歴: 100円, 確定状態
  24. シミュレーションテストのテストケース 2 4 ケース例 (ケース実行前の残高は1000円) - 割と複雑なケース input (数字はリクエスト順序) 1.

    決済: 100円 2. 確定前キャンセル: 50円 3. 決済確定:51円 - 為替変動などの影響 4. 確定後キャンセル: 25円 output クイズ! - 残高: ???円 - 決済履歴: ??円, ??状態
  25. シミュレーションテストのテストケース 2 5 ケース例 (ケース実行前の残高は1000円) - 割と複雑なケース input (数字はリクエスト順序) 1.

    決済: 100円 2. 確定前キャンセル: 50円 3. 決済確定:51円 - 為替変動などの影響 4. 確定後キャンセル: 25円 output クイズ! - 残高: 974円 - 決済履歴: 26円, 確定状態 ・・・みたいなケース(もっと複雑なものも)をひたすら洗い出して網羅、実行
  26. シミュレーションテストで実現できたこと 2 6 - 決済の流れに沿って作成、変更された決済レコードや残高変動の正当性を確認したい → シナリオベースのE2Eテストを実装、出力結果としてDBのレコードをチェックし担保 - メンテナビリティはそこまで重要視しない、テストケースの追加がしやすければよい →

    テーブルドリブンなテスト実装により、ケース追加は容易に - 決済のデグレを防ぐためにエッジケースまで対応したい → テストケースで決済フローをシーケンシャルかつ柔軟にシミュレーションできるように VISA決済のドメイン知識があったのでケースを(おそらく)網羅できた カード決済のSaaS使ってるとはいえ、カード決済の深いドメイン知識がないと ”正しい”決済処理を実現できないのが決済領域の難しいところ 決済に限らず金融、会計領域は特に深いドメイン知識を要求されることが多い
  27. まとめ 27

  28. まとめ 正しい決済処理の実現のためには 深いドメイン知識が必要 シナリオベースのE2Eテストで質を担保 28 なぜテストをしたいのか?から考えて 打ち手を選ぼう 1 2 3

  29. We are hiring! 29 @applepine1125 BASE BANK 紹介資料 https://twitter.com/applepine1125 https://speakerdeck.com/base/basebank