Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Goで実装した UPSIDERの決済金額リミット機能
Search
Miki.M
August 04, 2022
Technology
0
180
Goで実装した UPSIDERの決済金額リミット機能
Event page:
https://upsider.connpass.com/event/254313/
Miki.M
August 04, 2022
Tweet
Share
More Decks by Miki.M
See All by Miki.M
Custom logging with slog Making Logging Fun Again!
masumomo
3
3.7k
Other Decks in Technology
See All in Technology
ドキュメント管理の理想と現実
kazuhe
3
310
Running JavaScript within Ruby
hmsk
3
430
AIコーディングの最前線 〜活用のコツと課題〜
pharma_x_tech
4
2.9k
ペアーズにおける評価ドリブンな AI Agent 開発のご紹介
fukubaka0825
7
1.9k
DjangoCon Europe 2025 Keynote - Django for Data Science
wsvincent
0
400
AI駆動で進化する開発プロセス ~クラスメソッドでの実践と成功事例~ / aidd-in-classmethod
tomoki10
1
800
AndroidアプリエンジニアもMCPを触ろう
kgmyshin
2
570
OPENLOGI Company Profile for engineer
hr01
1
25k
GraphQLを活用したリアーキテクチャに対応するSLI/Oの再設計
coconala_engineer
0
190
【Λ(らむだ)】最近のアプデ情報 / RPALT20250422
lambda
0
330
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
7
63k
持続可能なドキュメント運用のリアル: 1年間の成果とこれから
akitok_
1
270
Featured
See All Featured
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
30
2k
Statistics for Hackers
jakevdp
798
220k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
26k
YesSQL, Process and Tooling at Scale
rocio
172
14k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
47
5.4k
A Tale of Four Properties
chriscoyier
158
23k
How GitHub (no longer) Works
holman
314
140k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
41
2.3k
Gamification - CAS2011
davidbonilla
81
5.3k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
227
22k
GraphQLの誤解/rethinking-graphql
sonatard
71
10k
Transcript
Goで実装した UPSIDERの決済金額リミット機能 株式会社 UPSIDER Miki Masumoto 1 Gopherは「Go」のマスコットキャラクター、原作者は Renee French
さんです。以降のページも同様。
自己紹介 • Masumoto Miki • 2022/1からUPSIDERにJOIN ◦ Sler→フリーランス→UPSIDER • Gopher歴は1年ほど
◦ JavaとJavaScript/TypeScriptをよく書いてました • 常にワーケーション中 2
UPSIDERについて • 成長企業向けの法人カード、支払いプラットフォームを提供 • ビジネスの「お金」を呼吸感覚まで自在に 3
Today’s goal 決済というクリティカルかつリアルタイム性が求め られるシステムで Goをどう活用しているのかを知ってもらうこと 4
目次 • 決済システムの概要 • 決済金額リミットを扱う機能の紹介 • 実装のポイントとGoのコードサンプル • Goで書いてよかったところ 5
カード決済の流れ 6 カード決済 システム 加盟店 オーソリ(承認要求) クリアリング(売上確定) ◯◯円で決済します
OK/NG ◯◯円請求します カード利用者
決済金額のリミット機能とは? 決済が飛んできた時にチェックされる金額上限 1.企業ごとの決済金額リミット 2.ユーザーごと1取引の決済金額リミット 3.ユーザーごとの月間決済金額リミット 毎月1日0時にリセット 4.ユーザーごとの日次決済金額リミット 毎日0時にリセット ユーザごとのリミットはユーザが任意で設定可能 7
決済金額リミット関連の処理たち • 決済金額のリミットを設定/解除する ◦ WEB画面からの操作によって呼ばれる • DBからのトータル決済額の読み込み・書き込み ◦ オーソリ・クリアリングなどが飛んできた時に呼ばれる •
トータル金額のリセット ◦ システム内部のバッチで呼ばれる 8
決済金額リミット関連のデータを扱うstruct 9
実装のポイント① 柔軟な金額リミット機能 10
実装のポイント① 柔軟な金額リミット機能 11 今後、もっと柔軟なリミット機能が欲しくなるかも • 週ごと/期ごとにリミットを持たせたい ... etc • 毎月20日/15日など間隔は同じで特定日や時間にリセットしたい
実装のポイント① 柔軟な金額リミット機能 12 💡新しいリミットのタイプを実装したい 👉次回のリセットのタイミングを計算するロジックだけ作れば実装できる
実装のポイント① 柔軟な金額リミット機能 13 👉次回リセット日時(NextResetAt)を変えることで実現できる 💡既存のリミット間隔で特定の日付・時間にリセットしたい • 20日にリセットされる月間リミット 7/1 8/1 9/1 リミットの設定をする
NextResetAt = 7/20 リセット処理が走る NextResetAt = 8/20 LastResetAt = 7/20 7/17 7/20 8/20
実装のポイント② 安全なトータル金額のリセット 14
実装のポイント② 安全なトータル金額のリセット 15 トータル金額リセット時の懸念 • リセット時刻にリセットする処理が遅延/失敗したら? • オーソリなどのリアルタイムで飛んでくる決済が同時に飛んできたら?
実装のポイント② 安全なトータル金額のリセット 16 💥 ケース1:リセット処理がまだなのにオーソリが飛んできてしまった 単純な、トータル金額を0円にするリセット処理ではなぜダメなのか 00:00:00 00:00:01 23:59:59 トータル金額 0時にリセットされる1日あたりの決済金額リミットの例
10000円 13000円 0円 オーソリ 3000円 リセット処理の実行 本当の トータル金額 10000円 3000円 3000円 合わない
実装のポイント② 安全なトータル金額のリセット 17 💥 ケース2:日付が変わる直前にオーソリが飛んできて処理中にリセットが走った 単純な、トータル金額を0円にするリセット処理ではなぜダメなのか 00:00:00 00:00:01 23:59:59 トータル金額 0時にリセットされる1日あたりの決済金額リミットの例
10000円 0円 4000円 オーソリ 4000円(処理に時間がかかった) リセット処理の実行 本当の トータル金額 10000円 0円 0円 合わない
実装のポイント② 安全なトータル金額のリセット 18 リセット前後のトータル金額も保持し、取得時刻から使われるべきトータル金額を判断する
実装のポイント② 安全なトータル金額のリセット 19 トータル金額リセット処理は0にするのではなく、次の断面にスライドさせる
Goのよかったところ① 20 • 言語仕様がシンプルで既存コードのキャッチアップしやすい 処理の流れと分岐が追いやすい
Goのよかったところ② 21 • 抽象化の機能が限られているので、個別ケースの扱いに困ったり過 度な抽象化による難読コードを書くリスクを避けられる 抽象化していないことで コードを追いやすい 似た振る舞いのstruct
Goのよかったところ③ 22 • エラーハンドルが必ず入るのでバグに気付きやすい いろんなところにif err If errを書きながら不具合に気づく Try catchのネストもない
Goのよかったところ④ 23 • ほぼ標準ライブラリで開発が可能(特にテストで嬉しい) テストカバレッジも自動で出してくれる 🎉 標準ライブラリで テーブル駆動テストが簡単に書ける
まとめ 24 📍 決済というクリティカルかつリアルタイム性が求められるシステムで Goをどう活用しているのか? 💪 考えることが多い要件や仕様でもGoのシンプルな言語仕様を生かし レビューしやすく見通しの良いコードを書くことによって 堅牢なシステム作りをしています
Thank you for listening. 25 We are hiring! @masumomo @m_miki0108
Goのつらかったところ 26 • ポインタ関連(うっかり ◦ た • 金額を扱うためのDecimalの扱いが面倒 ◦ DBは文字列で保持している
◦ 変換処理のエラーハンドルやコスト • コードが冗長になりがち
- 意味不明なところがないか - 間違ったこと言ってるところはないか - 用語の使い方や一貫性 - 自分はスライド作る中でゲシュタルト崩壊しており、正常な判断ができない - 余談:ledger.Calcの部分も色々作り込んだけど話してみたら時間オーバーで全部消した
😇 - なのでリミットに関連するusage serviceメイン - 余談2:ちょっとスライド寂しいところには Gopherを足そうと思う 気になるところ、フィードバックが欲しいところ 27
フィードバックメモするところ 28
UPSIDERの内部構成 29 Auth handler Clearing handler OrgAccount Reader/Writer 各メッセージの Handler
Services 各種ドメインの 読み書きServices UserAccount Reader/Writer Ledger Reader/Writer Usage Reader/Writer Shared DB VisaNet ・・・ ・・・ GatewayやRouter ・・・ Message Router
実装のポイント① 柔軟な金額リミット機能 30 👉NextResetAtを次のリセットしたい日時に設定することで実現できる 💡既存のリミット間隔で特定の日付・時間にリセットしたい • 通常の月間リミット(1日にリセットされる) 7/1 8/1 9/1 リミットの設定をする
NextResetAt = 8/1 リセット処理が走る NextResetAt = 9/1 LastResetAt = 8/1 7/17