Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
JP_Stripes: リコンサイル(突合処理)のテスト
Search
acomagu
September 20, 2024
130
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
JP_Stripes: リコンサイル(突合処理)のテスト
acomagu
September 20, 2024
More Decks by acomagu
See All by acomagu
Payment Records API を使って地域通貨を Stripe Dashboard に統合してみた
acomagu
0
62
Restate x Stripe: 安心して眠れる決済システムを目指して
acomagu
0
16
Stripe SSoT をするべきか否か
acomagu
0
81
「境界付けられたコンテキスト間の関係」についてもっと語ろう
acomagu
0
170
地方 MaaS 事例: アプリの進化に伴って変化してきた Stripe 利用方法
acomagu
0
500
Stripe リコンサイルの勘所
acomagu
0
540
CDK 一発で全てのエラーログを Slack に流す
acomagu
0
2.3k
AWS CDK を支える Constructs について
acomagu
0
190
DDDとは結局何なのか
acomagu
0
450
Featured
See All Featured
Learning to Love Humans: Emotional Interface Design
aarron
275
41k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
580
Building an army of robots
kneath
306
46k
ラッコキーワード サービス紹介資料
rakko
1
3.6M
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
300
Skip the Path - Find Your Career Trail
mkilby
1
140
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
270
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
19k
Paper Plane (Part 1)
katiecoart
PRO
0
8.8k
Six Lessons from altMBA
skipperchong
29
4.3k
Transcript
リコンサイル (突合処理) のテスト 「JAWS-UG会津」&「JP_Stripes会津」合同勉強会 2024 Autumn 株式会社デザイニウム 伊藤勇希 @acomagu
@acomagu 伊藤勇希 - 会津大学23期 - 東京からリモートでデザイニウム会津の仕事をさせていただいています - 武蔵村山市という超田舎に住んでいます -
今日は主に Stripe の話をしますが、5日後に JAWS-UG CDK 支部の CDK Conference Extra というイベントに「Terraform CDK in AWS CDK」というタイトルで 登壇しますので良かったら見に来てください Twitter: @acomagu
株式会社デザイニウムで Samurai.MaaS を作っています - バスチケット等の購入/利用ができる PWA - about.samurai.ms
テストでモック/スタブを利用するべきか? 外部サービスに依存するとき、それを実際に使う方法とモックする方法がある モック/スタブの利点 - まだ実装がない外部ライブラリ等があっても実装開始可能 - 外部を汚さずに実行可能 - 速い モック/スタブのデメリット
- 実際と違うコードが動く - 外部サービスの仕様に対して正確に模倣・追従することが必要
よく見る図 しかし Samurai.MaaS ではほとんど E2E テスト で書いている
なぜ E2E テストがほとんどなのか - 1年ほど前まで自動テストが存在せず、そのときに最も課題だったのが「安心して コードを変更できない」ことだった - 開発の空き時間に E2E テストを徐々に導入していくことで、割と初期から「プロダク
ト全体の包括的な動作確認ができる」というメリットを得られた
Stripe は E2E テストがものすごくやりやすい - Stripe は公式でローカルで動くモックサーバーが提供されていたりするが、「本物」 をそのままテストで利用する方法もかなり充実している - 通常外部サービスをそのままテストで使おうとすると、結構つらみが多い場合もあ
る - レスポンスが遅くてテストに時間がかかる - かといって並列化すると Rate Limit に引っかかる - たまに謎エラーが返却されてテストごと落ちる - 異常系を再現する方法がない ↑Stripe では今のところ全て経験していない - 唯一の Pain Point は(個人的には)Webhook だが、Stripe CLI の stripe listen –forward-to localhost でなんとかなりそう
Samurai.MaaS では Webhook を利用していない - E2E テストが大変になる - Webhook を受け入れるコードにバグがあると、Stripe
との不整合が発生する可能 性があり、回復を手動で行うしかない - 例えば「稀に Webhook リクエストを無視してしまうバグ」が存在したら? →回復には Stripe と DB を全件チェックして突き合わせる処理を行う必要があるかも 上記の理由から、Samurai.MaaS では Webhook を利用しない構成にしています。 (昔は Stripe Webhook を全面的に活用し Event Sourcing を行っていましたが、上記のような理由で辞めてしま いました 歴史: SpeakerDeck「JP_Stripes 一貫性に寄与する設計」) 代わりに導入したのが→リコンサイル
リコンサイル(突合処理)とは? 自前 DB の「購入」と Stripe 上の「購入」を一件一件照らし合わせ、不整合が無いか確 認するバッチ処理 不整合があれば: 整合性が取れるようにどちらかを合わせる (詳しくは:
SpeakerDeck「Stripe リコンサイルの勘所」)
リコンサイルのテストをどうするか...? 一応システムは「リコンサイル無しでも正しく動く」ことを目指しているため、普通に正常 系を動かしているだけではリコンサイルは何もせず終了するだけ。 「自前 DB と Stripe の状態をわざとずらす」ことをしないとリコンサイルのテストはできな い。
→どうずらすか?
私達の実装 Purchase というオブジェクトが Stripe の Checkout Session の状態に依存する状態を 持っています。 私達のサービスでは、Stripe
は下記の6つの状態を想定すれば十分であることが分か りました。 「Checkout Session オープン」 「Checkout Session 期限切れ」 「キャンセル済み(全額返金済み or 失敗)」 「キャプチャ待ち」 「一部キャプチャ待ち」 「成功」 まず Stripe の支払いデータが上記のいずれに当たるのか返却する関数を作成しまし た。 「Stripe リコンサイルの勘所」p26 より
Samurai.MaaS のリコンサイル 私達のリコンサイルは Stripe 側は - Checkout Session オープン -
Checkout Session 期限切れ - キャンセル済み(全額返金済み or 失敗) - 未キャプチャ - 一部未キャプチャ - 成功 の6つの状態のうちのいずれかとして捉えています。
Samurai.MaaS のリコンサイル Samurai.MaaS 側の “Purchase” は、 - Incompleted - Unapproved
- Uncaptured - Captured - Refunded - Denied の6つの状態があります。
- Incompleted - Unapproved - Uncaptured - Captured - Refunded
- Denied - Checkout Session オープン - Checkout Session 期限切れ - キャンセル済み(全額返金済み or 失敗) - 未キャプチャ - 一部未キャプチャ - 成功 Samurai.MaaS 側 Stripe 側
- Incompleted - Unapproved - Uncaptured - Captured - Refunded
- Denied - Checkout Session オープン - Checkout Session 期限切れ - キャンセル済み(全額返金済み or 失敗) - 未キャプチャ - 一部未キャプチャ - 成功 正しい状態 Samurai.MaaS 側 Stripe 側
- Incompleted - Unapproved - Uncaptured - Captured - Refunded
- Denied - Checkout Session オープン - Checkout Session 期限切れ - キャンセル済み(全額返金済み or 失敗) - 未キャプチャ - 一部未キャプチャ - 成功 正しい状態 - (Deleted) Samurai.MaaS 側 Stripe 側
- Incompleted - Unapproved - Uncaptured - Captured - Refunded
- Denied - Checkout Session オープン - Checkout Session 期限切れ - キャンセル済み(全額返金済み or 失敗) - 未キャプチャ - 一部未キャプチャ - 成功 正しい状態 - (Deleted) ↑こちらを「正しくない状態」へと 意図的にずらせればいい (どうやって?) Samurai.MaaS 側 Stripe 側
ずらし方 Stripe API /checkout/sessions/expire で可能 - Checkout Session オープン -
Checkout Session 期限切れ
ずらし方 Stripe API /payment_pages/{checkout_session_id}/confirm を User-Agent: Stripe/v1 stripe-cli/master 等のヘッダをつけて叩くと可能 -
Checkout Session オープン - 未キャプチャ(もしくは成功)
ずらし方 Stripe API /payment_pages/{checkout_session_id}/confirm に Stripe のエラーテストカードトークン(tok_visa_chargeDeclined 等)を投げると可能 - Checkout
Session オープン - キャンセル済み(全額返金済み or 失敗)
ずらし方 Stripe API /payment_intents/:id/capture を金額指定して叩くと可能 - Checkout Session 未キャプチャ -
一部未キャプチャ
ずらし方 Stripe API /payment_intents/:id/capture で可能 - 一部未キャプチャ - 成功
Stripe API を叩けば状態を意図的にずらせる よってリコンサイルのテストは - Samurai.MaaS 側でテストしたい状態(Incomplete, Captured, …)まで購入を進める -
Stripe API を叩いて購入に紐づいた Payment Intent 等の状態を「ずらす」 - リコンサイルを実行し、差分が意図する形で解消されていることを確認 という手順で行っています。
金額をずらす場合は? これらの状態のとき金額がずれている場合についてもテストしたいが、Stripe API からは無理 そう... ↓ 一部は Samurai.MaaS 側のデータの方をずらすことで再現 -
Checkout Session オープン - 未キャプチャ - 一部未キャプチャ - 成功
まとめ - Samurai.MaaS では、リコンサイル時に「Stripe の状態」を必要な情報のみ含むよう に、6つの状態に単純化してからリコンサイルを行っている - なので、リコンサイルのテストでは、その6つの状態を他の状態にずらすことでリコン サイルが必要な状況を再現する -
これは、Stripe API で全て行えることが分かった - 金額をずらすことに関しては、Stripe API からはほとんど再現できないので、こちら 側のデータを変更して再現している
おまけ: Stripe と E2E テストの Tips ① Stripe サンドボックスを活用しよう
普通に開発環境と同じ要領で E2E テストを回してしまうと、テストが回るたびに大量の Payment Intent や Customer が作成されてしまう そこで Stripe サンドボックス! Stripe サンドボックスは、「メインの環境の設定をコピーして作成されるテスト専用環境」 普通に別アカウントを作成するのと違い、 - Price や設定がコピーされる - 改めてチームメンバーを招待する必要がない というメリットがあり便利です。
おまけ: Stripe と E2E テストの Tips ② Test Clocks を活用しよう
「サブスクリプションが切れた時」の動作をするためには、サブスクリプションが切れるま で1ヶ月待たなければいけない? そこで Test Clocks! Customer を作成するときに Test Clocks を指定して作成すれば、その Customer の時 間だけ自由に進めることができる。 (サブスクリプション限定機能)