決済システムを壊さずに拡張した話

メルペイのBackend Engineerの @Hiraku です。与信決済システムのmicroserviceのTech Leadをしております。

この記事は、Merpay Advent Calendar 2022 の5日目の記事 メルカードの舞台裏編です。

2022年11月8日にメルペイ初のクレジットカードであるメルカードがリリースされました。これに伴い、システムにも広範囲に変更が加わっています。この記事ではその中でもちょっと分かりにくい、メルペイスマート払いの請求タイミングの変更について解説します。

月末ごろにメルカードによる決済を行うとわかるのですが、「処理中」と表示され、翌月の請求に含まれないものがあります。こちらはメルカード特有の実売上処理が終わってから請求する挙動です。順番に解説していきます。

カード決済の流れ

決済は大きく2段階の処理で成り立っています。「オーソリ」や「仮売上」と呼ばれる、利用可能枠の中から枠を押さえる処理と、実際に確定させる「売上」や「実売上」と呼ばれる処理です。オーソリと同額の実売上を立てるのが最も単純なケースです。

決済が2段階に分かれていることを活用すると、様々な決済スキームを実現できます。

例えば通販サイトで取り寄せ商品を扱う場合。購入時点でオーソリだけ行い、仮押さえをしておき、実際は在庫の確保ができた分だけを実売上として計上することができます。

他には、飲食店を予約する場合。飲食店側としては、万が一ドタキャンされたときにキャンセル料を取りたいニーズがあると思います。オンライン予約システムを用意して事前にオーソリしておき、実際の利用に応じた実売上を立てることで実現できます。

こういった柔軟な決済スキームの提供は、カード決済ならではのものです。

オーソリの時点で請求する世界

メルカードのリリース前から、iD決済やバーチャルカードなど、プリペイドによる決済方法を提供していますが、ここでも、カード決済の枠組みで決済システムが構築されており、オーソリと売上の2段階で動作します。
iD決済やバーチャルカードでは、支払い方式(チャージ方法)としてメルペイスマート払い(あと払い)を選べるようになっており、クレジットカードと同じく利用の翌月にお客さまに請求書を作成します。
このとき、メルカードや一般的なクレジットカードと異なる特徴として、「オーソリの段階の金額」をもとに請求書を作成するという点があります。少し分かりにくいので例を出します。

  • 1月31日: 300円の商品Aを購入(オーソリのみの状態)
  • 2月1日: 1月分の請求開始
    • 商品Aの300円分が入っている
    • 支払い期限は2月末
  • 2月2日: 商品Aを返品、キャンセル
    • 請求額から300円が減額される
    • すでに清算済みの場合は、300円が返金される

メルペイスマート払いは月末締め、翌月中に支払う形を取っています。このように月末頃に決済するとまだオーソリ状態ですが、翌月の請求に含まれます。請求を開始してから実売上のタイミングでキャンセルされたり、金額が変更になる可能性がありますが、状況に応じて請求の修正を行います。

なお、一般的なクレジットカードでは実売上が確定してから請求書に含めます。その方が請求書に修正が加わる可能性がなくなり、処理がシンプルになります。にもかかわらず、メルペイスマート払いがオーソリ時点で請求しているのは、以下の理由によるものです。

  • 割賦販売法上の二月払購入あっせん(いわゆるマンスリークリア)の範囲で請求清算が収まるようにしているため
    • メルペイスマート払いは翌月一括払い(マンスリークリア)の範疇でサービス提供しており、分割払いなど、2ヶ月を超えるあと払い方法を提供している一般的なクレジットカードとは適用される規制が異なります。
  • iDやバーチャルカードなどはプリペイドカードの券種を採用しており、いくつかの複雑な決済スキームは発生しない、あるいは発生頻度が低いことが見込まれている
    • このため請求の修正も受け入れ可能な範疇になる

清算期日を早めるなどで回避する方法もあるものの、月1回の請求清算の締日というわかりやすさを優先した仕様になっています。

クレジットカードの世界

さて、新しく登場したメルカードは「クレジットカード」です。公共料金や携帯電話料金などのサブスクリプション、海外取引などもカバーする、決済としてはフル機能を備えたものです。

プリペイドカード券種では拒否されていたような決済スキーム、特にオーソリより実売上の方が金額が大きくなるケースの増加が想定されることから、それを支える決済システムがオーソリ時点請求のままでは対応が難しく、売上時の請求に切り替えるというプロジェクトが立ち上がりました。

例として、こんな挙動を実現したいという要求です。

  • 1月31日: 300円の商品Aを購入(オーソリのみの状態)
  • 2月1日: 1月の実売上分を請求開始
    • 商品Aの分は含まれない
  • 2月2日: 商品Aが500円で実売上
  • 3月1日: 2月の実売上分を請求開始
    • 商品Aの500円分が含まれる
    • 支払い期限は3月末

請求タイミングを変更するだけ、と言うと簡単そうに聞こえますが、すでに請求書が大量に発行されている状態で、これらの請求書も辻褄が合うように仕様変更するのは大変むずかしい作業になります。

もし既存の請求も含めて仕様変更するとなると、お客さまとのコミュニケーション、発行済みの請求書をマイグレーションする作業、過去の履歴表示をどうするのかなど、考えることが山積みです。また、決済システムを扱うサービスとしてはなるべく無停止でリリースしたいものです。これは下手をすると改修に1年以上かかってしまうのではないか… そんな想定もされていました。

要求整理 / 設計

冷静に今回の要求を整理していくと、いくつかの事実が浮かび上がってきました。

  • 既存の決済はオーソリ時請求のままで問題ない
    • むしろ、オーソリ時請求を崩すとマンスリークリア要件が満たせなくなるため、変更しないほうが良い
  • メルカード経由の決済かどうかは見分けがつく

大枠として、メルカード経由の決済のみ実売上時請求に切り替え、それ以外の既存決済は仕様変更しないという方針が見えてきました。これなら既存決済をどうするのかといった問題は解消します。あとはシステム上の辻褄を合わせるだけです。

既存のオーソリ時請求でのシステム内のデータの流れは以下のようなものです。

  1. オーソリ電文が上流システムから届く
  2. 未清算の債権を集計し、利用可能枠が残っているかどうか判断
  3. 利用可能枠内に収まるなら決済を許可し、新たな債権を登録
  4. 実売上電文が上流システムから届く
    • 金額に変更がなければ特に何もしない
  5. 登録された債権を翌月まとめて請求する

ここにどう変更をすると売上時の請求が実現できるでしょうか。

新たな概念の導入

実売上時請求を実現するにあたり、新たに導入したのが未確定債権というデータ概念です。請求書には含めず、利用枠の集計には含めるようになっています。

  1. オーソリ電文が上流システムから届く
  2. 未清算の債権および未確定債権を集計し、利用可能枠が残っているかどうか判断
  3. 利用可能枠内に収まるなら決済を許可し
    • メルカードによる決済なら未確定債権を登録
    • それ以外の決済なら債権を登録
  4. 売上電文が上流システムから届く
    • 未確定債権として登録があれば、債権へ変換する
    • 債権として登録されていれば何もしない
  5. 登録された債権を翌月まとめて請求する (未確定債権は請求対象にしない)

これまでのオーソリ時請求は、未確定債権の段階を省略していきなり債権を登録しているだけという整理になり、後方互換性の保たれた拡張になりました。

メルカードによる決済が発生するまではシステム上の変化が外から見えないため、無停止で改修内容を事前にデプロイしていきました。この決済のコア部分は数ヶ月程度で開発完了となりました。当初の見積もりより遥かに小さな開発スコープに収めることができ、これにより品質もより良いものになったと思います。

壊すのでも、拒絶するのでもなく、拡張する

今回のプロジェクトをまとめてみて、個人的に、似た事例として思い出した話があります。

例えば、プログラミング言語に新機能を入れるときの話です。画期的な新機能を入れたいが、このままでは構文上の後方互換性がなくなってしまう、どうしようか。
「メジャーバージョンアップをするから」「旧バージョンのサポートを打ち切るから」といった条件をつけた上で、破壊的変更を選ぶケースもあると思いますが、壊す変更は痛みを伴います。アップデートに追従することが難しく、利用者が離れてしまうことも考えられます。これまで使われていなかった記号や、統計的にほとんど利用されていない予約語を利用して新たな構文を足すことで、なるべく互換性を保つ努力がされることが多いのではないでしょうか。

あるいは、数学の負数や虚数の発明の話です。それまで1を足して0になる数は存在しなかったところ、それを「-1」の定義にしてしまう。それまで2乗して-1になる数は存在しなかったところ、それを虚数単位iの定義にしてしまう。説明できない事象があったとき、そんな計算はできない、ナンセンスだ、と否定するのが自然な反応です。しかし、一歩先に進んで定義として逆に取り込んでしまうことで、数学はより豊かなものになっていきました。

どうも、既存システムで受け入れがたい変更や矛盾が起きた時、新たな概念もしくは階層のようなものを差し込み、既存はその一種だった、と整理することでうまくいくことが多いようです。請求タイミングの切り替えプロジェクトでは、未確定債権の概念の発明がそれでした。破壊的変更として諦めず、受け入れられないとして拒絶もせず、概念を拡張する道を探せば、後方互換性が保たれたまま、仕組みとしてもより豊かなものにできるのではないか…。

今回の変更はエンジニアリングだけでなくリーガル観点など様々な方面で知恵を練った結果できた落とし所です。「小さな開発スコープに収まった」と書きましたが、決して簡単なものではなかったと思います。チーム一丸となって考えれば、光明は見えてくるものだと学びました。

明日のMerpay Advent Calendar 2022はnorifumiさんによる「メルカードの還元率管理の仕組み」です。お楽しみに!

  • X
  • Facebook
  • linkedin
  • このエントリーをはてなブックマークに追加