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.8k
Other Decks in Technology
See All in Technology
Amplifyとゼロからはじめた AIコーディング 成果と展望
mkdev10
1
310
産業機械をElixirで制御する
kikuyuta
0
170
Azure AI Foundryでマルチエージェントワークフロー
seosoft
0
110
Create a Rails8 responsive app with Gemini and RubyLLM
palladius
0
130
QAはソフトウェアエンジニアリングを学んで実践するのが大事なの
ymty
1
470
DB 醬,嗨!哪泥嘎斯基?
line_developers_tw
PRO
0
260
OAuth/OpenID Connectで実現するMCPのセキュアなアクセス管理
kuralab
2
400
OpenTelemetry Collector internals
ymotongpoo
5
560
上長や社内ステークホルダーに対する解像度を上げて、より良い補完関係を築く方法 / How-to-increase-resolution-and-build-better-complementary-relationships-with-your-bosses-and-internal-stakeholders
madoxten
13
7.8k
工具人的一生: 開發很多 AI 工具讓我 慵懶過一生
line_developers_tw
PRO
0
250
DenoとJSRで実現する最速MCPサーバー開発記 / Building MCP Servers at Lightning Speed with Deno and JSR
yamanoku
1
120
“プロダクトを好きになれるか“も QAエンジニア転職の大事な判断基準だと思ったの
tomodakengo
0
200
Featured
See All Featured
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
16k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
31
2.4k
Music & Morning Musume
bryan
46
6.6k
Done Done
chrislema
184
16k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
16
930
Art, The Web, and Tiny UX
lynnandtonic
299
21k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
BBQ
matthewcrist
89
9.7k
StorybookのUI Testing Handbookを読んだ
zakiyama
30
5.8k
Rebuilding a faster, lazier Slack
samanthasiow
81
9k
ピンチをチャンスに:未来をつくるプロダクトロードマップ #pmconf2020
aki_iinuma
123
52k
YesSQL, Process and Tooling at Scale
rocio
172
14k
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