
2025年6月6日に開催された「JJUG Spring 2025」で、GMOペイメントゲートウェイ(以下、GMO-PG)のシステム本部 イプシロンサービス室に所属する國廣が、「サービスと共に歩んだ3年──Spring Bootで作る決済システムの安定稼働」をテーマに登壇しました。決済システムには、継続的な稼働とセキュリティの確保が求められます。本講演では、2022年にリリースされた決済インフラサービス「fincode byGMO」の開発・運用経験をもとに、Spring BootとAWSを活用した設定管理、暗号化、バッチ処理、非同期化・DB最適化の工夫を紹介。サービスの成長に伴う課題への向き合い方も、講演の書き起こしでお届けします。
【この記事でわかること】(クリックで開く)
- 24時間365日の稼働が求められる決済システムで、安定性とセキュリティを両立するための取り組み。
- プロパティファイル、AWS Parameter Store、DB設定テーブルによる設定値の管理。
- Spring Batch、Amazon EventBridge、AWS Step Functions、ECSを組み合わせたバッチ処理の運用。
- @Asyncによる非同期化やDB書き込み処理の見直しを通じた応答速度の確保。
- fincode byGMOのサービス成長とともに進めてきた設計・運用の改善。
fincode byGMOの開発に携わった3年間
![]()
こんにちは。GMOペイメントゲートウェイの 國廣 と申します。私は2022年に新卒で入社し、同年にリリースされた決済サービス「fincode byGMO」の開発チームに配属されました。配属当初は小規模な社内機能の開発を担当していて、開発を通してバックエンドはJava、フロントエンドはVue.jsの開発スキルを磨いていきました。その後、中規模・大規模案件のリードを務め、設計や要件整理、品質管理など、チーム全体を支える役割を担ってきました。リリース後の安定稼働やセキュリティ要件対応など、実装以外の部分でも経験を重ねています。今日はコードを深掘りするより、決済という止められないインフラをどのように安定かつセキュアに運用してきたかをご紹介いたします。
「fincode byGMO」は私の入社と同じ2022年にリリースされました。利用者がまだ少なかった頃から3年間、成長を共にしてきたという気持ちで開発・運用を続けています。決済システムを安定かつ安全に動かす難しさと向き合ってきた経験を、今日はできる限りお伝えします。
最初に決済システムとサービスの全体像をご紹介し、そのあとでSpring Bootを使ってどのように安定稼働を実現しているかを4つの観点から具体的にお話しします。その後にサービスと私自身がどのように成長してきたかを振り返り、最後にまとめてまいります。どうぞよろしくお願いします。
▶fincode byGMO サービスサイト: https://www.fincode.jp/
1. 決済システムに求められる安定稼働とセキュリティ
![]()
決済システムと聞いて、皆さんはどのようなイメージを持たれるでしょうか。「厳しそう」「止められなさそう」「セキュリティが大変そう」、そんな印象かもしれません。実際、決済は24時間365日稼働し続ける必要があり、停止するとお客様に損害を与える恐れがあります。設定ミスやプログラムバグがあれば即トラブルに直結します。加盟店様の商品セール期間などでアクセスが集中すると、予期しないボトルネックが発生することもあります。さらにクレジットカード情報を扱うため、国際的なセキュリティ基準 PCI DSS をはじめ、さまざまな要件を満たさなければなりません。
私が担当している決済システム「fincode byGMO」は、オンライン決済機能を導入したい事業者様向けの決済代行サービスです。決済機能を追加したい事業者様と、カード会社・コンビニ各社・各種Pay事業者との間に立ち、契約や審査、精算業務など、面倒な部分をまとめて引き受けるゲートウェイの役割を果たします。決済処理はすべてAPIで提供し、その基盤アプリケーションを Spring Boot で開発・運用しています。
![]()
上図の構成図をご覧ください。サービス全体はAWS上に構築しています。加盟店向けの決済APIから社内向け業務機能まで、バックエンドはすべてSpring Bootで実装しています。バッチ処理はAmazon EventBridgeとStep Functionsでジョブ管理し、安定運用を実現しています。詳細は後ほどお話しします。
2. Spring BootとAWSによる安定稼働の4つの工夫
2-1. 設定値の3段階管理と安全な環境切り替え
現場でサービスを運用していると、環境ごとの設定切り替えや機密情報の安全な取り扱いは避けて通れません。私たちは設定値を3段構えで管理しています。
![]()
- プロパティファイル :共通設定(タイムアウトなど環境に依存しない項目)と環境別設定(接続先URL、ログレベルなど)を分けて保持。
- AWS Parameter Store :DBのパスワードや暗号化キーなど重要度の高い設定値を保持。
- DBの設定テーブル :主に加盟店ごとに異なる設定値をDBで保持。
Spring Bootはプロパティ内で環境変数を参照できるため、ECSタスク定義の環境変数を切り替えるだけで設定を変更できます。コードと設定値を分離し、設定ミスのリスクを下げつつ、安全な切り替えを実現しています。
2-2. カード情報などの暗号化と安全性の確保
決済システムは個人情報やカード情報などセンシティブなデータを扱います。万が一漏えいしても内容が復元できないことが前提です。暗号化キーはAWS Parameter Store、初期化ベクトル(IV)はアプリ側に置き、保管場所を分けてリスクを低減しています。特にカード情報は、初期化ベクトルにユニークなキーを設定し、同じ値を暗号化しても毎回異なる暗号文になるよう強度を高めています。
2-3. Spring BatchとAWSによるバッチ処理の運用
![]()
日次・月次のバッチ処理(定期課金、加盟店精算など)は Spring Batch で実装しています。オンラインアプリとバッチアプリはどちらもJavaで実装しているので共通部分はライブラリ化して使いまわせるようにしています。
また、Spring Batchにはバッチの実行状態や履歴を管理するJobRepositoryという仕組みが標準でありますが、fincodeでは使っていません。独自に実行管理テーブルを定義し、このテーブルで管理を行えるように実装しています。
スケジュールやリトライはAWS Step FunctionsとEventBridgeに任せています。Step Functionsのワークフローは成功・失敗が色分け表示され、失敗箇所をピンポイントで再実行できます。
![]()
バッチはEventBridgeとStep FunctionsをトリガーにECSコンテナが起動する構成になっています。バッチ処理が終了すると、サーバーのリソースが解放されるため、コストを最小限に抑えられます。
2-4. 非同期処理とDB最適化による応答速度の確保
![]()
APIの実行履歴の記録など、レスポンスに直接関係しない処理は「@Async」で非同期化し、APIの応答速度を確保しています。さらにJPAの「save()」は内部的に存在確認のSELECTを実行するため、追記専用テーブルではINSERT専用メソッドを明示して無駄なSELECTを排除しました。これにより意図しない遅延やタイムアウトを抑制しています。
3. サービスの成長に合わせた設計改善と開発者の学び
入社当初はシステムの全体像すら見えず、設定値の意味を追うだけで精一杯でした。しかし設定周りを理解すると、Spring Bootの仕組みを通じて全体像が見えてきました。やがてオンライン処理の設計やパフォーマンス改善にも携わり、環境切り替えや暗号化、バッチ運用などの基本がサービスを支えていることを実感しました。
サービス開始当時は「fincode byGMO」の対応決済サービスがカード決済のみで、アクセスも少なかったものの、その後さまざまな決済サービスを追加し、アクセスも増加しました。処理遅延や運用課題が顕在化するたびに設計を見直し、Spring BootとAWSの機能を活かして安定稼働を実現してきました。今後さらに規模が大きくなっても安定して動く設計を目指し、技術理解とチーム視点を深めていきたいと考えています。
4. 決済インフラの安定稼働を支える取り組みのまとめ
![]()
複数環境の安全な設定管理、センシティブデータの暗号化、Spring BatchとAWSによるバッチ基盤、非同期化とDB最適化──これらの仕組みを組み合わせることで、「止められない決済インフラ」をSpring Bootで支えています。サービスと共に成長しながら、今後も安定稼働を追求していきます。
最後にご案内です。GMOペイメントゲートウェイではエンジニアを募集しています。本日の発表で興味を持っていただけた方は、採用特設サイトや会場ブースにぜひお立ち寄りください。ご清聴ありがとうございました。
質疑応答:設定管理・バッチ処理・障害対応の実際
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. 大規模障害は多くありませんが、規模に関わらずお客様に迷惑をかける点では同じです。復旧処理や再発防止策を考えるのは大変ですが、障害を次に生かす仕組み作りが重要だと学びました。
司会
時間になりましたので質疑応答はここまでです。 國廣 さん、ありがとうございました。
FAQ
よくある質問(FAQを開く)
fincode byGMOではSpring Bootをどのように活用していますか?
加盟店様向けの決済APIから社内向け業務機能まで、バックエンドをSpring Bootで実装しています。オンライン処理に加え、Spring Batchを使った日次・月次のバッチ処理にも活用しています。
決済システムの設定値はどのように管理していますか?
共通・環境別のプロパティファイル、AWS Parameter Store、DBの設定テーブルを使い分けています。コードと設定を分離し、環境ごとの切り替えや機密情報の管理に対応しています。
fincode byGMOのバッチ処理にはどのAWSサービスを使っていますか?
Amazon EventBridgeとAWS Step Functionsでスケジュールやリトライを管理し、ECSコンテナでバッチを実行しています。バッチ処理自体はSpring Batchで実装しています。
APIの応答速度を維持するためにどのような工夫をしていますか?
APIの応答に直接関係しない履歴記録などを@Asyncで非同期化しています。また、追記専用テーブルではINSERT専用メソッドを用意し、不要なSELECTの発生を抑えています。
サービスの成長に伴うバッチ処理の負荷増大にはどう対応していますか?
講演時点では、並列処理の導入、DBの読み書き処理の見直し、ECSタスクやDBのスペック増強などで対応していると説明しています。
▶ 関連採用情報 : エンジニア・デザイナーの求人一覧を見る
(by あなたのとなりに、決済を 編集チーム)
※本コンテンツ内容の著作権は、GMOペイメントゲートウェイ株式会社に属します。