Juju-62q's blog

参加記録やメモ書き、思考のまとめをしています

決済基盤でのテスト&リリース戦略(要件編)

f:id:Juju_62q:20191206175324p:plain

この記事はOpenSaaS Studio Advent Calendar 2019の6日目の記事です。

昨日の記事は

blog.stormcat.io

でした。

念のために伝えておきますとstormcat24 Advent Calendarではありません。

こんにちは。サイバーエージェント OpenSaaS Studioの@Juju_62qです。 普段自分は、Simply Payという決済基盤の開発を行っています。XX Payと聞くと、QR決済を想起する方も多いかと思いますがSimply Payはアプリケーションが決済を良い感じにするためのSaaSです。 最近継続課金の機能のリリースを行い、元々あった都度課金、銀行振り込み、ポイント管理機能も合わせて社内で必要な決済機能を取り揃えるまであと一歩という状態です(決済手段のとりこぼし等がいくらか)。 自分は今週と来週で2度にわけて決済基盤でのテスト&リリース戦略について書いていきます。 本来であれば実践部分だけでいいのですが、戦略と課金という領域の知識が深く混ざり合っているため要件と実践の2度に分割しています。

TL;DR

  • 決済システムで一番大事なのはお金が正しく処理されること
  • マイクロサービスで正確にトランザクションを管理するのは難しい
  • 放置するとデプロイが怖い状態に陥ってしまいリリースサイクルがどんどん落ちてしまう

決済基盤で最も大切なもの

決済系のSaaSで最も強く意識されることは”ユーザが実行した決済と結果が一致すること”だと思います。 エンドユーザやサービス開発者の立場でサービスを利用している時のことを考えるとこれはかなり自然です。

  • 決済を行ったのにその結果が反映されない
  • 課金額の2倍のポイントが付与された
  • 額は正しいが履歴が間違っている

1つ目の例であればお金を払ったのに結果として得られたものがないわけですから多くの場合問合せを行うでしょう。 そして、その対応がどうあれサービスに対する信頼やUXに大きくマイナスの影響をもたらすでしょう。

2つ目についてはエンドユーザは損をしていません。一方でサービスにとっては意図せぬ赤字が発生していることでしょうし、エンドユーザの立場からしてもかなり怪しい状況で体験がいいとはとても言えません。

3つ目は間違ってはいないかもしれませんが、エンドユーザとしてかなり気持ち悪いという印象を受けるでしょう。

もしこのような状況になる前に適切にエラーを返却することができていれば多少いらっとするなど体験を損なうかもしれないですがユーザ、サービス共に大きな損失にはなりません。

Simply Payでも、結果の完全性、一貫性を最も大切にしています。 もちろん決済基盤のダウンタイムはそのまま機会損失につながるため優先順位の問題があるだけで可用性等も非常に重要な要素です。

決済基盤とビジネス

決済基盤とビジネスは当然密につながります。 わかりやすいところで言うと逐次課金とサブスクリプションと言うようなお金の支払うタイミングの違いであったり、クレジットカード決済やキャリア決済というような支払う手段の違いが挙げられます。 そのほかにもポイントの付与や課金状態に応じた表示の変更など"課金"と紐付くビジネスの変化はあげればキリがありません。

エンドユーザのニーズや業界は物凄い勢いで変化をするわけですから当然決済基盤もすごい速さで変化することが要求されます。 そこで1つの機能に対してのリリースサイクルを早められるマイクロサービスアーキテクチャを採用しています。 副次的な効果として各機能の結合が疎になったため、クレジットカード決済機能の不具合によりキャリア決済の機能が落ちてしまうということがなくなりました。 全体に影響が出るよりもビジネス的な機会損失が避けられるというのは明確なメリットです。

分散システムとトランザクション

マイクロサービスを採用すると決めたのはいいものの基本的に分散システムとトランザクションは相反する組み合わせです。 一方で決済がどのような特徴を持つかというとトランザクションの権化です。 詰まるところ、分散システムできちんと整合性を保ったアプリケーションの開発は簡単ではありません。 具体的には下記のようなことを強く考える必要があります。

  • リトライ責務を誰が担うか明確にする
  • 冪等性をきちんと保証する
  • 途中で決済がロストしないようにステートを明確に管理する

決済システムは一般に状態遷移図のようなもので表現されることが多いですがステート管理をしながら、原子性を正確に管理するのは非常に難しい問題です。

チームが持つべき意識と副作用

したがってチームとしてリリースをする際にリトライ責務冪等性ステート管理がきちんと行われているのかを確認する必要があります。

これって簡単なことでしょうか?自分はそうは思いません。 このような背景からアプリケーションをリリースするための恐怖感が生まれてしまっています。 社会の変化に対応するためにマイクロサービスアーキテクチャを採用しているはずなのにマイクロサービス化したがゆえにデプロイが怖いという状態を生んでしまっています。

CI/CDに期待するもの

CIやCDはこの恐怖心を克服するための大切な武器です。 決済基盤に対するCI/CDではどんなものが求められるのでしょうか?

近頃のCDツールの多くはカナリアデプロイのような機能を備えているものが多いです。 しかしこれはチームの持つ恐怖感の解決につながるでしょうか?

例えば1%のトラフィックを新たにリリースしたものに流したとして、問題があれば5分後に自動的に切り戻しが行われるとしましょう。 確かに多くても99%の決済は救われているし、常にリリースし続けるわけではないですかもっと99%以上の決済は正常に行われるでしょう。 しかし基本的に決済の不整合は1つでも許されません。したがってカナリアリリースはAPIエラーや負荷確認の要素とはなり得ても正しく決済が行われるということの確認はできません。

決済基盤のCIやCDに求められることは"エンドユーザが決済を行った時に正常な額の決済が行える"という事実の確認です。 開発基盤を作る際には間違ったものを機械的に止める仕組みを最優先で作り上げる必要があります。

まとめ

決済基盤は信頼性が命です。 マイクロサービスアーキテクチャを採用しても何も考えないとむしろリリースサイクルが落ちる要因となってしまいます。 間違ったものを絶対に通さないという意思を込めたCD戦略を立てましょう。

次回予告

というわけで今日は決済基盤という領域での要件や特性について話をしました。 ビジネス要件を丁寧に解説しないと"なぜSimply Payでそのテスト&リリース戦略を採用したのか"という解説が薄くなってしまうので今日はケーススタディの記述を行うのは避けました。 来週は具体的にSimplyではどのような開発、テストを行い、何を行うことをリリースの基準にするのかという話をしていこうと思います。是非楽しみにしててください〜!