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
140
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.6k
Other Decks in Technology
See All in Technology
AWS re:Invent 2024 recap in 20min / JAWSUG 千葉 2025.1.14
shimy
1
110
Mocking your codebase without cursing it
gaqzi
0
110
新卒1年目、はじめてのアプリケーションサーバー【IBM WebSphere Liberty】
ktgrryt
0
160
Bring Your Own Container: When Containers Turn the Key to EDR Bypass/byoc-avtokyo2024
tkmru
0
890
2024AWSで個人的にアツかったアップデート
nagisa53
1
110
DMMブックスへのTipKit導入
ttyi2
1
130
「人物ごとのアルバム」の精度改善の軌跡/Improving accuracy of albums by person
mixi_engineers
PRO
2
150
0→1事業こそPMは営業すべし / pmconf #落選お披露目 / PM should do sales in zero to one
roki_n_
PRO
1
2.4k
商品レコメンドでのexplicit negative feedbackの活用
alpicola
2
470
Kotlin Multiplatformのポテンシャル
recruitengineers
PRO
2
160
メールヘッダーを見てみよう
hinono
0
140
やっちゃえ誤自宅Nutanix
yukiafronia
0
240
Featured
See All Featured
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.4k
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
251
21k
Art, The Web, and Tiny UX
lynnandtonic
298
20k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
33
2k
Six Lessons from altMBA
skipperchong
27
3.6k
jQuery: Nuts, Bolts and Bling
dougneiner
63
7.6k
How to Think Like a Performance Engineer
csswizardry
22
1.3k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Fantastic passwords and where to find them - at NoRuKo
philnash
50
3k
A designer walks into a library…
pauljervisheath
205
24k
Learning to Love Humans: Emotional Interface Design
aarron
274
40k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
507
140k
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