CAMPFIREで毎月数億円の流通の一端を支える送金自動化システムの構築

## はじめに
こんにちは。CAMPFIRE開発部Dチームのishimizuです。普段は経理周りやバックエンドのシステム開発やパートナーシステムの開発などを担当しています。

 今年は夏から秋にかけてCAMPFIREのビジネスモデルの根幹の一端を支える送金自動化システムを構築しましたのでその話を書こうと思います。
 プロトタイピングモデルの開発手法を取り入れたことにより開発プロセスの迅速化ができましたのでその辺の取組についてもまとめます。

## CAMPFIREのビジネスモデルとは
 CAMPFIREのビジネスモデルの大元と言える基本はお金の流れに着目するとプロジェクトの支援者からお金を集めてプロジェクトの起案者にお金を送るというものです。システム的な観点ではユーザ管理などを除いて大きく3つの機能に区分けできます。
①プロジェクトの作成と管理の機能
②プロジェクトへの支援の決済機能（クレジットカード決済やコンビニ支払など）
③プロジェクト起案者への募集金額の送金機能（今回作成した送金自動化システム）
です。
②がお金を集める部分に当たり、③がお金を送る部分に当たります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/851627/97fe1347-6f12-d74d-d758-a2d0bd2321ef.png)

## 送金自動化システム導入以前の問題点との導入の経緯
 そのうちお金を集める②の部分については私達が入社する以前から完全にシステム化されていましたが、一方で起案者にお金を送る③の部分については管理画面からは、振込先と金額をリスト化したCSVファイルを生成する機能があるぐらいで後は弊社の有能な経理チームがEXCELなどのツールで管理して送金データを作って銀行に指示出しをしている状態でした。

 その為人為的な不正が入り込む余地が拭えないことや、振込完了の通知や振込できなかった場合の口座変更を促す通知などの送信は別途CSVファイルを作成し管理画面でアップロードを行って同期する手段を取っていました。

 毎月数十件の規模のプロジェクト数であればそれでも間に合っていたのですが、想像が付くように毎月数千件近くのプロジェクトが達成し、合計数億から数十億円の送金規模になれば経理の負担は毎月とんでもない労力になります。

## 導入に伴うハードル
しかしここを自動化するにはいくつかのハードルがあり一般の銀行は送金APIを持っていなかったり、一般の送金サービスでも百万円単位の送金は受け付けられなかったりすることが多く、なかなかシステムによる自動化は難しい分野でした。

弊社の営業チームやPMの交渉のお陰でGMO送金サービスを使用することで送金の自動化システムが実現できることがわかりました。

## 先行してリリースされた2つのシステム
今回の私が作成した送金自動化システムの前提には先行して構築された2つの別のシステムがありました。口座バージョニングシステム（口座の承認機構と編集履歴の管理）と組戻し管理表システム（振込できなかった場合の口座変更依頼を通知したり変更ステータスの管理）です。それぞれの機能について軽く説明いたします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/851627/b9732f1b-c6e2-2ec7-3a35-5a48850a9932.png)


## 口座バージョニングシステム（2022年7月ごろ）
 こちらは不正送金を防ぐ為に作られたシステムで送金先の口座については必ずプロジェクトの担当者が承認して変更があればその履歴を残すようにしたものです。これにより口座データは弊社システムでは持たずに送金サービス側のデータベースにのみ登録するようになり、また修正の履歴を必ず持つようになりましたので不正に口座情報を書換えることが構造的にできないようになりました。
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/851627/3974c1e8-25e9-9c34-f70f-326dd510b811.png)

## 組戻し管理システム（2019年9月ごろ）
WEBサービスでお金を送金するサービスには必ずついて回る問題で口座が間違えていたり銀行支店の統廃合などで振込ができなかった場合に起案者に通知したり編集の状況のステータスを管理したりします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/851627/816ca0a4-e20b-f24e-60bf-a56596b31ff9.png)

* 送金結果の同期上の問題点
振込失敗や成功の情報は銀行から送られてくるのですがもちろんプロジェクトID等は記載されません。振込失敗プロジェクトについて、自動的に組戻し管理システムに登録されるわけはなく経理チームが口座名義などからプロジェクトIDを割り出したうえでリスト化して管理画面でアップロードすることで通知を行っていました。ここは完全に手動作業なのでミスも発生しやすく口座の変更周りでの不正の入り込む余地があり、早急に対処したい部分でもありました。

## 送金自動化システムの開発開始と想定された見積工数(8月頃)
 以上のように色々な問題がありながら送金自動化システムの実現には時間がかかって停滞しておりました。原因としては送金APIを触るのでこちらだけで工数の大きさを見積もる事が難しかった（自分も6人月程度はかかると想定していました）、後はお金周りなのでみんなやりたがらなかったのもあるかと思います。
しかしマネージャーから９月中に完成するように指示されましたので８月頃からAPIの仕様を調査しはじめました。

## テスト用のAPIを作成する（8月中旬）
手始めにテスト環境で動くモデルのAPI通信を２日ほどで必要となるものを全部作りました。これはGMOさんの送金APIが非常にわかりやすくシンプルに作られていたことも大きいと思います。送金周りなので単体テストなどもかなり細かく書いたので実装開始後１週間程度でモデルとDB設計を終わらせることができました。これが思いのほかスムーズに行ったので本格的な開発に舵を取ることができたのも大きかったと思います。
[参考github](https://gist.github.com/jagdeepsingh/e6fa5ff6d611c961e6ad7965b710b393)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/851627/83090e15-d756-eb47-4839-536f2e1999c6.png)

## デモ環境でのプロトタイプ作成（8月下旬9月上旬）
 ishimizuがこの数年取り組んでいる開発迅速化の手法としてプロトタイピング開発の手法を取り入れてスパイラル開発を進める開発手法を今回は取りました。これは細かい設計部分は極力事前にはせず、画面設計ベースで必要最小限のテーブル項目から始めシステムの使用者（今回の場合は経理とPM）の確認できる環境を先に用意し、そこから足りない機能を肉付けして実装していく手法です。
 プロトタイプ開発の良いところは開発者もPMも同じ画面を見てあるべき仕様の姿や不具合の解決した状態を想像しやすい点だと思います。事前にすべての画面仕様を想像で用意するのは熟練のPMでもなかなか難しい（手間がかかる）ので早めに画面を共有するのは重要なプロセスだと思います。
 
#### デモ環境
 CAMPFIRE開発部では開発レーンが常に複数並列で動いていることもあり、動作確認環境としてQA環境と呼ばれる本番と同じ構成のAWSインスタンスを持ったテスト環境（インスタンスクラスは相応の低い性能のものです）を簡単に作れるコマンドがあります。もちろん実際のAWSインスタンスを立てるわけですから時間もお金もかかりますが、それでもPMや経理の担当者が確認できる環境を気軽に用意できるのは弊社の開発環境の大きな利点の一つだと思っています。
 今回はこのQA環境をデモ環境として開発当初のかなり早い段階で立ち上げてバグ込みの状態でビューとコントローラの基本の実装を２週間ほどで終わらせ、社内の関係メンバーで確認できるようにしました。バグ対応もありますが各ボタンの挙動など仕様が曖昧だった点も実際の画面を見ながら検討できたので効果は大きいと思います。

## バグ対応・DB設計の見直し・日時バッチの作成（9月中旬下旬）
 プロトタイピング開発なのでデモ環境に不具合が含まれることは容認した上で進めました。日々PMから上がってくるバグ対応と必要になったDB項目の追加、同時に送金APIと既存の機能を繋ぎこむ日時バッチの作成なども並行して行いました。
 今回作成したバッチは次の２つです。
* 予約送金の実行バッチ
  GMO送金APIでは送金先の銀行によって送金指示を出したタイミングと実際に送金されるタイミングが微妙に異なります。そのため今回構築したシステムでは送金情報テーブルに送金予約日という概念を待たせることでバッチの実行時刻にいま送金指示を出せばいつ着金するのかを予測して送金の実行のタイミングを図れるような機能を入れました。祝日や銀行営業日の仕様も考慮した計算ロジックを組み込むのに苦労しました。
 この時送金指示や、予約状況の分岐に使われる銀行口座情報は上述の口座バージョニング機能を通して作成され社員によって承認されたものに限られます。口座情報は起案者自ら入力したものであると保証され、不正がないことを最低一人のキュレータが承認したものになり不正が入り込む余地はありえません。

* 送金指示中のものの結果取得バッチ
  送金結果が送金成功か失敗かをバッチで検知し同期します。送金成功なら自動的に起案者に送金成功のメール送信をし、失敗なら組戻し管理表に登録した上、起案者に口座の変更を促す通知が送信されます。

これらの作業をさらに2週間ほどかけて実現し、9月中にほぼ完成させることができました。

## テストの作成（10月上旬）
 送金周りなので単体テストだけでなく結合テストもコードレベルでかなり細かく書きました。10月中旬の早期振込申請での本番運用開始のスケジュールが決められ、それに向けて準備を進めました。

 ## 初回の実送金実行（10月中旬）
 やはりこれだけの大きなお金を扱う仕事では緊張がつきものです。初回の実送金実行はテスト通りスムーズに実施され十数件の起案者への送金が実行されました。同時期にテスト用の口座への入金も確認することができました。この時は合計金額が数百万円で件数も10件程度であったと記憶しています。件数が桁違いとはいえ、これで月末の送金にも実運用可能なシステムであると確信することができました。

## 10月末の数百プロジェクトの合計数億円の送金実行（10月31日）
  10月31日は奇しくも私の誕生日の前日でした。長いエンジニア人生で億単位のお金を扱う仕事などしたことがなく、これまでソシャゲーやECサイトの開発、CAMPFIREに事業譲渡されたFAAVOの開発運用をしていた時でも億単位のお金を扱う仕事など経験がありませんでした。冷静に考えればそのような経験のあるエンジニアなんてあまり多くないのではないか。「自分の書いたコードを数億円のお金が流れる」そんな経験に携われる機会なんてそうそうないのではないか。と震えながらその日を迎えました。
 この時点では送金結果の社内向けの通知機能がまだなかったので結果の同期バッチの実行結果を自分でSQLを書いてモニタリングして合計金額を共有していました。
 結果が1円でもずれていれば今までの苦労が全て水の泡になるとドキドキしながらすべての結果取得が終わって17時半頃送金成功分と送金失敗分の合算が予定していた数字と一致した時は一気に肩の荷が下り、リモートワークの自室で一人「ヨッシャ」と大声を上げました。（この「送金失敗」は不具合による失敗ではなく正常系の振込不可口座の検出の意味です）
 こういう時にすぐに仲間と打ち上げに行ったりできないのがリモートワークのデメリットですね。（後日開発メンバーと経理やPMのメンバーと渋谷でささやかな打ち上げ会を開きました）
 結果大きな問題はなく、気持ちよく誕生日を迎えることができました。今年は誕生日当日は休めなかったので翌週にお休みいただいて平日に上野のモネ展とキュビズム展をのんびり回ってきました
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/851627/df3dcecc-a2fb-b1a9-ef3b-6a60c1f7a7d8.png)


 ## 最後に
  その後、この送金自動化システムは11月の送金も正常に動くことができ順調に機能改善を重ねより堅牢で安全なシステムへと進化を続けています。
  
  冒頭に「CAMPFIREのビジネスモデルの一端を担う」と書いたのはこの機能により今後もしCAMPFIREの流通規模が何倍にも大きく成長して毎月数百億円以上の規模になったとしてもこの送金システムがあればきっと支払を捌けるであろうと確信しています。弊社のビジネスモデル上のボトルネックを一つ解消できたという意味で今後の大きな飛躍の礎になったと言えると確信しています。
  
# ITの力で1円でも多く必要なところに必要なお金が巡る社会を実現するために私達にできることはきっとまだまだあるはずだ！

 今年は年始には想像もしてなかったような大きな仕事を成し遂げられることができ、一エンジニアとしても稀有な経験をすることができました。

今回この短期間で想定工数よりも大幅に短く大きな成果が出せたと自分が考える背景は、過去の実装の果実をうまく取り入れられたことと適した開発手法を取り入れたこと、リモートワークでも安心して働ける開発環境、開発に集中できるようにタスクの管理ができていたこと、その全てが今回の実装に生かされたと思っています。あと全社的に導入している[github copilot](https://docs.github.com/ja/copilot/using-github-copilot/getting-started-with-github-copilot)にもかなり助けられました。

CAMPFIREでは開発メンバーの募集を随時行っています。本当に働きやすいやりがいのある仕事のできる会社だと思いますので私達と一緒に働きたいという方はぜひ下記のリンクから応募して下さい。
https://campfire.co.jp/careers/