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

JP_Stripes: リコンサイル(突合処理)のテスト

acomagu
September 20, 2024
48

JP_Stripes: リコンサイル(突合処理)のテスト

acomagu

September 20, 2024
Tweet

Transcript

  1. @acomagu 伊藤勇希 - 会津大学23期
 - 東京からリモートでデザイニウム会津の仕事をさせていただいています
 - 武蔵村山市という超田舎に住んでいます 
 -

    今日は主に Stripe の話をしますが、5日後に JAWS-UG CDK 支部の CDK Conference Extra というイベントに「Terraform CDK in AWS CDK」というタイトルで 登壇しますので良かったら見に来てください
 Twitter: @acomagu

  2. Stripe は E2E テストがものすごくやりやすい - Stripe は公式でローカルで動くモックサーバーが提供されていたりするが、「本物」 をそのままテストで利用する方法もかなり充実している
 - 通常外部サービスをそのままテストで使おうとすると、結構つらみが多い場合もあ

    る
 - レスポンスが遅くてテストに時間がかかる 
 - かといって並列化すると Rate Limit に引っかかる 
 - たまに謎エラーが返却されてテストごと落ちる 
 - 異常系を再現する方法がない 
 ↑Stripe では今のところ全て経験していない
 - 唯一の Pain Point は(個人的には)Webhook だが、Stripe CLI の stripe listen –forward-to localhost でなんとかなりそう
 

  3. Samurai.MaaS では Webhook を利用していない - E2E テストが大変になる
 - Webhook を受け入れるコードにバグがあると、Stripe

    との不整合が発生する可能 性があり、回復を手動で行うしかない
 - 例えば「稀に Webhook リクエストを無視してしまうバグ」が存在したら? 
 →回復には Stripe と DB を全件チェックして突き合わせる処理を行う必要があるかも 
 上記の理由から、Samurai.MaaS では Webhook を利用しない構成にしています。
 (昔は Stripe Webhook を全面的に活用し Event Sourcing を行っていましたが、上記のような理由で辞めてしま いました
 歴史: SpeakerDeck「JP_Stripes 一貫性に寄与する設計」) 
 代わりに導入したのが→リコンサイル

  4. 私達の実装 Purchase というオブジェクトが Stripe の Checkout Session の状態に依存する状態を 持っています。
 私達のサービスでは、Stripe

    は下記の6つの状態を想定すれば十分であることが分か りました。
 「Checkout Session オープン」
 「Checkout Session 期限切れ」
 「キャンセル済み(全額返金済み or 失敗)」
 「キャプチャ待ち」
 「一部キャプチャ待ち」
 「成功」
 まず Stripe の支払いデータが上記のいずれに当たるのか返却する関数を作成しまし た。
 「Stripe リコンサイルの勘所」p26 より

  5. Samurai.MaaS のリコンサイル 私達のリコンサイルは
 Stripe 側は
 - Checkout Session オープン
 -

    Checkout Session 期限切れ
 - キャンセル済み(全額返金済み or 失敗)
 - 未キャプチャ
 - 一部未キャプチャ
 - 成功
 の6つの状態のうちのいずれかとして捉えています。

  6. Samurai.MaaS のリコンサイル Samurai.MaaS 側の “Purchase” は、
 - Incompleted
 - Unapproved


    - Uncaptured
 - Captured
 - Refunded
 - Denied
 の6つの状態があります。

  7. - Incompleted
 - Unapproved
 - Uncaptured
 - Captured
 - Refunded


    - Denied
 - Checkout Session オープン
 - Checkout Session 期限切れ
 - キャンセル済み(全額返金済み or 失敗)
 - 未キャプチャ
 - 一部未キャプチャ
 - 成功
 Samurai.MaaS 側
 Stripe 側

  8. - Incompleted
 - Unapproved
 - Uncaptured
 - Captured
 - Refunded


    - Denied
 - Checkout Session オープン
 - Checkout Session 期限切れ
 - キャンセル済み(全額返金済み or 失敗)
 - 未キャプチャ
 - 一部未キャプチャ
 - 成功
 正しい状態
 Samurai.MaaS 側
 Stripe 側

  9. - Incompleted
 - Unapproved
 - Uncaptured
 - Captured
 - Refunded


    - Denied
 - Checkout Session オープン
 - Checkout Session 期限切れ
 - キャンセル済み(全額返金済み or 失敗)
 - 未キャプチャ
 - 一部未キャプチャ
 - 成功
 正しい状態
 - (Deleted)
 Samurai.MaaS 側
 Stripe 側

  10. - Incompleted
 - Unapproved
 - Uncaptured
 - Captured
 - Refunded


    - Denied
 - Checkout Session オープン
 - Checkout Session 期限切れ
 - キャンセル済み(全額返金済み or 失敗)
 - 未キャプチャ
 - 一部未キャプチャ
 - 成功
 正しい状態
 - (Deleted)
 ↑こちらを「正しくない状態」へと 
 意図的にずらせればいい 
 (どうやって?)
 Samurai.MaaS 側
 Stripe 側

  11. Stripe API を叩けば状態を意図的にずらせる よってリコンサイルのテストは
 - Samurai.MaaS 側でテストしたい状態(Incomplete, Captured, …)まで購入を進める
 -

    Stripe API を叩いて購入に紐づいた Payment Intent 等の状態を「ずらす」
 - リコンサイルを実行し、差分が意図する形で解消されていることを確認
 という手順で行っています。

  12. おまけ: Stripe と E2E テストの Tips ① Stripe サンドボックスを活用しよう 


    普通に開発環境と同じ要領で E2E テストを回してしまうと、テストが回るたびに大量の Payment Intent や Customer が作成されてしまう
 そこで Stripe サンドボックス!
 Stripe サンドボックスは、「メインの環境の設定をコピーして作成されるテスト専用環境」
 普通に別アカウントを作成するのと違い、
 - Price や設定がコピーされる
 - 改めてチームメンバーを招待する必要がない
 というメリットがあり便利です。

  13. おまけ: Stripe と E2E テストの Tips ② Test Clocks を活用しよう

    
 「サブスクリプションが切れた時」の動作をするためには、サブスクリプションが切れるま で1ヶ月待たなければいけない?
 そこで Test Clocks!
 Customer を作成するときに Test Clocks を指定して作成すれば、その Customer の時 間だけ自由に進めることができる。
 (サブスクリプション限定機能)