Powered by

サービスと共に歩んだ3年──Spring Bootで作る決済システムの安定稼働

article-0166_top.jpg

2025年6月6日にJJUG Spring 2025が開催されました。本記事では、当日登壇したシステム本部 イプシロンサービス室の国廣の「サービスと共に歩んだ3年──Spring Bootで作る決済システムの安定稼働」を書き起こし記事にてご紹介します。

自己紹介

article-0166_thumb01.jpg

こんにちは。GMOペイメントゲートウェイの国廣と申します。私は2022年に新卒で入社し、同年にリリースされた決済サービス「fincode byGMO」の開発チームに配属されました。配属当初は小規模な社内機能の開発を担当していて、開発を通してバックエンドはJava、フロントエンドはVue.jsの開発スキルを磨いていきました。その後、中規模・大規模案件のリードを務め、設計や要件整理、品質管理など、チーム全体を支える役割を担ってきました。リリース後の安定稼働やセキュリティ要件対応など、実装以外の部分でも経験を重ねています。今日はコードを深掘りするより、決済という止められないインフラをどのように安定かつセキュアに運用してきたかをご紹介いたします。

「fincode byGMO」は私の入社と同じ2022年にリリースされました。利用者がまだ少なかった頃から3年間、成長を共にしてきたという気持ちで開発・運用を続けています。決済システムを安定かつ安全に動かす難しさと向き合ってきた経験を、今日はできる限りお伝えします。

最初に決済システムとサービスの全体像をご紹介し、そのあとでSpring Bootを使ってどのように安定稼働を実現しているかを4つの観点から具体的にお話しします。その後にサービスと私自身がどのように成長してきたかを振り返り、最後にまとめてまいります。どうぞよろしくお願いします。

▶fincode byGMO サービスサイト:https://www.fincode.jp/

1. 止められない決済システムの現場

article-0166_thumb02.jpg

決済システムと聞いて、皆さんはどのようなイメージを持たれるでしょうか。「厳しそう」「止められなさそう」「セキュリティが大変そう」、そんな印象かもしれません。実際、決済は24時間365日稼働し続ける必要があり、停止するとお客様に損害を与える恐れがあります。設定ミスやプログラムバグがあれば即トラブルに直結します。加盟店様の商品セール期間などでアクセスが集中すると、予期しないボトルネックが発生することもあります。さらにクレジットカード情報を扱うため、国際的なセキュリティ基準 PCI DSS をはじめ、さまざまな要件を満たさなければなりません。

私が担当している決済システム「fincode byGMO」は、オンライン決済機能を導入したい事業者様向けの決済代行サービスです。決済機能を追加したい事業者様と、カード会社・コンビニ各社・各種Pay事業者との間に立ち、契約や審査、精算業務など、面倒な部分をまとめて引き受けるゲートウェイの役割を果たします。決済処理はすべてAPIで提供し、その基盤アプリケーションを Spring Boot で開発・運用しています。

article-0166_thumb03.jpg

上図の構成図をご覧ください。サービス全体はAWS上に構築しています。加盟店向けの決済APIから社内向け業務機能まで、バックエンドはすべてSpring Bootで実装しています。バッチ処理はAmazon EventBridgeとStep Functionsでジョブ管理し、安定運用を実現しています。詳細は後ほどお話しします。

2. Spring Bootで支える安定稼働の工夫

2-1. 設定の一元管理と安全な切り替え

現場でサービスを運用していると、環境ごとの設定切り替えや機密情報の安全な取り扱いは避けて通れません。私たちは設定値を3段構えで管理しています。

article-0166_thumb04.jpg

  • プロパティファイル:共通設定(タイムアウトなど環境に依存しない項目)と環境別設定(接続先URL、ログレベルなど)を分けて保持。
  • AWS Parameter Store:DBのパスワードや暗号化キーなど重要度の高い設定値を保持。
  • DBの設定テーブル:主に加盟店ごとに異なる設定値をDBで保持。

Spring Bootはプロパティ内で環境変数を参照できるため、ECSタスク定義の環境変数を切り替えるだけで設定を変更できます。コードと設定値を分離し、設定ミスのリスクを下げつつ、安全な切り替えを実現しています。

2-2. 暗号化と安全性

決済システムは個人情報やカード情報などセンシティブなデータを扱います。万が一漏えいしても内容が復元できないことが前提です。暗号化キーはAWS Parameter Store、初期化ベクトル(IV)はアプリ側に置き、保管場所を分けてリスクを低減しています。特にカード情報は、初期化ベクトルにユニークなキーを設定し、同じ値を暗号化しても毎回異なる暗号文になるよう強度を高めています。

2-3. バッチ処理の設計と運用

article-0166_thumb05.jpg

日次・月次のバッチ処理(定期課金、加盟店精算など)は Spring Batch で実装しています。オンラインアプリとバッチアプリはどちらもJavaで実装しているので共通部分はライブラリ化して使いまわせるようにしています。

また、Spring Batchにはバッチの実行状態や履歴を管理するJobRepositoryという仕組みが標準でありますが、fincodeでは使っていません。独自に実行管理テーブルを定義し、このテーブルで管理を行えるように実装しています。

スケジュールやリトライはAWS Step FunctionsとEventBridgeに任せています。Step Functionsのワークフローは成功・失敗が色分け表示され、失敗箇所をピンポイントで再実行できます。

article-0166_thumb06.jpg

バッチはEventBridgeとStep FunctionsをトリガーにECSコンテナが起動する構成になっています。バッチ処理が終了すると、サーバーのリソースが解放されるため、コストを最小限に抑えられます。

2-4. 処理の分離と安定性

article-0166_thumb07.jpg

APIの実行履歴の記録など、レスポンスに直接関係しない処理は「@Async」で非同期化し、APIの応答速度を確保しています。さらにJPAの「save()」は内部的に存在確認のSELECTを実行するため、追記専用テーブルではINSERT専用メソッドを明示して無駄なSELECTを排除しました。これにより意図しない遅延やタイムアウトを抑制しています。

3. サービスと自分自身の成長

入社当初はシステムの全体像すら見えず、設定値の意味を追うだけで精一杯でした。しかし設定周りを理解すると、Spring Bootの仕組みを通じて全体像が見えてきました。やがてオンライン処理の設計やパフォーマンス改善にも携わり、環境切り替えや暗号化、バッチ運用などの基本がサービスを支えていることを実感しました。

サービス開始当時は「fincode byGMO」の対応決済サービスがカード決済のみで、アクセスも少なかったものの、その後さまざまな決済サービスを追加し、アクセスも増加しました。処理遅延や運用課題が顕在化するたびに設計を見直し、Spring BootとAWSの機能を活かして安定稼働を実現してきました。今後さらに規模が大きくなっても安定して動く設計を目指し、技術理解とチーム視点を深めていきたいと考えています。

4. まとめ

article-0166_thumb08.jpg

複数環境の安全な設定管理、センシティブデータの暗号化、Spring BatchとAWSによるバッチ基盤、非同期化とDB最適化──これらの仕組みを組み合わせることで、「止められない決済インフラ」をSpring Bootで支えています。サービスと共に成長しながら、今後も安定稼働を追求していきます。

最後にご案内です。GMOペイメントゲートウェイではエンジニアを募集しています。本日の発表で興味を持っていただけた方は、採用特設サイトや会場ブースにぜひお立ち寄りください。ご清聴ありがとうございました。

QA セッション

Q1.同じ年次のメンバーがチームにいます。これまで勉強して役立ったことがあれば教えてください。
A1.入社時にJava研修で基礎を固め、その後はOJTを通じてJava、Vue.js、AWSのCloudFormationなどを触る機会が多かったです。特定の本より、実務で学ぶことが多かったですね。

Q2.設定を分けて管理しているとのことですが、運用で工夫していることはありますか。誤字で壊れないようにする仕組みなど。
A2.AWS Parameter Storeで設定を入力するときに不要な改行が入ると動かないことがあります。再確認のプロセスを設け、必ずレビューを通してからリリースしています。

Q3.当初数時間で終わっていたバッチが、3年経って一日以上かかるようになったことはありますか。対策があれば教えてください。
A3.一日を超えるバッチはまだありませんが、数時間だったものが五~六時間に伸びた例はあります。対処法は色々ありますが、並列処理の導入やDBの読み書きする処理の見直し、ECSタスクやDBのスペック増強などで対応しています。

Q4.カード番号をアプリケーション内でも暗号化したまま扱うとのことですが、PCI DSSの要件だからですか、それとも社内ポリシーですか。
A4.PCI DSSの要件と社内ポリシーの両方です。アプリ内でも平文で持たず、必要なときだけ復号しています。

Q5.JPAのsave()以外でDB書き込みを最適化した例はありますか。
A5.重たいバッチではJPAではなくJDBCやプロシージャを使い、一括で処理しています。大量の売上集計などはプロシージャで一気に処理し、一時間程度で終えられるようにしています。

Q6.3年間運用してきて障害はありましたか。対応で学んだことがあれば教えてください。
A6.大規模障害は多くありませんが、規模に関わらずお客様に迷惑をかける点では同じです。復旧処理や再発防止策を考えるのは大変ですが、障害を次に生かす仕組み作りが重要だと学びました。

司会
時間になりましたので質疑応答はここまでです。国廣さん、ありがとうございました。

(by あなたのとなりに、決済を 編集チーム)

※本コンテンツ内容の著作権は、GMOペイメントゲートウェイ株式会社に属します。

PAGETOP

Copyright (C) 1995 GMO Payment Gateway, Inc. All Rights Reserved.