์์ ํ ์ฒญ๊ตฌ ์ ๋ฐ์ดํธ๋ฅผ ์ํ ๋ฉฑ๋ฑ์ฑ ๊ฒฐ์ ์นํ ์ฒดํฌ๋ฆฌ์คํธ
์ด ์ฒดํฌ๋ฆฌ์คํธ๋ ์ด๋ฒคํธ ์ค๋ณต ์ ๊ฑฐ, ์ฌ์๋ ์ฒ๋ฆฌ, ์ธ๋ณด์ด์คยท๊ตฌ๋ ยท๊ถํ์ ์์ ํ๊ฒ ์ ๋ฐ์ดํธํ๋ ๋ฐฉ๋ฒ์ ์๋ดํฉ๋๋ค.

๊ฒฐ์ ์นํ ์ด ์ค๋ณต ์ ๋ฐ์ดํธ๋ฅผ ๋ง๋๋ ์ด์
๊ฒฐ์ ์นํ ์ ๊ฒฐ์ ์ ๊ณต์๊ฐ ๊ฒฐ์ ์ฑ๊ณต, ์ธ๋ณด์ด์ค ๊ฒฐ์ , ๊ตฌ๋ ๊ฐฑ์ , ํ๋ถ ๋ฑ ์ค์ํ ์ผ์ด ๋ฐ์ํ์ ๋ ๋ฐฑ์๋๋ก ๋ณด๋ด๋ ๋ฉ์์ง์ ๋๋ค. ์์ฝํ๋ฉด ์ ๊ณต์๊ฐ โ์ด๋ฐ ์ผ์ด ๋ฐ์ํ์ต๋๋ค. ๊ธฐ๋ก์ ์ ๋ฐ์ดํธํ์ธ์.โ๋ผ๊ณ ์๋ ค์ฃผ๋ ์ ์ ๋๋ค.
์ค๋ณต์ ์นํ ์ ๋ฌ์ด ์ ํํ ํ ๋ฒ์ ๋ณด์ฅํ๋๋ก ์ค๊ณ๋ ๊ฒ์ด ์๋๋ผ ์ ๋ขฐ์ฑ์ ์ฐ์ ํ๊ธฐ ๋๋ฌธ์ ๋ฐ์ํฉ๋๋ค. ์๋ฒ๊ฐ ๋๋ฆฌ๊ฑฐ๋ ํ์์์์ด ๋๊ฑฐ๋ ์ค๋ฅ๋ฅผ ๋ฐํํ๊ฑฐ๋ ์ ๊น ์ฌ์ฉ ๋ถ๊ฐ ์ํ๋ฉด ์ ๊ณต์๋ ๋ณดํต ๊ฐ์ ์ด๋ฒคํธ๋ฅผ ๋ค์ ๋ณด๋ ๋๋ค. ๋ํ ํ๋์ ์ค์ ๋์์ ๋ํด ์๋ก ๋ค๋ฅธ ์ด๋ฒคํธ(์: ํ๋์ ๊ฒฐ์ ์ ์ฐ๊ฒฐ๋ ์ธ๋ณด์ด์ค ์ด๋ฒคํธ์ ๊ฒฐ์ ์ด๋ฒคํธ)๊ฐ ์๊ธธ ์ ์๊ณ , ํ๋ถ์ฒ๋ผ ๋น ๋ฅด๊ฒ ์ด์ด์ง๋ ํ์ ์ฒ๋ฆฌ ๋๋ฌธ์ ์ด๋ฒคํธ๊ฐ ์์๋๋ก ๋์ฐฉํ์ง ์์ ์๋ ์์ต๋๋ค.
ํธ๋ค๋ฌ๊ฐ ๋ฉฑ๋ฑ์ฑ์ด ์๋ค๋ฉด ๊ฐ์ ์ด๋ฒคํธ๋ฅผ ๋ ๋ฒ ์ ์ฉํด ๊ณ ๊ฐ๊ณผ ์ฌ๋ฌดํ์ด ๋ฐ๋ก ์์์ฐจ๋ฆฌ๋ ๋ฌธ์ ๊ฐ ์๊น๋๋ค:
- ์ธ๋ณด์ด์ค๊ฐ ๋ ๋ฒ ๊ฒฐ์ ๋จ์ผ๋ก ํ์๋์ด ์ค๋ณต ํ๊ณ ํญ๋ชฉ ๋ฐ์
- ๊ฐฑ์ ์ด ๋ ๋ฒ ์ ์ฉ๋์ด ์ ๊ทผ ๊ธฐ๊ฐ์ด ๊ณผ๋ํ๊ฒ ์ฐ์ฅ๋จ
- ๊ถํ(์ถ๊ฐ ํฌ๋ ๋ง, ์ข์, ๊ธฐ๋ฅ)์ด ๋ ๋ฒ ๋ถ์ฌ๋จ
- ํ๋ถ์ด๋ ์ฐจ์ง๋ฐฑ์ด ์ ๊ทผ์ ์ฌ๋ฐ๋ฅด๊ฒ ๋๋๋ฆฌ์ง ๋ชปํจ
์ด๊ฑด ๋จ์ํ โ๋ชจ๋ฒ ์ฌ๋กโ ๋ฌธ์ ๊ฐ ์๋๋๋ค. ์ ๋ขฐํ ์ ์๋ ์ฒญ๊ตฌ์ธ์ง, ๋ฌธ์ ํฐ์ผ์ ๋ง๋๋ ์ฒญ๊ตฌ์ธ์ง์ ์ฐจ์ด์ ๋๋ค.
์ด ์ฒดํฌ๋ฆฌ์คํธ์ ๋ชฉํ๋ ๊ฐ๋จํฉ๋๋ค: ๋ค์ด์ค๋ ๊ฐ ์ด๋ฒคํธ๋ฅผ "์ต๋ ํ ๋ฒ ์ ์ฉ"์ผ๋ก ์ฒ๋ฆฌํ์ธ์. ๋ชจ๋ ์ด๋ฒคํธ์ ๋ํด ์์ ์ ์ธ ์๋ณ์๋ฅผ ์ ์ฅํ๊ณ ์ฌ์๋๋ฅผ ์์ ํ๊ฒ ์ฒ๋ฆฌํ๋ฉฐ ์ธ๋ณด์ด์ค, ๊ตฌ๋ , ๊ถํ์ ํต์ ๋ ๋ฐฉ์์ผ๋ก ์ ๋ฐ์ดํธํฉ๋๋ค. AppMaster ๊ฐ์ ๋ ธ์ฝ๋ ๋๊ตฌ๋ก ๋ฐฑ์๋๋ฅผ ๋ง๋ ๋ค๋ฉด ๋์ผํ ๊ท์น์ด ์ ์ฉ๋ฉ๋๋ค: ๋ช ํํ ๋ฐ์ดํฐ ๋ชจ๋ธ๊ณผ ์ฌ์๋ ์ํฉ์์๋ ์ฌ๋ฐ๋ฅด๊ฒ ์ ์ง๋๋ ๋ฐ๋ณต ๊ฐ๋ฅํ ํธ๋ค๋ฌ ํ๋ก์ฐ๊ฐ ํ์ํฉ๋๋ค.
์นํ ์ ์ ์ฉํ ์ ์๋ ๋ฉฑ๋ฑ์ฑ ๊ธฐ๋ณธ ์์น
๋ฉฑ๋ฑ์ฑ์ ๊ฐ์ ์ ๋ ฅ์ ์ฌ๋ฌ ๋ฒ ์ฒ๋ฆฌํด๋ ์ต์ข ์ํ๊ฐ ๊ฐ๊ฒ ๋๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ์ฒญ๊ตฌ ๊ด์ ์์๋: ํ๋์ ์ธ๋ณด์ด์ค๋ ํ ๋ฒ๋ง ๊ฒฐ์ ์ฒ๋ฆฌ๋๊ณ , ํ๋์ ๊ตฌ๋ ์ ํ ๋ฒ๋ง ์ ๋ฐ์ดํธ๋๋ฉฐ, ์ ๊ทผ ๊ถํ์ ํ ๋ฒ๋ง ๋ถ์ฌ๋์ด์ผ ํฉ๋๋ค. ์นํ ์ด ๋ ๋ฒ ์ ๋ฌ๋๋๋ผ๋ ๋ง์ ๋๋ค.
์ ๊ณต์๋ ์๋ํฌ์ธํธ๊ฐ ํ์์์๋๊ฑฐ๋ 5xx๋ฅผ ๋ฐํํ๊ฑฐ๋ ๋คํธ์ํฌ๊ฐ ๋๊ธฐ๋ฉด ์ฌ์๋ํฉ๋๋ค. ์ด๋ฌํ ์ฌ์๋๋ ๊ฐ์ ์ด๋ฒคํธ๋ฅผ ๋ฐ๋ณตํฉ๋๋ค. ๋ฉฐ์น ํ ๋ฐ์ํ๋ ํ๋ถ ๊ฐ์ ์ค์ ๋ณ๊ฒฝ์ ๋ํ๋ด๋ ๋ณ๊ฐ์ ์ด๋ฒคํธ๋ ID๊ฐ ๋ค๋ฆ ๋๋ค.
์ด๊ฒ์ ์๋์ํค๋ ค๋ฉด ๋ ๊ฐ์ง๊ฐ ํ์ํฉ๋๋ค: ์์ ์ ์ธ ์๋ณ์์ ์ด๋ฏธ ๋ณธ ๊ฒ์ ๊ธฐ์ตํ ์์ "๋ฉ๋ชจ๋ฆฌ"์ ๋๋ค.
์ด๋ค ID๋ฅผ ์ ์ฅํด์ผ ํ๋(๊ทธ๋ฆฌ๊ณ ๋ฌด์์ ๋ณด๊ดํ ์ง)
๋๋ถ๋ถ์ ๊ฒฐ์ ํ๋ซํผ์ ์นํ ์ด๋ฒคํธ์ ๊ณ ์ ํ ์ด๋ฒคํธ ID๋ฅผ ํฌํจํฉ๋๋ค. ์ผ๋ถ๋ ์์ฒญ ID, ๋ฉฑ๋ฑ์ฑ ํค ๋๋ ํ์ด๋จผํธ ๊ฐ์ฒด ID(์: charge ๋๋ payment intent) ๊ฐ์ ๊ณ ์ ์๋ณ์๋ฅผ ํ์ด๋ก๋ ์์ ์ ๊ณตํฉ๋๋ค.
๋ค์ ์ง๋ฌธ์ ๋ตํ ์ ์๊ฒ ์ ์ฅํ์ธ์: โ์ด ์ ํํ ์ด๋ฒคํธ๋ฅผ ์ด๋ฏธ ์ ์ฉํ๋?โ
์ค๋ฌด์ ์ต์ ํญ๋ชฉ:
- ์ด๋ฒคํธ ID(๊ณ ์ ํค)
- ์ด๋ฒคํธ ํ์ (๋๋ฒ๊น ์ ์ ์ฉ)
- ์์ ํ์์คํฌํ
- ์ฒ๋ฆฌ ์ํ(์ฒ๋ฆฌ๋จ/์คํจ)
- ์ํฅ์ ๋ฐ์ ๊ณ ๊ฐ, ์ธ๋ณด์ด์ค ๋๋ ๊ตฌ๋ ์ ๋ํ ์ฐธ์กฐ
ํต์ฌ์ ์ด๋ฒคํธ ID๋ฅผ ๊ณ ์ ์ ์ฝ์ด ์๋ ํ ์ด๋ธ์ ์ ์ฅํ๋ ๊ฒ์ ๋๋ค. ๊ทธ๋ฐ ๋ค์ ํธ๋ค๋ฌ๋ ์์ ํ๊ฒ ์ด๋ ๊ฒ ํ ์ ์์ต๋๋ค: ๋จผ์ ์ด๋ฒคํธ ID๋ฅผ ์ฝ์ ํ์ธ์; ์ด๋ฏธ ์กด์ฌํ๋ฉด ์ค๋ณต์ผ๋ก ๋ณด๊ณ ์ค์งํ๊ณ 200์ ๋ฐํํฉ๋๋ค.
์ค๋ณต ๊ธฐ๋ก์ ์ผ๋ง๋ ์ค๋ ๋ณด๊ดํด์ผ ํ๋
์ง์ฐ๋ ์ฌ์๋์ ์กฐ์ฌ ๊ธฐ๊ฐ์ ์ปค๋ฒํ ๋งํผ ์ค๋ณต ๊ธฐ๋ก์ ๋ณด๊ดํ์ธ์. ์ผ๋ฐ์ ์ธ ์ฐฝ(window)์ 3090์ผ์
๋๋ค. ์ฐจ์ง๋ฐฑ, ๋ถ์ ๋๋ ๊ธด ๊ตฌ๋
์ฃผ๊ธฐ๋ฅผ ๋ค๋ฃจ๋ฉด ๋ ์ค๋(612๊ฐ์) ๋ณด๊ดํ๊ณ ์ค๋๋ ํ์ ์ ๋ฆฌํด ํ
์ด๋ธ์ด ๋น ๋ฅด๊ฒ ์ ์ง๋๋๋ก ํ์ธ์.
AppMaster ๊ฐ์ ์์ฑ๋ ๋ฐฑ์๋์์๋ ์ด ๊ฒ์ด WebhookEvents ๋ชจ๋ธ์ ์ด๋ฒคํธ ID์ ๋ํ ์ ๋ํฌ ํ๋๋ฅผ ๋๊ณ , ์ค๋ณต์ด ๊ฐ์ง๋๋ฉด ์กฐ๊ธฐ ์ข
๋ฃํ๋ ๋น์ฆ๋์ค ํ๋ก์ธ์ค๋ก ๊น๋ํ๊ฒ ๋งคํ๋ฉ๋๋ค.
์ด๋ฒคํธ ์ค๋ณต ์ ๊ฑฐ๋ฅผ ์ํ ๊ฐ๋จํ ๋ฐ์ดํฐ ๋ชจ๋ธ ์ค๊ณ
์ข์ ์นํ ํธ๋ค๋ฌ๋ ๋๋ถ๋ถ ๋ฐ์ดํฐ ๋ฌธ์ ์ ๋๋ค. ์ ๊ณต์ ์ด๋ฒคํธ๋ฅผ ์ ํํ ํ ๋ฒ์ฉ ๊ธฐ๋กํ ์ ์๋ค๋ฉด ๊ทธ ๋ค์์ ๋ชจ๋ ์ฒ๋ฆฌ๊ฐ ๋ ์์ ํด์ง๋๋ค.
์์์ฆ ๋ก๊ทธ์ฒ๋ผ ๋์ํ๋ ํ๋์ ํ ์ด๋ธ๋ก ์์ํ์ธ์. PostgreSQL(๋๋ AppMaster์ Data Designer์ ๋ชจ๋ธ๋งํ ๋)์์๋ ์๊ณ ์๊ฒฉํ๊ฒ ์ ์งํด ์ค๋ณต์ด ๋น ๋ฅด๊ฒ ์คํจํ๋๋ก ํ์ธ์.
์ต์๋ก ํ์ํ ํญ๋ชฉ
์ค๋ฌด์ ์ธ ๊ธฐ์ค์ webhook_events ํ
์ด๋ธ ์:
provider(ํ ์คํธ, ์: "stripe")provider_event_id(ํ ์คํธ, ํ์)status(ํ ์คํธ, ์: "received", "processed", "failed")processed_at(ํ์์คํฌํ, nullable)raw_payload(jsonb ๋๋ text)
(provider, provider_event_id)์ ์ ๋ํฌ ์ ์ฝ์ ์ถ๊ฐํ์ธ์. ์ด ๋จ์ผ ๊ท์น์ด ์ฃผ์ํ ์ค๋ณต ๋ฐฉ์ง ์๋จ์ ๋๋ค.
์ ๋ฐ์ดํธํ ๋ ์ฝ๋๋ฅผ ์ฐพ๊ธฐ ์ํด ์ฌ์ฉํ๋ ๋น์ฆ๋์ค ID๋ ํ์ํฉ๋๋ค. ์ด๋ ์นํ ์ด๋ฒคํธ ID์ ๋ค๋ฆ ๋๋ค.
์ผ๋ฐ์ ์ผ๋ก customer_id, invoice_id, subscription_id ๊ฐ์ ๊ฐ๋ค์ ํ
์คํธ๋ก ๋ณด๊ดํ์ธ์. ์ ๊ณต์๋ค์ด ์ข
์ข
์ซ์๊ฐ ์๋ ID๋ฅผ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์
๋๋ค.
์์ ํ์ด๋ก๋ vs ํ์ฑ๋ ํ๋
์์ ํ์ด๋ก๋๋ฅผ ์ ์ฅํ๋ฉด ๋๋ฒ๊น ๊ณผ ์ฌ์ฒ๋ฆฌ ์ ์ ์ฉํฉ๋๋ค. ํ์ฑ๋ ํ๋๋ ์ฟผ๋ฆฌ์ ๋ฆฌํฌํ ์ ์ฝ๊ฒ ํ์ง๋ง ์ค์ ๋ก ์ฌ์ฉํ๋ ๊ฒ๋ง ์ ์ฅํ์ธ์.
๊ฐ๋จํ ์ ๊ทผ๋ฒ:
- ํญ์
raw_payload๋ฅผ ์ ์ฅํ์ธ์ - ์์ฃผ ์กฐํํ๋ ๋ช๋ช ํ์ฑ๋ ID(๊ณ ๊ฐ, ์ธ๋ณด์ด์ค, ๊ตฌ๋ )๋ ์ ์ฅํ์ธ์
- ํํฐ๋ง์ ์ํ ์ ๊ทํ๋
event_type(ํ ์คํธ)์ ์ ์ฅํ์ธ์
์๋ฅผ ๋ค์ด invoice.paid ์ด๋ฒคํธ๊ฐ ๋ ๋ฒ ๋์ฐฉํ๋ฉด ์ ๋ํฌ ์ ์ฝ์ด ๋ ๋ฒ์งธ ์ฝ์
์ ๋ง์ต๋๋ค. ๊ฐ์ฌ์ฉ์ผ๋ก ์์ ํ์ด๋ก๋๊ฐ ๋จ์ ์๊ณ , ํ์ฑ๋ ์ธ๋ณด์ด์ค ID๋ก ์ฒซ ๋ฒ์งธ ์
๋ฐ์ดํธ ์์ ์ ์ฝ๊ฒ ์ฐพ์ ์ ์์ต๋๋ค.
๋จ๊ณ๋ณ: ์์ ํ ์นํ ํธ๋ค๋ฌ ํ๋ก์ฐ
์์ ํ ํธ๋ค๋ฌ๋ ์ผ๋ถ๋ฌ ์ง๋ฃจํฉ๋๋ค. ์ ๊ณต์๊ฐ ๊ฐ์ ์ด๋ฒคํธ๋ฅผ ์ฌ์๋ํ๊ฑฐ๋ ์ด๋ฒคํธ๊ฐ ์์๋๋ก ์ค์ง ์์๋ ํญ์ ๊ฐ์ ๋ฐฉ์์ผ๋ก ๋์ํฉ๋๋ค.
๋งค๋ฒ ๋ฐ๋ผ์ผ ํ 5๋จ๊ณ ํ๋ก์ฐ
-
์๋ช ์ ๊ฒ์ฆํ๊ณ ํ์ด๋ก๋๋ฅผ ํ์ฑํ์ธ์. ์๋ช ์ฒดํฌ์ ์คํจํ๊ฑฐ๋, ์์์น ๋ชปํ ์ด๋ฒคํธ ํ์ ์ด๊ฑฐ๋, ํ์ฑํ ์ ์์ผ๋ฉด ์์ฒญ์ ๊ฑฐ๋ถํ์ธ์.
-
์ฒญ๊ตฌ ๋ฐ์ดํฐ๋ฅผ ๊ฑด๋๋ฆฌ๊ธฐ ์ ์ ์ด๋ฒคํธ ๋ ์ฝ๋๋ฅผ ๊ธฐ๋กํ์ธ์. ์ ๊ณต์ ์ด๋ฒคํธ ID, ํ์ , ์์ฑ ์๊ฐ, ์์ ํ์ด๋ก๋(๋๋ ํด์)๋ฅผ ์ ์ฅํ์ธ์. ์ด๋ฒคํธ ID๊ฐ ์ด๋ฏธ ์กด์ฌํ๋ฉด ์ค๋ณต์ผ๋ก ์ฒ๋ฆฌํ๊ณ ์ค๋จํ์ธ์.
-
์ด๋ฒคํธ๋ฅผ ๋จ์ผ โ์์ ์โ ๋ ์ฝ๋์ ๋งคํํ์ธ์. ๋ฌด์์ ์ ๋ฐ์ดํธํ ์ง ๊ฒฐ์ ํ์ธ์: ์ธ๋ณด์ด์ค, ๊ตฌ๋ , ๋๋ ๊ณ ๊ฐ. ์ธ๋ถ ID๋ฅผ ๋ ์ฝ๋์ ์ ์ฅํด ์ง์ ์กฐํํ ์ ์๊ฒ ํ์ธ์.
-
์์ ํ ์ํ ๋ณ๊ฒฝ์ ์ ์ฉํ์ธ์. ์ํ๋ ํญ์ ์์ผ๋ก๋ง ์ด๋์ํค์ธ์. ๋ฆ๊ฒ ๋์ฐฉํ "invoice.updated"๋ก ์ด๋ฏธ ๊ฒฐ์ ๋ ์ธ๋ณด์ด์ค๋ฅผ ๋๋๋ฆฌ์ง ๋ง์ธ์. ์ ์ฉํ ๋ด์ฉ(์ด์ ์ํ, ์ ์ํ, ํ์์คํฌํ, ์ด๋ฒคํธ ID)์ ๊ฐ์ฌ์ฉ์ผ๋ก ๊ธฐ๋กํ์ธ์.
-
๋น ๋ฅด๊ฒ ์๋ตํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ๋ก๊น ํ์ธ์. ์ด๋ฒคํธ๊ฐ ์์ ํ๊ฒ ์ ์ฅ๋๊ณ ์ฒ๋ฆฌ๋์๊ฑฐ๋ ๋ฌด์๋๋ฉด ์ฑ๊ณต์ ๋ฐํํ์ธ์. ์ฒ๋ฆฌ๋์๋์ง, ์ค๋ณต์ผ๋ก ๋ฌด์๋์๋์ง, ๊ฑฐ๋ถ๋์๋์ง์ ๊ทธ ์ด์ ๋ฅผ ๋ก๊น ํ์ธ์.
AppMaster์์๋ ๋ณดํต ์นํ ์ด๋ฒคํธ์ฉ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํ ์ด๋ธ๊ณผ "์ด๋ฒคํธ ID๋ฅผ ์ด๋ฏธ ๋ณด์๋๊ฐ?"๋ฅผ ํ์ธํ ๋ค ์ต์ํ์ ์ ๋ฐ์ดํธ ๋จ๊ณ๋ฅผ ์คํํ๋ ๋น์ฆ๋์ค ํ๋ก์ธ์ค๋ก ๋งคํ๋ฉ๋๋ค.
์ฌ์๋, ํ์์์, ์์๊ฐ ๋ค๋ฐ๋ ์ ๋ฌ ์ฒ๋ฆฌ
์ ๊ณต์๋ ๋น ๋ฅธ ์ฑ๊ณต ์๋ต์ ๋ฐ์ง ๋ชปํ๋ฉด ์นํ ์ ์ฌ์๋ํฉ๋๋ค. ๋ํ ์ด๋ฒคํธ๋ฅผ ์์๋๋ก ๋ณด๋ด์ง ์์ ์ ์์ต๋๋ค. ๋์ผํ ์ ๋ฐ์ดํธ๊ฐ ๋ ๋ฒ ๋์ฐฉํ๊ฑฐ๋ ๋์ค ์ด๋ฒคํธ๊ฐ ๋จผ์ ๋์ฐฉํด๋ ํธ๋ค๋ฌ๋ ์์ ํด์ผ ํฉ๋๋ค.
์ค๋ฌด ๊ท์น ํ๋: ๋น ๋ฅด๊ฒ ์๋ตํ๊ณ ์์ ์ ๋์ค์ ํ์ธ์. ์นํ ์์ฒญ์ ์์์ฆ์ผ๋ก ์ทจ๊ธํ๊ณ ๋ฌด๊ฑฐ์ด ๋ก์ง์ ๊ทธ ์์์ ์คํํ์ง ๋ง์ธ์. ํ์ฌ API ํธ์ถ, PDF ์์ฑ, ๊ณ์ ์ฌ๊ณ์ฐ ๋ฑ์ ์์ฒญ ์ฒ๋ฆฌ ์์์ ํ๋ฉด ํ์์์์ด ๋์ด๋ ์ฌ์๋๊ฐ ๋ ๋น๋ฒํด์ง๋๋ค.
์์๊ฐ ๋ค๋ฐ๋์์ ๋: ์ต์ ์ํ๋ฅผ ์ ์งํ์ธ์
์์๊ฐ ๋ค๋ฐ๋๋ ๊ฒ์ ์ ์์ ๋๋ค. ๋ณ๊ฒฝ์ ์ ์ฉํ๊ธฐ ์ ์ ๋ ๊ฐ์ง ๊ฒ์ฌ๋ฅผ ํ์ธ์:
- ํ์์คํฌํ ๋น๊ต: ๊ฐ์ฒด(์ธ๋ณด์ด์ค, ๊ตฌ๋ , ๊ถํ)์ ๋ํด ์ด๋ฏธ ์ ์ฅ๋ ๊ฒ๋ณด๋ค ์ต์ ์ธ ๊ฒฝ์ฐ๋ง ์ ์ฉํ์ธ์.
- ํ์์คํฌํ๊ฐ ๊ทผ์ ํ๊ฑฐ๋ ๋ถ๋ช ํํ ๋๋ ์ํ ์ฐ์ ์์๋ฅผ ์ฌ์ฉํ์ธ์: paid๋ open์ ๋ฎ๊ณ , canceled๋ active๋ฅผ ๋ฎ์ต๋๋ค.
์ด๋ฏธ ์ธ๋ณด์ด์ค๋ฅผ ๊ฒฐ์ ๋ก ๊ธฐ๋กํด๋๊ณ ๋ฆ๊ฒ "open" ์ด๋ฒคํธ๊ฐ ๋์ฐฉํ๋ฉด ๋ฌด์ํ์ธ์. "canceled"๋ฅผ ๋ฐ์๋๋ฐ ์ดํ ๋ ์ค๋๋ "active" ์ ๋ฐ์ดํธ๊ฐ ๋ํ๋๋ฉด ์ทจ์๋ ์ํ๋ฅผ ์ ์งํ์ธ์.
๋ฌด์ vs ํ์
์ค๋๋์๊ฑฐ๋ ์ด๋ฏธ ์ ์ฉ๋์์์ ์ฆ๋ช ํ ์ ์์ผ๋ฉด ์ด๋ฒคํธ๋ฅผ ๋ฌด์ํ์ธ์(๊ฐ์ ์ด๋ฒคํธ ID, ๋ ์ค๋๋ ํ์์คํฌํ, ๋ฎ์ ์ํ ์ฐ์ ์์). ๋ฐ๋๋ก ํ์ํ ๋ฐ์ดํฐ๊ฐ ์์ง ์์ด ์ฒ๋ฆฌํ ์ ์๋ ๊ฒฝ์ฐ(์: ๊ณ ๊ฐ ๋ ์ฝ๋๊ฐ ์์ง ์์) ์ด๋ฒคํธ๋ฅผ ํ์ ๋ฃ์ผ์ธ์.
์ค๋ฌด ํจํด:
- ์ด๋ฒคํธ๋ฅผ ์ฆ์ ์ ์ฅํ๊ณ ์ฒ๋ฆฌ ์ํ(received, processing, done, failed)๋ฅผ ๋์ธ์
- ์ข ์ ๋ฐ์ดํฐ๊ฐ ์์ผ๋ฉด waiting์ผ๋ก ํ์ํ๊ณ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์ฌ์๋ํ์ธ์
- ์ฌ์๋ ์ ํ์ ๋๊ณ ๋ฐ๋ณต ์คํจ ์ ์๋ฆผ์ ์ค์ ํ์ธ์
AppMaster์์๋ ์นํ ์ด๋ฒคํธ ํ ์ด๋ธ๊ณผ ์์ฒญ์ ๋น ๋ฅด๊ฒ ํ์ธํ๊ณ ํ์ ๋ฃ์ ์ด๋ฒคํธ๋ฅผ ๋น๋๊ธฐ์ ์ผ๋ก ์ฒ๋ฆฌํ๋ ๋น์ฆ๋์ค ํ๋ก์ธ์ค๊ฐ ์ ๋ง์ต๋๋ค.
์ธ๋ณด์ด์ค, ๊ตฌ๋ , ๊ถํ์ ์์ ํ๊ฒ ์ ๋ฐ์ดํธํ๊ธฐ
์ค๋ณต ์ ๊ฑฐ๋ฅผ ์ฒ๋ฆฌํ ๋ค์์ ์ํ์ ๋ถ๋ฆฌ๋ ์ฒญ๊ตฌ ์ํ์ ๋๋ค: ์ธ๋ณด์ด์ค๋ ๊ฒฐ์ ๋จ์ผ๋ก ํ์๋์์ง๋ง ๊ตฌ๋ ์ ์ฌ์ ํ ์ฐ์ฒด ์ํ์ด๊ฑฐ๋, ์ ๊ทผ์ด ๋ ๋ฒ ๋ถ์ฌ๋์ด ์ ๋๋ก ํ์๋์ง ์๋ ๊ฒฝ์ฐ ๋ฑ์ด ์์ต๋๋ค. ๋ชจ๋ ์นํ ์ ์ํ ์ ์ด๋ก ์ทจ๊ธํ๊ณ ํ ๋ฒ์ ์์์ ์ผ๋ก ์ ์ฉํ์ธ์.
์ธ๋ณด์ด์ค: ์ํ ๋ณ๊ฒฝ์ ๋จ์กฐ๋กญ๊ฒ(๋ชจ๋ ธํ ๋) ์ ์งํ์ธ์
์ธ๋ณด์ด์ค๋ paid, voided, refunded ๊ฐ์ ์ํ๋ฅผ ๊ฑฐ์นฉ๋๋ค. ๋ถ๋ถ ๊ฒฐ์ ๊ฐ ์์ ์๋ ์์ต๋๋ค. ์ด๋ค ์ด๋ฒคํธ๊ฐ ๋ง์ง๋ง์ผ๋ก ๋์ฐฉํ๋์ง์ ๋ฐ๋ผ ์ธ๋ณด์ด์ค๋ฅผ ํ ๊ธํ์ง ๋ง์ธ์. ํ์ฌ ์ํ์ ์ฃผ์ ์ด์ก(amount_paid, amount_refunded)์ ์ ์ฅํ๊ณ ์์ผ๋ก ์์ ํ ์ ์ด๋ง ํ์ฉํ์ธ์.
์ค๋ฌด ๊ท์น:
- ์ธ๋ณด์ด์ค๋ ํ ๋ฒ๋ง paid๋ก ํ์ํ์ธ์. paid ์ด๋ฒคํธ๋ฅผ ์ฒ์ ๋ณด์์ ๋๋ง ํ์ํฉ๋๋ค.
- ํ๋ถ์ด ๋ฐ์ํ๋ฉด
amount_refunded๋ฅผ ์ธ๋ณด์ด์ค ์ด์ก๊น์ง ์ฆ๊ฐ์ํค๊ณ ์ ๋ ๊ฐ์์ํค์ง ๋ง์ธ์. - ์ธ๋ณด์ด์ค๊ฐ voided๋๋ฉด ์ดํ(fulfillment) ๋์์ ์ค์งํ๋ ๊ฐ์ฌ์ฉ์ผ๋ก ๋ ์ฝ๋๋ฅผ ์ ์งํ์ธ์.
- ๋ถ๋ถ ๊ฒฐ์ ์ ๊ฒฝ์ฐ "์์ ๊ฒฐ์ (fully paid)" ์ด์ ์ ์ฃผ์ง ๋ง๊ณ ๊ธ์ก๋ง ์ ๋ฐ์ดํธํ์ธ์.
๊ตฌ๋ ๊ณผ ๊ถํ: ๋ถ์ฌ๋ ํ ๋ฒ, ํ์๋ ํ ๋ฒ
๊ตฌ๋
์๋ ๊ฐฑ์ , ์ทจ์, ์ ์ ๊ธฐ๊ฐ์ด ํฌํจ๋ฉ๋๋ค. ๊ตฌ๋
์ํ์ ๊ธฐ๊ฐ ๊ฒฝ๊ณ(current_period_start/end)๋ฅผ ์ ์งํ๊ณ ๊ถํ ๊ธฐ๊ฐ์ ๊ทธ ๋ฐ์ดํฐ์์ ์ ๋ํ์ธ์. ๊ถํ์ ๋จ์ํ ๋ถ๋ฆฌ์ธ์ด ์๋๋ผ ๋ช
์์ ๋ ์ฝ๋๋ก ๊ด๋ฆฌํ์ธ์.
์ ๊ทผ ์ ์ด๋ฅผ ์ํ ๊ท์น:
- ์ฌ์ฉ์๋ณ/์ํ๋ณ/๊ธฐ๊ฐ๋ณ๋ก ๊ถํ ๋ถ์ฌ๋ ํ ๋ฒ๋ง
- ์ ๊ทผ์ด ์ข ๋ฃ๋ ๋(์ทจ์, ํ๋ถ, ์ฐจ์ง๋ฐฑ) ํ ๋ฒ์ ํ์ ๊ธฐ๋ก์ ๋จ๊น
- ์ด๋ค ์นํ ์ด๋ฒคํธ๊ฐ ๊ฐ ๋ณ๊ฒฝ์ ๋ฐ์์์ผฐ๋์ง ๊ฐ์ฌ ๋ก๊ทธ๋ก ๊ธฐ๋ก
๋ถ๋ฆฌ ์ํ๋ฅผ ํผํ๋ ค๋ฉด ํ ํธ๋์ญ์ ์์ ์ฒ๋ฆฌํ์ธ์
์ธ๋ณด์ด์ค, ๊ตฌ๋ , ๊ถํ ์ ๋ฐ์ดํธ๋ฅผ ํ๋์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํธ๋์ญ์ ์์ ์ ์ฉํ์ธ์. ํ์ฌ ํ์ ์ฝ๊ณ , ์ด ์ด๋ฒคํธ๊ฐ ์ด๋ฏธ ์ ์ฉ๋์๋์ง ํ์ธํ ๋ค ๋ชจ๋ ๋ณ๊ฒฝ์ ํจ๊ป ๊ธฐ๋กํ์ธ์. ์คํจํ๋ฉด ๋กค๋ฐฑ๋๋๋ก ํ์ธ์. ๊ทธ๋์ผ "์ธ๋ณด์ด์ค๋ ๊ฒฐ์ ๋จ"์ธ๋ฐ "์ ๊ทผ ์์" ๊ฐ์ ์ํ ๋ถ์ผ์น๊ฐ ์๊ธฐ์ง ์์ต๋๋ค.
AppMaster์์๋ ๋ณดํต ํ๋์ Business Process ํ๋ฆ์์ PostgreSQL์ ์ ์ดํ๊ณ ๋น์ฆ๋์ค ๋ณ๊ฒฝ๊ณผ ํจ๊ป ๊ฐ์ฌ ํญ๋ชฉ์ ์์ฑํ๋ ๋ฐฉ์์ผ๋ก ์ ๋งคํ๋ฉ๋๋ค.
์นํ ์๋ํฌ์ธํธ ๋ณด์ ๋ฐ ๋ฐ์ดํฐ ์์ ๊ฒ์ฌ
์นํ ๋ณด์์ ์ ํ์ฑ์ ์ผ๋ถ์ ๋๋ค. ๊ณต๊ฒฉ์๊ฐ ์๋ํฌ์ธํธ์ ์ ๊ทผํ ์ ์๋ค๋ฉด ์์กฐ๋ "๊ฒฐ์ ์๋ฃ" ์ํ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ์ค๋ณต ์ ๊ฑฐ๊ฐ ์์ด๋ ์ด๋ฒคํธ๊ฐ ์ง์ง์ธ์ง ์ฆ๋ช ํ๊ณ ๊ณ ๊ฐ ๋ฐ์ดํฐ๋ฅผ ์์ ํ๊ฒ ์ง์ผ์ผ ํฉ๋๋ค.
์ฒญ๊ตฌ ๋ฐ์ดํฐ๋ฅผ ๊ฑด๋๋ฆฌ๊ธฐ ์ ์ ๋ฐ์ ์๋ฅผ ๊ฒ์ฆํ์ธ์
๋ชจ๋ ์์ฒญ์ ์๋ช
์ ๊ฒ์ฆํ์ธ์. Stripe์ ๊ฒฝ์ฐ ์ผ๋ฐ์ ์ผ๋ก Stripe-Signature ํค๋๋ฅผ ํ์ธํ๊ณ ์์ ์์ฒญ ๋ณธ๋ฌธ(raw request body)์ ์ฌ์ฉํ๋ฉฐ(์ฌ์์ฑ๋ JSON์ด ์๋) ์ค๋๋ ํ์์คํฌํ๋ ๊ฑฐ๋ถํฉ๋๋ค. ํค๋๊ฐ ์์ผ๋ฉด ๋ฐ๋ก ์คํจ ์ฒ๋ฆฌํ์ธ์.
์ด๊ธฐ ๊ฒ์ฆ์ผ๋ก๋ ์ฌ๋ฐ๋ฅธ HTTP ๋ฉ์๋, Content-Type, ํ์ํ ํ๋(์ด๋ฒคํธ id, ํ์
, ์ธ๋ณด์ด์ค๋ ๊ตฌ๋
์ ์ฐพ๋ ๋ฐ ์ธ ๊ฐ์ฒด id)๋ฅผ ํ์ธํ์ธ์. AppMaster๋ก ๋น๋ํ๋ฉด ์๋ช
๋น๋ฐ์ ํ๊ฒฝ ๋ณ์๋ ๋ณด์ ์ค์ ์ ๋๊ณ ๋ฐ์ดํฐ๋ฒ ์ด์ค๋ ํด๋ผ์ด์ธํธ ์ฝ๋์ ๋์ง ๋ง์ธ์.
๋น ๋ฅธ ๋ณด์ ์ฒดํฌ๋ฆฌ์คํธ:
- ์ ํจํ ์๋ช ๊ณผ ์ต์ ํ์์คํฌํ๊ฐ ์์ผ๋ฉด ์์ฒญ์ ๊ฑฐ๋ถ
- ์์ ํค๋์ ์ฝํ ์ธ ํ์ ์ ์๊ตฌ
- ์นํ ํธ๋ค๋ฌ๋ ์ต์ ๊ถํ์ DB ์ ๊ทผ๋ง ์ฌ์ฉ
- ๋น๋ฐ๊ฐ์ ํ ์ด๋ธ ๋ฐ(env/config)์ ์ ์ฅํ๊ณ ํ์ ์ ๊ต์ฒด
- ์ด๋ฒคํธ๋ฅผ ์์ ํ๊ฒ ์๊ตฌ ์ ์ฅํ ๋ค์๋ง 2xx ์๋ต ๋ฐํ
๋น๋ฐ ์ ์ถ ์์ด ๋ก๊ทธ๋ฅผ ์ ์ฉํ๊ฒ ์ ์งํ์ธ์
์ฌ์๋์ ๋ถ์์ ๋๋ฒ๊น
ํ ์ ์์ ๋งํผ ์ถฉ๋ถํ ๋ก๊ทธ๋ฅผ ๋จ๊ธฐ๋ ๋ฏผ๊ฐํ ๊ฐ์ ํผํ์ธ์. ์ ์ฅํ ์ ์๋ ์์ ํ PII์ ๋ถ๋ถ์งํฉ: ์ ๊ณต์ ๊ณ ๊ฐ ID, ๋ด๋ถ ์ฌ์ฉ์ ID, ๋ง์คํน๋ ์ด๋ฉ์ผ(์: a***@domain.com). ์ ์ฒด ์นด๋ ๋ฐ์ดํฐ, ์ ์ฒด ์ฃผ์, ์์ ์ธ์ฆ ํค๋๋ ์ ๋ ์ ์ฅํ์ง ๋ง์ธ์.
์ฌ๊ตฌ์ฑ์ ๋์์ด ๋๋ ๋ก๊ทธ ํญ๋ชฉ:
- ์ ๊ณต์ ์ด๋ฒคํธ id, ํ์ , ์์ฑ ์๊ฐ
- ๊ฒ์ฆ ๊ฒฐ๊ณผ(์๋ช ์ ์/์คํจ) โ ๋จ, ์๋ช ์์ฒด๋ ์ ์ฅ ๊ธ์ง
- ์ค๋ณต ๊ฒฐ์ (new vs already processed)
- ์์ ๋ ๋ด๋ถ ๋ ์ฝ๋ ID(์ธ๋ณด์ด์ค/๊ตฌ๋ /๊ถํ)
- ์ค๋ฅ ์ด์ ์ ์ฌ์๋ ํ์(ํ๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ)
๊ธฐ๋ณธ์ ์ธ ๋จ์ฉ ๋ฐฉ์ง๋ ์ถ๊ฐํ์ธ์: IP๋ณ ์๋ ์ ํ๊ณผ(๊ฐ๋ฅํ๋ฉด) ๊ณ ๊ฐ ID๋ณ ์ ํ, ํ์ ์ ์ ๊ณต์ IP ๋ฒ์๋ง ํ์ฉํ๋ ๊ฒ๋ ๊ณ ๋ คํ์ธ์.
์ค๋ณต ์ฒญ๊ตฌ๋ ์ค๋ณต ์ ๊ทผ์ ๋ฐ์์ํค๋ ํํ ์ค์
๋๋ถ๋ถ์ ์ฒญ๊ตฌ ๋ฒ๊ทธ๋ ์ํ ๋ฌธ์ ๋๋ฌธ์ด ์๋๋๋ค. ์นํ ์ ๋ฌ์ ๋จ์ผ ์ ๋ขฐ ๊ฐ๋ฅํ ๋ฉ์์ง๋ก ์ทจ๊ธํ ๋ ๋ฐ์ํฉ๋๋ค.
์์ฃผ ๋ฐ์ํ๋ ์ค์:
- ํ์์คํฌํ๋ ๊ธ์ก์ผ๋ก ์ค๋ณต ์ ๊ฑฐ: ์๋ก ๋ค๋ฅธ ์ด๋ฒคํธ๊ฐ ๊ฐ์ ๊ธ์ก์ ๊ฐ์ง ์ ์๊ณ ์ฌ์๋๊ฐ ๋ช ๋ถ ํ์ ๋์ฐฉํ ์ ์์ต๋๋ค. ์ ๊ณต์์ ๊ณ ์ ์ด๋ฒคํธ ID๋ฅผ ์ฌ์ฉํ์ธ์.
- ์๋ช ๊ฒ์ฆ ์ ์ DB๋ฅผ ์ ๋ฐ์ดํธ: ๋จผ์ ๊ฒ์ฆํ๊ณ , ํ์ฑํ ๋ค์ ํ๋ํ์ธ์.
- ํ์ฌ ์ํ๋ฅผ ํ์ธํ์ง ์๊ณ ๋ชจ๋ ์ด๋ฒคํธ๋ฅผ ์ ๋ขฐ: ์ด๋ฏธ ๊ฒฐ์ ๋๊ฑฐ๋ ํ๋ถ๋ ์ธ๋ณด์ด์ค๋ฅผ ๋งน๋ชฉ์ ์ผ๋ก paid๋ก ํ๊ธฐํ์ง ๋ง์ธ์.
- ๋์ผ ๊ตฌ๋งค์ ๋ํด ์ฌ๋ฌ ๊ถํ ์์ฑ: ์ฌ์๋๋ก ์ค๋ณต ํ์ด ์๊น๋๋ค.
ensure entitlement exists for subscription_id๊ฐ์ upsert ๊ท์น์ ์ ํธํ์ธ์. - ์๋ฆผ ์๋น์ค๊ฐ ๋ค์ด๋์ด ์นํ ์ ์คํจ ์ฒ๋ฆฌํจ: ์ด๋ฉ์ผ, SMS, Slack ๋ฑ์ ์ฒญ๊ตฌ๋ฅผ ์ฐจ๋จํ๋ฉด ์ ๋ฉ๋๋ค. ์๋ฆผ์ ํ์ ๋ฃ๊ณ ํต์ฌ ์ฒญ๊ตฌ ๋ณ๊ฒฝ์ ์์ ํ๊ฒ ์ ์ฅํ ๋ค ์ฑ๊ณต์ ๋ฐํํ์ธ์.
๊ฐ๋จํ ์: ๊ฐฑ์ ์ด๋ฒคํธ๊ฐ ๋ ๋ฒ ๋์ฐฉํ์ต๋๋ค. ์ฒ์ ์ ๋ฌ์ ๊ถํ ํ์ ์์ฑํฉ๋๋ค. ์ฌ์๋๊ฐ ๋ ๋ฒ์งธ ํ์ ์์ฑํด ์ฑ์ด "๋ ๊ฐ์ ํ์ฑ ๊ถํ"์ด๋ผ๊ณ ํ๋จํ๋ฉด ์ถ๊ฐ ์ข์์ด๋ ํฌ๋ ๋ง์ ๋ถ์ฌํ๊ฒ ๋ฉ๋๋ค.
AppMaster์์๋ ์์ ๋ฐฉ๋ฒ์ด ๋๋ถ๋ถ ํ๋ฆ์ ๊ดํ ๊ฒ์ ๋๋ค: ๋จผ์ ๊ฒ์ฆ, ์ ๋ํฌ ์ ์ฝ์ผ๋ก ์ด๋ฒคํธ ๋ ์ฝ๋ ์ฝ์ , ์ํ ๊ฒ์ฌ์ ํจ๊ป ์ฒญ๊ตฌ ์ ๋ฐ์ดํธ ์ ์ฉ, ๋ถ์ ํจ๊ณผ(์ด๋ฉ์ผ, ์์์ฆ)๋ ๋น๋๊ธฐ ๋จ๊ณ๋ก ๋ฐ์ด ์ฌ์๋ ํญ์ฃผ๋ฅผ ๋ง์ผ์ธ์.
์ค๋ฌด ์์: ์ค๋ณต ๊ฐฑ์ + ์ดํ ํ๋ถ
์ด ํจํด์ ๊ฒ๋ ๋ณด์ผ ์ ์์ง๋ง ํธ๋ค๋ฌ๊ฐ ๋ค์ ์คํํด๋ ์์ ํ๋๋ก ์ค๊ณ๋์ด ์๋ค๋ฉด ๊ด๋ฆฌ ๊ฐ๋ฅํฉ๋๋ค.
๊ณ ๊ฐ์ด ์๊ฐ ์๊ธ์ ๋ฅผ ์ฌ์ฉ ์ค์
๋๋ค. Stripe๊ฐ ๊ฐฑ์ ์ด๋ฒคํธ(์: invoice.paid)๋ฅผ ๋ณด๋์ต๋๋ค. ์๋ฒ๊ฐ ์ด๋ฅผ ์์ ํด DB๋ฅผ ์
๋ฐ์ดํธํ์ง๋ง 200 ์๋ต์ ๋ฐํํ๋ ๋ฐ ๋๋ฌด ์ค๋ ๊ฑธ๋ ธ์ต๋๋ค(์ฝ๋ ์คํํธ, ๋ฐ์ DB ๋ฑ). Stripe๋ ์คํจํ ๊ฒ์ผ๋ก ๋ณด๊ณ ๊ฐ์ ์ด๋ฒคํธ๋ฅผ ์ฌ์๋ํฉ๋๋ค.
์ฒซ ์ ๋ฌ์์ ์ ๊ทผ์ ๋ถ์ฌํฉ๋๋ค. ์ฌ์๋์์๋ ๊ฐ์ ์ด๋ฒคํธ์์ ๊ฐ์งํ๊ณ ์๋ฌด ์์
๋ ํ์ง ์์ต๋๋ค. ์ดํ ํ๋ถ ์ด๋ฒคํธ(์: charge.refunded)๊ฐ ๋์ฐฉํ๋ฉด ํ ๋ฒ๋ง ์ ๊ทผ์ ํ์ํฉ๋๋ค.
๋ฐ์ดํฐ๋ฒ ์ด์ค๋ฅผ ๋ชจ๋ธ๋งํ๋ ๊ฐ๋จํ ๋ฐฉ๋ฒ(์ฑ๋ง์คํฐ Data Designer์์ ๋ง๋ค ์ ์๋ ํ ์ด๋ธ):
webhook_events(event_id UNIQUE, type, processed_at, status)invoices(invoice_id UNIQUE, subscription_id, status, paid_at, refunded_at)entitlements(customer_id, product, active, valid_until, source_invoice_id)
๊ฐ ์ด๋ฒคํธ ํ์ DB ์ํ ์์
Event A(๊ฐฑ์ , ์ฒซ ์ ๋ฌ) ํ: webhook_events์ event_id=evt_123๋ก ์ ํ์ด ์ถ๊ฐ๋๊ณ status=processed๊ฐ ๋ฉ๋๋ค. invoices๋ paid๋ก ํ์๋๊ณ entitlements.active=true, valid_until์ด ํ ๊ฒฐ์ ์ฃผ๊ธฐ๋งํผ ์์ผ๋ก ์ด๋ํฉ๋๋ค.
Event A ์ฌ์ ๋ฌ(์ฌ์๋) ํ: webhook_events ์ฝ์
์ด ์ ๋ํฌ ์ ์ฝ์ผ๋ก ์คํจํ๊ฑฐ๋ ํธ๋ค๋ฌ๊ฐ ์ด๋ฏธ ์ฒ๋ฆฌ๋ ๊ฒ์ผ๋ก ๋ณด๊ณ ์๋ฌด ๋ณ๊ฒฝ๋ ํ์ง ์์ต๋๋ค.
Event B(ํ๋ถ) ํ: webhook_events์ event_id=evt_456 ์ ํ์ด ์ถ๊ฐ๋ฉ๋๋ค. invoices.refunded_at์ด ์ค์ ๋๊ณ status=refunded๊ฐ ๋ฉ๋๋ค. entitlements.active=false๋ก ์ค์ ๋๊ฑฐ๋ valid_until์ด ํ์ฌ ์๊ฐ์ผ๋ก ์กฐ์ ๋์ด source_invoice_id๋ฅผ ์ฌ์ฉํด ์ ๊ทผ์ ํ ๋ฒ๋ง ํ์ํฉ๋๋ค.
์ค์ํ ์ธ๋ถ๋ ํ์ด๋ฐ์ ๋๋ค: ์ค๋ณต ๊ฒ์ฌ(๋ํ ์ฒดํฌ)๋ ๊ถํ์ ๋ถ์ฌํ๊ฑฐ๋ ํ์ํ๊ธฐ ์ ์ ์ํ๋ฉ๋๋ค.
์ถ์ ์ ๋น ๋ฅธ ์ฒดํฌ๋ฆฌ์คํธ
์ค์ ์นํ ์ ์ผ๊ธฐ ์ ์ ํ๋์ ์ค์ ์ด๋ฒคํธ๊ฐ ์ ๊ณต์๊ฐ ์ด ๋ฒ ๋ณด๋๋ ํ ๋ฒ๋ง ์ ์ฉ๋์ด ์ฒญ๊ตฌ ๋ ์ฝ๋๊ฐ ํ ๋ฒ๋ง ์ ๋ฐ์ดํธ๋๋ ๊ฒ์ ์ฆ๋ช ํด์ผ ํฉ๋๋ค.
์๋ํฌ์๋ ์ค์ ์ ๊ฒ์ฆํ๋ ์ฒดํฌ๋ฆฌ์คํธ:
- ๋ค์ด์ค๋ ๋ชจ๋ ์ด๋ฒคํธ๋ ๋จผ์ ์ ์ฅ๋๋๊ฐ(์์ ํ์ด๋ก๋, ์ด๋ฒคํธ id, ํ์ , ์์ฑ ์๊ฐ, ์๋ช ๊ฒ์ฆ ๊ฒฐ๊ณผ ํฌํจ)? ์ดํ ๋จ๊ณ๊ฐ ์คํจํ๋๋ผ๋ ์ ์ฅ๋์ด์ผ ํฉ๋๋ค.
- ์ค๋ณต์ ์ด๊ธฐ์ ๊ฐ์ง๋์ด(๊ฐ์ ์ ๊ณต์ ์ด๋ฒคํธ id) ํธ๋ค๋ฌ๊ฐ ์ธ๋ณด์ด์ค/๊ตฌ๋ /๊ถํ์ ๋ณ๊ฒฝํ์ง ์๊ณ ์ข ๋ฃํ๋๊ฐ?
- ๋น์ฆ๋์ค ์ ๋ฐ์ดํธ๊ฐ ๋จ์ผ ์คํ์ธ์ง ์ฆ๋ช ํ ์ ์๋๊ฐ: ํ ๋ฒ์ ์ธ๋ณด์ด์ค ์ํ ๋ณ๊ฒฝ, ํ ๋ฒ์ ๊ตฌ๋ ์ํ ๋ณ๊ฒฝ, ํ ๋ฒ์ ๊ถํ ๋ถ์ฌ/ํ์.
- ์คํจ๋ ์ฌ์คํ ๊ฐ๋ฅํ๊ฒ ๊ธฐ๋ก๋๋๊ฐ(์ค๋ฅ ๋ฉ์์ง, ์คํจํ ๋จ๊ณ, ์ฌ์๋ ์ํ).
- ํธ๋ค๋ฌ๊ฐ ๋น ๋ฅด๊ฒ ์๋ตํ๋๊ฐ: ์ด๋ฒคํธ๋ฅผ ์ ์ฅํ๋ฉด ๋ฐ๋ก ์์ ํ์ธ์ ํ๊ณ ์์ฒญ ๋ด๋ถ์์ ๋๋ฆฐ ์์ ์ ํผํ๋๊ฐ?
๋๊ท๋ชจ ๊ด์ฐฐ(์ค๋ฒ์๋น๋ฆฌํฐ) ์ธํธ๊ฐ ์์ด๋ ์์ํ ์ ์์ง๋ง ์ ํธ๋ ํ์ํฉ๋๋ค. ๋ก๊ทธ๋ ๋จ์ ๋์๋ณด๋์์ ๋ค์์ ์ถ์ ํ์ธ์:
- ์ค๋ณต ์ ๋ฌ ๊ธ์ฆ(์ ์ ๋ฒ์์ด์ง๋ง ํฐ ์ฆ๊ฐ ์ ํ์์์์ด๋ ์ ๊ณต์ ๋ฌธ์ ์ ํธ)
- ์ด๋ฒคํธ ํ์ ๋ณ ๋์ ์ค๋ฅ์จ(์: invoice.payment_failed)
- ์ฌ์๋์ ๊ฐํ ์ด๋ฒคํธ์ ๋ฐฑ๋ก๊ทธ ์ฆ๊ฐ
- ๋ถ์ผ์น ์ฒดํฌ(๊ฒฐ์ ๋ ์ธ๋ณด์ด์ค์ง๋ง ๊ถํ ๋๋ฝ, ๊ถํ์ด ํ์๋์๋๋ฐ ์ ๊ทผ์ด ๋จ์ ์์)
- ์ฒ๋ฆฌ ์๊ฐ์ ๊ธ๊ฒฉํ ์ฆ๊ฐ
AppMaster๋ก ๊ตฌ์ถํ๋ค๋ฉด ์ด๋ฒคํธ ์ ์ฅ์ ์ ์ฉ ํ ์ด๋ธ์ ๋๊ณ "์ฒ๋ฆฌ๋จ์ผ๋ก ํ์"๋ฅผ ๋น์ฆ๋์ค ํ๋ก์ธ์ค ๋ด ๋จ์ผ ์์์ ๊ฒฐ์ ์ง์ ์ผ๋ก ๋ง๋์ธ์.
๋ค์ ๋จ๊ณ: ํ ์คํธ, ๋ชจ๋ํฐ๋ง, ๋ ธ์ฝ๋ ๋ฐฑ์๋๋ก ๊ตฌ์ถํ๊ธฐ
ํ ์คํธ๋ ๋ฉฑ๋ฑ์ฑ์ด ์ฆ๋ช ๋๋ ๊ณณ์ ๋๋ค. ๋จ์ํ ์ ์ ๊ฒฝ๋ก๋ง ํ ์คํธํ์ง ๋ง์ธ์. ๋์ผํ ์ด๋ฒคํธ๋ฅผ ์ฌ๋ฌ ๋ฒ ์ฌ์(replay)ํ๊ณ , ์ด๋ฒคํธ๋ฅผ ์์ ์์ด ๋ณด๋ด๊ณ , ํ์์์์ ๊ฐ์ ํด ์ ๊ณต์๊ฐ ์ฌ์๋ํ๋๋ก ๋ง๋์ธ์. ๋ ๋ฒ์งธ, ์ธ ๋ฒ์งธ, ์ด ๋ฒ์งธ ์ ๋ฌ์ ์๋ฌด๋ฐ ๋ณ๊ฒฝ์ ๋ง๋ค์ด๋ด์ง ์์์ผ ํฉ๋๋ค.
์ด๊ธฐ์๋ ๋ฐฑํ(backfilling) ๊ณํ์ ์ธ์ฐ์ธ์. ๋ฒ๊ทธ ์์ , ์คํค๋ง ๋ณ๊ฒฝ, ์ ๊ณต์ ์ฌ๊ณ ํ ๊ณผ๊ฑฐ ์ด๋ฒคํธ๋ฅผ ์ฌ์ฒ๋ฆฌํด์ผ ํ ์ผ์ด ์๊น๋๋ค. ํธ๋ค๋ฌ๊ฐ ์ง์ ์ผ๋ก ๋ฉฑ๋ฑ์ฑ์ด ์๋ค๋ฉด ๋ฐฑํ์ โ๊ฐ์ ํ์ดํ๋ผ์ธ์ ํตํด ์ด๋ฒคํธ ์ฌ์โํ๋ ๊ฒ๋ง์ผ๋ก ์ค๋ณต์ ๋ง๋ค์ง ์๊ณ ์์ ํ๊ฒ ์ฌ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
์ง์ํ์๋ ๊ฐ๋จํ ๋ฐ๋ถ์ ์ ๊ณตํด ๋ฌธ์ ๋ฅผ ์ถ์ ํ๋๋ก ํ์ธ์:
- ์ด๋ฒคํธ ID๋ฅผ ์ฐพ์ ์ด๋ฏธ ์ฒ๋ฆฌ๋์๋์ง ํ์ธ
- ์ธ๋ณด์ด์ค ๋๋ ๊ตฌ๋ ๋ ์ฝ๋๋ฅผ ํ์ธํด ์์ ์ํ์ ํ์์คํฌํ ํ์ธ
- ๊ถํ ๋ ์ฝ๋(์ธ์ , ์ ์ ๊ทผ์ด ๋ถ์ฌ๋์๋์ง) ๊ฒํ
- ํ์ํ ๊ฒฝ์ฐ ๋จ์ผ ์ด๋ฒคํธ ID์ ๋ํด ์์ ํ ์ฌ์ฒ๋ฆฌ ๋ชจ๋๋ก ๋ค์ ์คํ
- ๋ฐ์ดํฐ ๋ถ์ผ์น๊ฐ ์์ผ๋ฉด ๋จ์ผ ์์ ์กฐ์น๋ฅผ ์ ์ฉํ๊ณ ๊ธฐ๋ก
๋ง์ ๋ณด์ผ๋ฌํ๋ ์ดํธ ์ฝ๋๋ฅผ ์ฐ์ง ์๊ณ ๊ตฌํํ๋ ค๋ฉด AppMaster(appmaster.io)์ด ํต์ฌ ํ ์ด๋ธ์ ๋ชจ๋ธ๋งํ๊ณ ์นํ ํ๋ก์ฐ๋ฅผ ์๊ฐ์ Business Process๋ก ๋ง๋๋ ๋ฐ ๋์์ ์ค๋๋ค. ์์ฑ๋ ๋ฐฑ์๋๋ฅผ ๋ฐฐํฌํ๊ธฐ ์ ์ ์ฌ์๋ ์ํฉ์์๋ ์์ ํ์ง ๋ฐ๋์ ํ์ธํ์ธ์.
์์ฃผ ๋ฌป๋ ์ง๋ฌธ
์ค๋ณต ์นํ ์ ๋ฌ์ ์ผ๋ฐ์ ์ ๋๋ค. ์ ๊ณต์๊ฐ ์ต์ ํ ๋ฒ ์ด์(at least once) ์ ๋ฌ์ ๋ชฉํ๋ก ํ๊ธฐ ๋๋ฌธ์, ์๋ํฌ์ธํธ๊ฐ ํ์์์๋๊ฑฐ๋ 5xx๋ฅผ ๋ฐํํ๊ฑฐ๋ ์ฐ๊ฒฐ์ด ์ ๊น ๋๊ธฐ๋ฉด ๋์ผํ ์ด๋ฒคํธ๋ฅผ ์ฌ์ ์กํฉ๋๋ค.
๊ณต๊ธ์๊ฐ ์ ๊ณตํ๋ ๊ณ ์ ํ ์ด๋ฒคํธ ID(์นํ ์ด๋ฒคํธ ์๋ณ์)๋ฅผ ์ฌ์ฉํ์ธ์. ๊ธ์ก, ํ์์คํฌํ, ๊ณ ๊ฐ ์ด๋ฉ์ผ๋ก ์ค๋ณต ์ ๊ฑฐํ์ง ๋ง์ธ์. ์ด๋ฒคํธ ID๋ฅผ ์ ๋ํฌ ์ ์ฝ์ผ๋ก ์ ์ฅํ๋ฉด ์ฌ์๋๋ฅผ ์ฆ์ ๊ฐ์งํ๊ณ ์์ ํ๊ฒ ๋ฌด์ํ ์ ์์ต๋๋ค.
์ธ๋ณด์ด์ค, ๊ตฌ๋ , ๊ถํ์ ์ ๋ฐ์ดํธํ๊ธฐ ์ ์ ๋จผ์ ์ด๋ฒคํธ ๋ ์ฝ๋๋ฅผ ์ฝ์ ํ์ธ์. ์ฝ์ ์ด ์คํจํด ์ด๋ฒคํธ ID๊ฐ ์ด๋ฏธ ์กด์ฌํ๋ฉด ์ฒ๋ฆฌ๋ฅผ ๋ฉ์ถ๊ณ ์ฑ๊ณต์ ๋ฐํํด ์ฌ์๋๊ฐ ์ค๋ณต ์ ๋ฐ์ดํธ๋ฅผ ๋ง๋ค์ง ์๊ฒ ํ์ธ์.
์ง์ฐ๋ ์ฌ์๋์ ์กฐ์ฌ ๊ธฐ๊ฐ์ ์ปค๋ฒํ ๋งํผ ๋ณด๊ดํ์ธ์. ์ค๋ฌด์ ์ผ๋ก๋ 30โ90์ผ์ด ์ผ๋ฐ์ ์ด๊ณ , ๋ถ์์ด๋ ์ฐจ์ง๋ฐฑ, ๊ธด ๊ตฌ๋ ์ฃผ๊ธฐ๊ฐ ์๋ค๋ฉด 6โ12๊ฐ์๊น์ง ๋ณด๊ดํ ๋ค ์ค๋๋ ํ์ ์ ๋ฆฌํด ํ ์ด๋ธ ์ฑ๋ฅ์ ์ ์งํ์ธ์.
์๋ช ์ ๊ฒ์ฆํ ๋ค์๋ง ์ฒญ๊ตฌ ๋ฐ์ดํฐ๋ฅผ ๊ฑด๋๋ฆฌ์ธ์. ์๋ช ๊ฒ์ฆ์ ๋จผ์ ํ์ง ์์ผ๋ฉด ์์กฐ๋ โ๊ฒฐ์ ์๋ฃโ ์ด๋ฒคํธ๋ก๋ถํฐ ๋ณดํธ๋ฐ์ ์ ์์ต๋๋ค. ๊ฒ์ฆ ์คํจ ์ ์์ฒญ์ ๊ฑฐ๋ถํ๊ณ ์ฒญ๊ตฌ ๋ณ๊ฒฝ์ ๊ธฐ๋กํ์ง ๋ง์ธ์.
์ด๋ฒคํธ๊ฐ ์์ ํ๊ฒ ์ ์ฅ๋ ํ์ ์์ ์ ๋น ๋ฅด๊ฒ ํ์ธํ๊ณ ๋ฌด๊ฑฐ์ด ์์ ์ ๋ฐฑ๊ทธ๋ผ์ด๋๋ก ์ฎ๊ธฐ์ธ์. ๋๋ฆฐ ํธ๋ค๋ฌ๋ ํ์์์์ ์ ๋ฐํ๊ณ , ํ์์์์ ์ฌ์๋๋ฅผ ๋๋ ค ์ค๋ณต ์ ๋ฐ์ดํธ ์ํ์ ํค์๋๋ค.
์ํ๋ฅผ ์์ผ๋ก๋ง ์ด๋์ํค๊ณ ์ค๋๋ ์ด๋ฒคํธ๋ ๋ฌด์ํ์ธ์. ๊ฐ๋ฅํ๋ฉด ์ด๋ฒคํธ ํ์์คํฌํ๋ฅผ ๋น๊ตํ๊ณ , ํ์์คํฌํ๊ฐ ์ ๋งคํ๋ฉด ์ํ ์ฐ์ ์์๋ฅผ ์ฌ์ฉํ์ธ์(์: refunded๋ paid๋ฅผ ๋ฎ์ด์ด๋ค).
๋งค ์ด๋ฒคํธ๋ง๋ค ์ ๊ถํ ํ์ ๋ง๋ค์ง ๋ง์ธ์. โ์ฌ์ฉ์/์ํ/๊ธฐ๊ฐ(๋๋ ๊ตฌ๋ ) ๋น ํ๋์ ๊ถํ์ ๋ณด์ฅโํ๋ upsert ๊ท์น์ ์ ์ฉํ๊ณ ๋ ์ง๋ ํ๋๋ฅผ ์ ๋ฐ์ดํธํ์ธ์. ์ด๋ค ์ด๋ฒคํธ ID๊ฐ ๋ณ๊ฒฝ์ ๋ฐ์์์ผฐ๋์ง ๊ธฐ๋กํด ๊ฐ์ฌํ ์ ์๊ฒ ํ์ธ์.
์ธ๋ณด์ด์ค, ๊ตฌ๋ , ๊ถํ ๋ณ๊ฒฝ์ ํ๋์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ํธ๋์ญ์ ์ผ๋ก ์์ฑํ์ธ์. ์ด๋ ๊ฒ ํ๋ฉด โ์ธ๋ณด์ด์ค๋ ๊ฒฐ์ ๋จโ์ด์ง๋ง โ์ ๊ทผ์ด ๋ถ์ฌ๋์ง ์์โ ๊ฐ์ ๋ถ๋ฆฌ๋ ์ํ๋ฅผ ๋ฐฉ์งํ ์ ์์ต๋๋ค.
์ โ ๊ฐ๋ฅํฉ๋๋ค. WebhookEvents ๋ชจ๋ธ์ ์ ๋ํฌ ์ด๋ฒคํธ ID๋ฅผ ๋ง๋ค๊ณ โ์ด๋ฏธ ๋ณด์๋๊ฐ?โ๋ฅผ ํ์ธํ๋ Business Process๋ฅผ ๊ตฌ์ถํ์ธ์. ์ธ๋ณด์ด์ค/๊ตฌ๋
/๊ถํ์ Data Designer์ ๋ช
์์ ์ผ๋ก ๋ชจ๋ธ๋งํ๋ฉด ์ฌ์๋์ ์ฌ์คํ ์ ์ค๋ณต ํ ์์ฑ์ ํผํ ์ ์์ต๋๋ค.


