Otoku Revolution ~ 楽しい自動値引き体験の裏側

はじめに

こんにちは。メルペイの @yutaro です。
「Merpay & Mercoin Tech Openness Month 2026」17日目として、メルペイの決済をもっと楽しく、繰り返し使いたくなる体験にするための取り組み(Otoku Revolution)について紹介します。

私は普段、Payment Platform の Balance Team で、メルペイ残高やポイントの状態管理、債権管理、会計連携、法定帳簿(法律上必要な帳簿)等の開発・運用をおこなっています。

この記事でシェアしたいのは、新鮮な体験を作るときほど、早い段階で「決済では何が起きるか」「返金や失効ではどう扱うか」「お金の流れはどうなるか」のような具体的な部分のイメージも煮詰めておくと、実装も追加施策も速く進められる、という実例です。

Otoku Revolution とは

Otoku Revolution は、一言でいうと「決済するほど次の決済がおトクになる」体験を、メルペイの既存の決済基盤の上で実現するプロジェクトです。

実際の施策は、コード決済するたびにスタンプが貯まり、3回決済すると値引き特典を受け取り、次回決済時に自動で値引きされる新しい還元プログラムになりました。


画面イメージ1

画面イメージ2

(実際の決済後の画面)

決済する、スタンプがたまる、値引き特典を受け取る、受け取った特典が次回の決済で自動的に使われる。というような流れで、クーポンを選んだり、後日ポイントを受け取ったりするのではなく、次の決済で自然におトクになる体験を目指しました。

2026年5月中旬から、メルペイをご利用のお客さまの約半数を対象に試験的な導入を進めています。

決済基盤の上でこの体験(即時値引き)を作るには、キャンペーン条件、値引きを実現するリワード、決済処理、履歴、会計上の扱いを矛盾なくつなぐ必要があります。

構想初期には、周辺リポジトリをすべてcloneし、Claude Codeに読ませながら、関係しそうなサービスとデータの流れを図に起こしていました。
次のスクリーンショットは、そのときの初期アーキテクチャ図です。細部はその後整理していますが、議論のたたき台としては十分に現実に近く、どのサービスで何を扱うべきかを早い段階でそろえる助けになりました。

ここからは、この還元プログラムを実現するために値引きポイント DISCOUNT_POINT をなぜ選んだのかを紹介します。


画面イメージ1

画面イメージ2

なぜ DISCOUNT_POINT を作ったのか

最初の大きな判断は、この特典をどのような形で実現するかでした。

検討した選択肢は、大きく3つありました。

  • ポイントバック: 既存のポイント付与の仕組みで実現しやすい。一方、即時ではなく後日ポイントを受け取る体験になる
  • クーポン: 特典として理解しやすい。一方、お客さまが選んで使うものになりやすく、既存の仕組みで即時反映を実現しにくかった
  • 値引き専用の残高(DISCOUNT POINT): 完全に新しい即時値引き専用の残高を作成し、対象の決済で最優先で使われるようにする

3つ比較した結果、即時値引きという体験を実現するためには、値引き専用の残高を作成する必要があるという判断になりました。

これは通常のポイントとは別の、値引きにだけ使えるお客さま向けの残高です。
内部的には残高のように扱えますが、お客さま向けにはすぐに次の決済に使えるクーポンのように振る舞います。次回の決済の値引きを実現したいので、決済金額が値引き額より小さい場合は、使い切れなかった分を失効させます。

DISCOUNT_POINTをスピーディーに実装するために役立ったのが、約1年半前から稼働している新しい残高管理システムである Balance V2 です。
Balance V2 では、残高の種類を後から柔軟に追加できる設計になっており、種類ごとに使われ方や会計連携を宣言的に定義できます。また、残高の付与や消費、失効に伴う変動があった場合に自動で会計連携されるようになっています。
このプロジェクトではその汎用性を活かし、施策専用のサービスを立ち上げるのではなく、DISCOUNT_POINT という新しい残高の一種として即時値引き特典を扱う設計にしました。

結果的に、全く新しい種類のクーポンであるはずの即時値引き特典を、決済基盤上では残高の延長線上で扱い実装できるようになりました。

DISCOUNT_POINT の全体像

DISCOUNT_POINT は、決済完了後にスタンプが3回溜まっていれば付与されます。付与後、次の決済前に利用可能な残高として参照され、決済手段に最優先で使われる残高として組み込まれ、通常の残高やポイント・メルペイのクレジットより先に使われます。

例えば、DISCOUNT_POINTを100円分もっているお客さまが300円分の商品を購入しようとすると、100円分が優先的にDISCOUNT_POINTから消費され、他の残高等の決済手段から200円分が消費されます。
このように、お客さま目線では200円分の負担で300円分の決済ができた。という値引き体験を実現できています。

このような体験を実現するために、このプロジェクトではサービスの役割を分けました。冒頭の初期アーキテクチャ図は細かい実装寄りの図なので、ここでは大きく「決済前」「決済時」「決済後」の3つに整理しています。実際の構成にはさらに細かい処理や例外がありますが、大きな役割だけに絞ると次のようになります。括弧内は、社内で使っているサービス名です。

service 主な役割
特典付与サービス (santa-service) スタンプの管理、付与額の決定
支払い方法設定サービス (payment-config-service) お客さまの設定や状況ごとの決済手段を決定
決済サービス(payment-service) 渡された決済手段どおりに支払いを実施する
残高管理サービス(balance-service) DISCOUNT_POINT の残高管理、消費、失効、会計連携

このように役割を分けると、santa-serviceは条件判定、balance-serviceは残高の増減、payment-serviceは渡された内訳どおりに決済を成立させることに集中できます。

お客さまにはひとつの施策に見えるものを、裏側ではスタンプ、決済に使う残高やポイント、履歴表示、会計上の記録に分けて考えられるようになり、それぞれの影響範囲について議論や意思決定がしやすくなりました。

実際のキャンペーンの条件や例外の多くは、santa-serviceで扱っています。@hasegway さんの「メルペイのキャンペーン基盤をルールベース汎用システムに書き直し、Otoku Revolutionするまでの話」 では、このような複雑なキャンペーンをルール組み合わせとして扱えるようにした Rulebase 移行について紹介されています。

次の章から、付与、利用、返金・失効、会計 についての詳細をそれぞれ紹介していきます。

付与: 還元で決済を止めない

Otoku Revolution、は決済完了後のスタンプ更新から始まります。

決済が完了すると、payment-serviceから非同期のeventが発行されます。santa-serviceはそのeventを受け取り、キャンペーンの対象のユーザーかどうかを確認してスタンプの付与を行います。ここで、スタンプが3回分に到達した場合は特典額を決め、balance-serviceに DISCOUNT_POINTの付与を行います。

ここで大事だったのは、スタンプ更新や値引きポイント付与を、決済そのものの成功条件にしないことです。

この還元プログラムの体験としては「決済後に即時でスタンプ・DISCOUNT_POINTの付与が行われる」が理想です。一方で、スタンプ更新やDISCOUNT_POINTの付与までを決済処理の中で完了させようとすると、キャンペーン側の遅延や障害が決済成功率に影響してしまいます。

決済基盤では、決済そのものをキャンペーン側の都合で不安定にしないことが最優先です。そのため、決済完了後にあとからスタンプを更新し、条件達成時にDISCOUNT_POINTを付与する設計にしました。

利用: 最優先で使われるポイントとしてのDISCOUNT POINT

付与された DISCOUNT_POINT は、次の決済で自動的に使われます。

ここで設計上大事だったのは、payment-serviceの役割を広げすぎないことです。
直感的には、payment-serviceが残高を見て「DISCOUNT_POINTがあるなら使う」と決める設計も考えられます。この形にすると、値引きの判断を1か所に集めやすいという良さがあります。

しかし、payment-serviceは単に外部向けの決済を担当しているだけではなく、社内のありとあらゆるお金の流れに関与しており、できるだけDISCOUNT_POINTに関係する専用のロジックは入りこまないようにしたいです。

そのため、決済前に支払い方法と金額を組み立てる payment-config-serviceが、支払い方法とDISCOUNT_POINT残高を見て、DISCOUNT_POINTを優先的に消費する決済内訳を作る設計にしました。payment-serviceはその内訳どおりに決済を進め、残高管理サービスが実際の残高消費を担います。

このような責務分担にすることで、コード決済等の決済手段ごとに値引きを適用するかどうかのルールを段階的決めることができるようにもなります。

返金・失効: クーポンとして振る舞うように設計

DISCOUNT_POINT は、通常のポイントのように貯め続けるものではなく、「スタンプがたまった次の決済で使える特典」です。

返金時や、決済金額が値引きポイントより小さいときも、不正対策やユーザービリティの観点でクーポンに近い挙動になるようにしました。

返金・失効では、主に次のように扱います。

  • 返金時に、スタンプの数は戻さない
  • 返金時に、使用済みの値引きポイントは再付与しない
  • 決済金額より値引きポイントが大きい場合、使い切れなかった分は失効させる

例えば、1,000円の決済で100円分の値引きポイントを使ったあとに返金された場合でも、通常の返金処理の中でスタンプや値引きポイントの状態までは巻き戻しません。巻き戻す設計にすると、「再付与した値引きポイントをもう一度使えるのか」「スタンプも取り消すのか」「会計上は何を取り消すのか」を追加で扱う必要があり、スタンプカードとしてのルールも複雑になります。

また、500円分の値引きポイントを持っているお客さまが300円の決済をした場合は、300円分を消費し、残り200円は失効します。DISCOUNT_POINT は残高として管理しつつ、次の決済だけで使われる特典に近い性質を持たせたかったためです。

このように整理することで、クーポンのような挙動のポイントであるDISCOUNT_POINTを実現しています。

会計: お金の流れを先にデザイン

DISCOUNT_POINT を新しい残高として扱う以上、アプリに表示して決済で使えるだけでは不十分です。付与された時点、使われた時点、失効した時点で会計上どう記録されるのかを説明できないまま進めると、後から設計を大きく見直すことになります。

そこで、まだ設計が固まりきる前に、プロジェクト全体の MoneyFlow、つまりお金がどう動くかを図にして、経理チームに相談しに行きました。

この図では、DISCOUNT_POINT の付与・消費・失効が、会計上の記録につながることを描いています。全体ではなく一部だけを載せています。このプロジェクトでは早い段階からお金の流れを具体的な図にして議論していました。

実装が本格化する前に、お金の流れと会計上の意味を一緒に確認できたことは、後から振り返っても大きかったと思います。MoneyFlow そのものについては、@komatsu さんの 「決済プラットフォームと経理を繋ぐ MoneyFlow」に詳しくまとまっています。

Otoku Revolutionではこのように整理したうえで、DISCOUNT_POINTの付与・消費・失効をbalance-serviceで扱い、会計連携までつなげて、会計レポートを作成できるようにしました。

リリース後、事前付与施策で効いた設計

リリース後には、多くのお客さまにこの還元プログラムを知ってもらうための施策も必要になりました。

そこで、対象のお客さまにあらかじめDISCOUNT_POINTを付与する施策を追加で開始することにしました。キャンペーン開始直後のタイトなスケジュールの中、スピーディーに付与実施までもっていくことができました。

このような柔軟な追加施策を実施できたのは、単に実装が早かったからではありません。DISCOUNT_POINT が残高管理サービスで管理される残高として扱われ、付与、消費、失効、会計上の記録の意味がすでに整理されていたことが効きました。

追加施策でも、付与する残高の種類、決済時の使われ方、使い切れなかった分の扱い、履歴での見え方、会計上の記録を新しく考え直す必要はありませんでした。「誰に、いくら、どの条件で付与するか」に集中できたことが、速度を出せたポイントかなと思います。

振り返り

Otoku Revolutionでは、最初から「値引きポイントをどう見せるか」だけでなく、「決済では何が起きるか」「返金ではどう扱うか」「会計ではどう記録するか」をまとめて確認できたことが大きかったです。そのおかげで、DISCOUNT_POINT を残高として付与し、決済で優先的に使うといアイディアで最後まで手戻りなくリリースまで実現できました。

個人的には、プロジェクトの構想段階から体験面の議論に混ぜてもらいながら、エンジニアとして実現性や整理が必要になりそうな点を少し先回りして確認しにいけたことは、私にとっても学びの多い進め方でした。体験を決めたあとに会計や法務、返金のルールに合わせて作り直すのではなく、最初からそれらを含めて設計できたことは大きかったと思います。普段 Balance Team で扱っている残高・会計・帳簿の知識が、お客さまに届く体験につながったことも印象に残っています。

決済基盤の仕事をしていると正しさや安全性を守る場面が多いですが、その知識の延長線上で新しい体験を実現できたことは、素直にうれしかったです。

次の記事は @kobaryo さんの「任意の単位での債権の色付けと与信の分割を実現する Debt View」です。私がこのプロジェクトに多くの時間を割いていた間、Balance Team の日々の業務を @kobaryo さんに大きく支えてもらっていました。次の記事もぜひ読んでみてください。

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