Skip to content

Latest commit

ย 

History

History
546 lines (421 loc) ยท 23.5 KB

File metadata and controls

546 lines (421 loc) ยท 23.5 KB

1. ์กฐ์‚ฌ ์ฃผ์ œ ์„ ์ • ๋ฐฐ๊ฒฝ

์ด์ „์— ์กธ์—…์ž‘ํ’ˆ์œผ๋กœ ์ง„ํ–‰ํ–ˆ๋˜ Ignis ํ”„๋กœ์ ํŠธ์—์„œ ๊ฒฐ์ œ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•œ ๊ฒฝํ—˜์ด ์žˆ์—ˆ๋‹ค. ๋‹น์‹œ ํฌํŠธ์›(PortOne)์„ ํ™œ์šฉํ•˜์—ฌ ๊ฒฐ์ œ ์—ฐ๋™์„ ์™„๋ฃŒํ–ˆ์ง€๋งŒ, ๊ฒฐ์ œ ์‹œ์Šคํ…œ์˜ ๋‚ด๋ถ€ ๋™์ž‘ ์›๋ฆฌ์™€ ์ „์ฒด์ ์ธ ํ๋ฆ„์— ๋Œ€ํ•ด ๋” ๊นŠ์ด ์ดํ•ดํ•˜๊ณ  ์‹ถ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.

์ตœ๊ทผ ๋Œ€๋ถ€๋ถ„์˜ ์›น ์„œ๋น„์Šค๋Š” ์˜จ๋ผ์ธ ๊ฒฐ์ œ ๊ธฐ๋Šฅ์„ ํ•„์ˆ˜์ ์œผ๋กœ ํฌํ•จํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, ๊ฒฐ์ œ ๊ณผ์ •์€ ์‚ฌ์šฉ์ž ์ธ์ฆ, ๊ฒฐ์ œ ์Šน์ธ, ๊ฒฐ์ œ ์ƒํƒœ ์—…๋ฐ์ดํŠธ, ์ •์‚ฐ ๋“ฑ ์—ฌ๋Ÿฌ ๋‹จ๊ณ„๋กœ ๊ตฌ์„ฑ๋œ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒฐ์ œ ์‹œ์Šคํ…œ์€ ์‹ค์ œ๋กœ PG(Payment Gateway) ์—…์ฒด๋ฅผ ํ†ตํ•ด ๋ณต์žกํ•œ ์—ฐ๋™ ๊ณผ์ •์„ ๊ฑฐ์ณ ๋™์ž‘ํ•˜๋ฉฐ, ๋‚ด๋ถ€ ๊ตฌ์กฐ๊ฐ€ ๊ณต๊ฐœ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์•„ ํ•™์Šต์ž๊ฐ€ ์ „๋ฐ˜์ ์ธ ํ๋ฆ„์„ ์ดํ•ดํ•˜๊ธฐ ์–ด๋ ต๋‹ค.

์ด์— ๋”ฐ๋ผ ๋ณธ ๋ณด๊ณ ์„œ๋Š” ๊ฒฐ์ œ ํ”„๋กœ์„ธ์Šค์˜ ํ•ต์‹ฌ ์ž‘๋™ ๋ฐฉ์‹๊ณผ ๋ฐ์ดํ„ฐ ํ๋ฆ„์„ ์ง์ ‘ ์ฒดํ—˜ํ•˜๊ณ  ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด, ๊ฒฐ์ œ ๊ธฐ๋Šฅ์„ ๋‹จ์ˆœํ™”ํ•œ ํ•™์Šต์šฉ ํ† ์ด ํ”„๋กœ์ ํŠธ PayFlow๋ฅผ ์กฐ์‚ฌ ๋ฐ ๊ตฌํ˜„ ๋Œ€์ƒ์œผ๋กœ ์„ ์ •ํ•˜์˜€๋‹ค. ๋ณธ ์กฐ์‚ฌ๋Š” PayFlow ํ”„๋กœ์ ํŠธ๋ฅผ ํ†ตํ•ด ๊ฒฐ์ œ ๋ชจ๋ธ์˜ ๊ตฌ์„ฑ ์š”์†Œ, ๋ฐฑ์—”๋“œ ๊ตฌ์กฐ, ์ƒํƒœ ๊ด€๋ฆฌ ๋ฐฉ์‹ ๋“ฑ์„ ๋ถ„์„ํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•œ๋‹ค.


2. ์กฐ์‚ฌ ๋ชฉ์ 

๋ณธ ์กฐ์‚ฌ์˜ ๋ชฉ์ ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  1. ์‹ค์ œ ๊ฒฐ์ œ ์‹œ์Šคํ…œ์ด ๊ฐ–์ถ”์–ด์•ผ ํ•˜๋Š” ๊ธฐ๋ณธ ๊ธฐ๋Šฅ๊ณผ ๊ตฌ์กฐ๋ฅผ ์ดํ•ดํ•œ๋‹ค.
  2. ๊ฒฐ์ œ ์ƒ์„ฑ โ†’ PG ์Šน์ธ โ†’ ์ƒํƒœ ์กฐํšŒ ๊ณผ์ •์˜ ํ๋ฆ„์„ ์ง์ ‘ ๊ตฌ์„ฑํ•˜์—ฌ ๋ฐฑ์—”๋“œ ๋™์ž‘ ์›๋ฆฌ๋ฅผ ๋ถ„์„ํ•œ๋‹ค.
  3. ๊ฐ„๋‹จํ•œ Payment ๋ฐ์ดํ„ฐ ๋ชจ๋ธ์„ ์„ค๊ณ„ํ•จ์œผ๋กœ์จ ์ƒํƒœ ๊ธฐ๋ฐ˜(State-based) ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๊ฐœ๋…์„ ํ•™์Šตํ•œ๋‹ค.
  4. Spring Boot ๊ธฐ๋ฐ˜์˜ ๊ฒฐ์ œ ์ฒ˜๋ฆฌ ์‹œ์Šคํ…œ ์ „์ฒด ๊ตฌ์กฐ๋ฅผ ์กฐ์‚ฌํ•˜๊ณ  ๊ตฌํ˜„ํ•˜์—ฌ ์‹ค๋ฌด์ ์ธ ๊ฐ๊ฐ์„ ๊ธฐ๋ฅธ๋‹ค.
  5. ํฌํŠธ์›(PortOne) V2 Checkout SDK ์‹ค์ œ ์—ฐ๋™์„ ํ†ตํ•ด PG ์—ฐ๋™ ๊ฒฝํ—˜์„ ํ™•๋ณดํ•œ๋‹ค.

3. ์กฐ์‚ฌ ๋‚ด์šฉ

3-1. PayFlow ํ”„๋กœ์ ํŠธ ๊ฐœ์š”

PayFlow๋Š” Spring Boot 3.2.2 + Java 17 ๊ธฐ๋ฐ˜์˜ ๊ฐ„๋‹จํ•œ ๊ฒฐ์ œ ์ฒ˜๋ฆฌ ์‹œ์Šคํ…œ์œผ๋กœ, ์‚ฌ์šฉ์ž๊ฐ€ ๊ฒฐ์ œ ์ •๋ณด๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ์„œ๋ฒ„์—์„œ ๊ฒฐ์ œ ๋ฐ์ดํ„ฐ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ํฌํŠธ์›(PortOne) V2 Checkout SDK๋ฅผ ํ†ตํ•ด ์‹ค์ œ ๊ฒฐ์ œ ์Šน์ธ์„ ์ฒ˜๋ฆฌํ•œ๋‹ค. ์ดํ›„ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ํ•ด๋‹น ๋‚ด์—ญ์„ ์ €์žฅํ•˜๊ณ , ๊ฒฐ์ œ ์ƒ์„ธ ํŽ˜์ด์ง€์—์„œ ๊ฒฐ๊ณผ๋ฅผ ์กฐํšŒํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.

๋ณธ ํ”„๋กœ์ ํŠธ๋Š” "๊ฒฐ์ œ ์š”์ฒญ โ†’ PG ์Šน์ธ ์ฒ˜๋ฆฌ โ†’ ์ƒํƒœ ๋ณ€๊ฒฝ" ๊ณผ์ •์„ ์ค‘์‹ฌ์œผ๋กœ ๊ตฌ์„ฑํ•˜์˜€์œผ๋ฉฐ, ์‹ค์ œ ํฌํŠธ์› V2 API๋ฅผ ํ†ตํ•œ ์‹ค๊ฒฐ์ œ ์—ฐ๋™์„ ๊ตฌํ˜„ํ•˜์˜€๋‹ค.

๊ธฐ์ˆ  ์Šคํƒ

๊ตฌ๋ถ„ ๊ธฐ์ˆ 
Backend Spring Boot 3.2.2, Java 17
ORM Spring Data JPA, Hibernate
Database MySQL 8.x
Template Engine Thymeleaf
Build Tool Gradle
PG ์—ฐ๋™ ํฌํŠธ์› V2 Checkout SDK
๋ณด์•ˆ Spring Security Crypto (BCrypt)

3-2. PG์‚ฌ(Payment Gateway) ์ข…๋ฅ˜ ๋ฐ ๋น„๊ต ์กฐ์‚ฌ

๊ฒฐ์ œ ์‹œ์Šคํ…œ ๊ตฌํ˜„ ์‹œ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋‹ค์–‘ํ•œ PG์‚ฌ๋“ค์ด ์กด์žฌํ•œ๋‹ค. ๊ฐ PG์‚ฌ๋ณ„ ํŠน์ง•์„ ์กฐ์‚ฌํ•˜์˜€๋‹ค.

๊ตญ๋‚ด ์ฃผ์š” PG์‚ฌ

PG์‚ฌ ํŠน์ง• ์—ฐ๋™ ๋ฐฉ์‹
ํฌํŠธ์›(PortOne) ์—ฌ๋Ÿฌ PG์‚ฌ๋ฅผ ํ†ตํ•ฉ ์—ฐ๋™ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฐ์ œ ๋Œ€ํ–‰ ์„œ๋น„์Šค. ํ•˜๋‚˜์˜ API๋กœ ๋‹ค์–‘ํ•œ PG์‚ฌ ์—ฐ๋™ ๊ฐ€๋Šฅ. Checkout V2 SDK ์ œ๊ณต REST API + JavaScript SDK
ํ† ์ŠคํŽ˜์ด๋จผ์ธ  ํ† ์Šค ๊ณ„์—ด PG์‚ฌ. ๊น”๋”ํ•œ API ๋ฌธ์„œ์™€ ๊ฐœ๋ฐœ์ž ์นœํ™”์  ํ™˜๊ฒฝ ์ œ๊ณต. ๊ฒฐ์ œ์œ„์ ฏ(Payment Widget) ๋ฐฉ์‹ ์ง€์› REST API + JavaScript SDK
NHN KCP ์˜ค๋ž˜๋œ PG์‚ฌ ์ค‘ ํ•˜๋‚˜๋กœ ์•ˆ์ •์ ์ธ ์„œ๋น„์Šค ์ œ๊ณต. ๋‹ค์–‘ํ•œ ๊ฒฐ์ œ ์ˆ˜๋‹จ ์ง€์› REST API + Server-to-Server
์ด๋‹ˆ์‹œ์Šค(INICIS) KG์ด๋‹ˆ์‹œ์Šค. ๊ตญ๋‚ด ์ ์œ ์œจ 1์œ„ PG์‚ฌ. ๋Œ€ํ˜• ์‡ผํ•‘๋ชฐ์—์„œ ๋งŽ์ด ์‚ฌ์šฉ REST API + JavaScript SDK
๋‹ค๋‚  ํœด๋Œ€ํฐ ๊ฒฐ์ œ์— ๊ฐ•์ . ์†Œ์•ก๊ฒฐ์ œ ์„œ๋น„์Šค ์ „๋ฌธ REST API
์นด์นด์˜คํŽ˜์ด ๊ฐ„ํŽธ๊ฒฐ์ œ ์„œ๋น„์Šค. ์นด์นด์˜คํ†ก ์•ฑ ์—ฐ๋™. ๋น ๋ฅธ ๊ฒฐ์ œ ๊ฒฝํ—˜ ์ œ๊ณต REST API + Redirect
๋„ค์ด๋ฒ„ํŽ˜์ด ๋„ค์ด๋ฒ„ ๊ฐ„ํŽธ๊ฒฐ์ œ. ๋„ค์ด๋ฒ„ ์‡ผํ•‘๊ณผ ์—ฐ๊ณ„ ์‹œ ์œ ๋ฆฌ REST API + JavaScript SDK

ํฌํŠธ์›(PortOne) ์„ ํƒ ์ด์œ 

๋ณธ ํ”„๋กœ์ ํŠธ์—์„œ **ํฌํŠธ์›(PortOne)**์„ ์„ ํƒํ•œ ์ด์œ ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค:

  1. ํ†ตํ•ฉ ์—ฐ๋™: ํ•˜๋‚˜์˜ API๋กœ ํ† ์ŠคํŽ˜์ด๋จผ์ธ , ์ด๋‹ˆ์‹œ์Šค, KCP ๋“ฑ ๋‹ค์–‘ํ•œ PG์‚ฌ๋ฅผ ์—ฐ๋™ํ•  ์ˆ˜ ์žˆ์Œ
  2. V2 Checkout SDK: ์ตœ์‹  JavaScript SDK๋กœ ๊ฐ„ํŽธํ•˜๊ฒŒ ๊ฒฐ์ œ์ฐฝ ํ˜ธ์ถœ ๊ฐ€๋Šฅ
  3. ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ: ๋ณ„๋„์˜ ์‚ฌ์—…์ž๋“ฑ๋ก ์—†์ด ํ…Œ์ŠคํŠธ ๊ฒฐ์ œ ์ง„ํ–‰ ๊ฐ€๋Šฅ
  4. ๋ฌธ์„œํ™”: ๊ฐœ๋ฐœ์ž ์นœํ™”์ ์ธ API ๋ฌธ์„œ ๋ฐ ์˜ˆ์ œ ์ฝ”๋“œ ์ œ๊ณต

์ฐธ๊ณ : ํ† ์ŠคํŽ˜์ด๋จผ์ธ ๋Š” ๋ณธ ํ”„๋กœ์ ํŠธ์—์„œ ์ง์ ‘ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜์ง€๋งŒ, ํ–ฅํ›„ ๋น„๊ต ์—ฐ๋™์„ ์œ„ํ•ด ๊ด€์‹ฌ ์žˆ๋Š” PG์‚ฌ๋กœ ์กฐ์‚ฌํ•˜์˜€๋‹ค. ํ† ์ŠคํŽ˜์ด๋จผ์ธ ๋Š” Payment Widget ๋ฐฉ์‹์„ ์ œ๊ณตํ•˜์—ฌ ํ”„๋ก ํŠธ์—”๋“œ์—์„œ ๊ฐ„ํŽธํ•˜๊ฒŒ ๊ฒฐ์ œ์ฐฝ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ํŠน์ง•์ด ์žˆ๋‹ค.

PG์‚ฌ ์—ฐ๋™ ๋ฐฉ์‹ ๋น„๊ต

flowchart LR
    subgraph Direct["์ง์ ‘ ์—ฐ๋™ ๋ฐฉ์‹"]
        A[ํ† ์ŠคํŽ˜์ด๋จผ์ธ ] --> B[๊ฐ PG์‚ฌ๋ณ„ ๊ฐœ๋ณ„ ์—ฐ๋™]
        C[์ด๋‹ˆ์‹œ์Šค] --> B
        D[KCP] --> B
    end
    
    subgraph Aggregator["ํ†ตํ•ฉ ์—ฐ๋™ ๋ฐฉ์‹"]
        E[ํฌํŠธ์›] --> F[๋‹จ์ผ API๋กœ ํ†ตํ•ฉ ๊ด€๋ฆฌ]
        F --> G[ํ† ์ŠคํŽ˜์ด๋จผ์ธ ]
        F --> H[์ด๋‹ˆ์‹œ์Šค]
        F --> I[KCP]
    end
Loading

3-3. ์‹œ์Šคํ…œ ๊ตฌ์„ฑ๋„

flowchart TB
    subgraph Client["๐Ÿ‘ค ํด๋ผ์ด์–ธํŠธ"]
        A[์‚ฌ์šฉ์ž ์š”์ฒญ]
    end

    subgraph Controller["โ‘  Controller ๊ณ„์ธต"]
        B[PaymentController - ํŽ˜์ด์ง€ ๋ Œ๋”๋ง]
        C[PaymentRestController - API ์ˆ˜์‹ ]
    end

    subgraph BO["โ‘ก BO ๊ณ„์ธต (Business Object)"]
        E[PaymentBO - ๊ฒฐ์ œ ์ƒ์„ฑ/์ƒํƒœ ์—…๋ฐ์ดํŠธ]
    end

    subgraph Client_Layer["โ‘ข PG Client ๊ณ„์ธต"]
        F[PgClient Interface]
        G[PortOneClient]
    end

    subgraph Repository["โ‘ฃ Repository ๊ณ„์ธต"]
        I[PaymentRepository]
        J[UserRepository]
    end

    subgraph DB["โ‘ค DB ๊ณ„์ธต (MySQL)"]
        K[(payflow Database)]
    end

    subgraph PG["โ‘ฅ PG์‚ฌ"]
        L[ํฌํŠธ์› V2 API]
        M[์ด๋‹ˆ์‹œ์Šค ์‹ค๊ฒฐ์ œ]
    end

    A --> B
    A --> C
    B --> E
    C --> E
    E --> F
    F --> G
    G --> L
    L --> M
    E --> I
    E --> J
    I --> K
    J --> K
Loading
๊ณ„์ธต ์—ญํ•  ์ฃผ์š” ํด๋ž˜์Šค
โ‘  Controller ๊ณ„์ธต ํŽ˜์ด์ง€ ๋ Œ๋”๋ง ๋ฐ API ์š”์ฒญ ์ฒ˜๋ฆฌ PaymentController, PaymentRestController
โ‘ก BO ๊ณ„์ธต ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ๋‹ด๋‹น PaymentBO
โ‘ข PG Client ๊ณ„์ธต PG์‚ฌ ์—ฐ๋™ ์ถ”์ƒํ™” PgClient, PortOneClient
โ‘ฃ Repository ๊ณ„์ธต ๋ฐ์ดํ„ฐ ์˜์†์„ฑ ๋‹ด๋‹น PaymentRepository, UserRepository
โ‘ค DB ๊ณ„์ธต ๋ฐ์ดํ„ฐ ์ €์žฅ MySQL (payflow DB)
โ‘ฅ PG์‚ฌ ์‹ค์ œ ๊ฒฐ์ œ ์ฒ˜๋ฆฌ ํฌํŠธ์› โ†’ ์ด๋‹ˆ์‹œ์Šค

3-4. ํฌํŠธ์› V2 ๊ฒฐ์ œ ์ฒ˜๋ฆฌ ํ๋ฆ„(Flow)

ํฌํŠธ์› V2 Checkout SDK๋ฅผ ์‚ฌ์šฉํ•œ ์‹ค์ œ ๊ฒฐ์ œ ํ๋ฆ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค:

sequenceDiagram
    participant Client as ๐Ÿ‘ค ํด๋ผ์ด์–ธํŠธ
    participant Server as ๐Ÿ–ฅ๏ธ PayFlow ์„œ๋ฒ„
    participant PortOne as ๐Ÿ’ณ ํฌํŠธ์› V2 SDK
    participant PG as ๐Ÿฆ PG์‚ฌ (์ด๋‹ˆ์‹œ์Šค)

    Client->>Server: 1. ๊ฒฐ์ œ ์ƒ์„ฑ ์š”์ฒญ (POST /api/pay/create)
    Note over Server: userId, amount, method
    Server->>Server: 2. Payment ์—”ํ‹ฐํ‹ฐ ์ƒ์„ฑ<br/>(status: ready, orderId ์ƒ์„ฑ)
    Server->>Client: 3. orderId ๋ฐ˜ํ™˜ ๋ฐ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
    Client->>Server: 4. ๊ฒฐ์ œ ์š”์ฒญ ํŽ˜์ด์ง€ (GET /pay/request/{orderId})
    Server->>Server: 5. ํฌํŠธ์› ํŒŒ๋ผ๋ฏธํ„ฐ ์ค€๋น„<br/>(storeId, channelKey, amount ๋“ฑ)
    Server->>Client: 6. ํฌํŠธ์› V2 SDK ํŒŒ๋ผ๋ฏธํ„ฐ ์ „๋‹ฌ
    Client->>PortOne: 7. PortOne.requestPayment() ํ˜ธ์ถœ
    Note over Client,PortOne: ๊ฒฐ์ œ์ฐฝ ํ‘œ์‹œ
    PortOne->>PG: 8. ๊ฒฐ์ œ ์Šน์ธ ์š”์ฒญ
    PG->>PortOne: 9. ๊ฒฐ์ œ ์Šน์ธ ๊ฒฐ๊ณผ
    PortOne->>Client: 10. paymentId ๋ฐ˜ํ™˜ (์„ฑ๊ณต ์‹œ)
    Client->>Server: 11. ๊ฒฐ์ œ ์„ฑ๊ณต ์ฝœ๋ฐฑ (GET /pay/success)
    Note over Server: paymentId, orderId
    Server->>Server: 12. ๊ฒฐ์ œ ์ƒํƒœ ์—…๋ฐ์ดํŠธ<br/>(status: paid, pg_tid ์ €์žฅ)
    Server->>Client: 13. ๊ฒฐ์ œ ์™„๋ฃŒ ํŽ˜์ด์ง€ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
Loading

์ƒ์„ธ ๋‹จ๊ณ„ ์„ค๋ช…:

  1. ๊ฒฐ์ œ ์ƒ์„ฑ ์š”์ฒญ: ์‚ฌ์šฉ์ž๊ฐ€ ๊ธˆ์•ก๊ณผ ๊ฒฐ์ œ ์ˆ˜๋‹จ์„ ์„ ํƒํ•˜์—ฌ POST /api/pay/create๋กœ ๊ฒฐ์ œ ์ƒ์„ฑ ์š”์ฒญ

    • ์„ธ์…˜์—์„œ userId ์ž๋™ ์ถ”์ถœ
    • amount, method ํŒŒ๋ผ๋ฏธํ„ฐ ์ˆ˜์‹ 
  2. Payment ์—”ํ‹ฐํ‹ฐ ์ƒ์„ฑ: ์„œ๋ฒ„์—์„œ ORD-{timestamp} ํ˜•์‹์˜ ์ฃผ๋ฌธ๋ฒˆํ˜ธ ์ƒ์„ฑ

    • ์ดˆ๊ธฐ ์ƒํƒœ: ready
    • createdAt, updatedAt ์ž๋™ ์„ค์ •
  3. ๊ฒฐ์ œ ์š”์ฒญ ํŽ˜์ด์ง€: GET /pay/request/{orderId}๋กœ ๊ฒฐ์ œ์ฐฝ ํ˜ธ์ถœ ํŽ˜์ด์ง€ ๋ Œ๋”๋ง

    • ํฌํŠธ์› V2 SDK ํŒŒ๋ผ๋ฏธํ„ฐ ์ค€๋น„:
      • storeId: ํฌํŠธ์› ์Šคํ† ์–ด ID
      • channelKey: ํฌํŠธ์› ์ฑ„๋„ ํ‚ค (V2 ํ•„์ˆ˜)
      • orderId, amount, orderName
      • payMethod: CARD ๋˜๋Š” VBANK
      • customer: ๊ตฌ๋งค์ž ์ •๋ณด (fullName, phoneNumber, email)
      • successUrl, failUrl: ์ฝœ๋ฐฑ URL
  4. ๊ฒฐ์ œ์ฐฝ ํ˜ธ์ถœ: ํ”„๋ก ํŠธ์—”๋“œ์—์„œ PortOne.requestPayment() ํ•จ์ˆ˜ ์‹คํ–‰

    • ํฌํŠธ์› V2 SDK๊ฐ€ ๊ฒฐ์ œ์ฐฝ์„ ์ž๋™์œผ๋กœ ํ‘œ์‹œ
    • ์‚ฌ์šฉ์ž๊ฐ€ ๊ฒฐ์ œ ์ˆ˜๋‹จ ์„ ํƒ ๋ฐ ์ธ์ฆ ์ง„ํ–‰
  5. PG์‚ฌ ๊ฒฐ์ œ ์ฒ˜๋ฆฌ: ํฌํŠธ์›์„ ํ†ตํ•ด ์‹ค์ œ PG์‚ฌ(์ด๋‹ˆ์‹œ์Šค)๋กœ ๊ฒฐ์ œ ์Šน์ธ ์š”์ฒญ

    • ํฌํŠธ์›์ด ๋‚ด๋ถ€์ ์œผ๋กœ ์ด๋‹ˆ์‹œ์Šค API ํ˜ธ์ถœ
    • ์นด๋“œ์‚ฌ ์Šน์ธ ์ฒ˜๋ฆฌ
  6. ๊ฒฐ์ œ ๊ฒฐ๊ณผ ์ฒ˜๋ฆฌ:

    • ์„ฑ๊ณต ์‹œ: paymentId๋ฅผ ๋ฐ›์•„ successUrl๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
    • ์‹คํŒจ ์‹œ: ์—๋Ÿฌ ๋ฉ”์‹œ์ง€์™€ ํ•จ๊ป˜ failUrl๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
  7. ์„œ๋ฒ„ ์ฝœ๋ฐฑ ์ฒ˜๋ฆฌ: GET /pay/success ๋˜๋Š” GET /pay/fail ์—”๋“œํฌ์ธํŠธ ํ˜ธ์ถœ

    • ์„ฑ๊ณต: PaymentBO.updatePaymentSuccess() ํ˜ธ์ถœ
      • orderId๋กœ Payment ์กฐํšŒ
      • status๋ฅผ paid๋กœ ๋ณ€๊ฒฝ
      • pg_tid์— paymentId ์ €์žฅ
      • pg_response์— "SUCCESS" ์ €์žฅ
    • ์‹คํŒจ: PaymentBO.updatePaymentFail() ํ˜ธ์ถœ
      • status๋ฅผ failed๋กœ ๋ณ€๊ฒฝ
      • pg_response์— ์‹คํŒจ ์‚ฌ์œ  ์ €์žฅ
  8. ๊ฒฐ์ œ ์™„๋ฃŒ ํŽ˜์ด์ง€: ์ตœ์ข… ๊ฒฐ๊ณผ๋ฅผ ์‚ฌ์šฉ์ž์—๊ฒŒ ํ‘œ์‹œ

ํฌํŠธ์› V2 Checkout SDK ํŠน์ง•

  • ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๊ฒฐ์ œ: ์„œ๋ฒ„์—์„œ ๋ณ„๋„์˜ ์Šน์ธ API ํ˜ธ์ถœ ์—†์ด ํด๋ผ์ด์–ธํŠธ์—์„œ ์ง์ ‘ ๊ฒฐ์ œ ์ฒ˜๋ฆฌ
  • ์ž๋™ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ: ๊ฒฐ์ œ ์™„๋ฃŒ ํ›„ ์ž๋™์œผ๋กœ successUrl ๋˜๋Š” failUrl๋กœ ์ด๋™
  • ๊ฐ„ํŽธํ•œ ์—ฐ๋™: ๋ณต์žกํ•œ ์„œ๋ฒ„-์„œ๋ฒ„ ํ†ต์‹  ์—†์ด JavaScript SDK๋งŒ์œผ๋กœ ๊ตฌํ˜„ ๊ฐ€๋Šฅ
  • ํ†ตํ•ฉ PG ๊ด€๋ฆฌ: ํ•˜๋‚˜์˜ ์ฑ„๋„ ํ‚ค๋กœ ์—ฌ๋Ÿฌ PG์‚ฌ๋ฅผ ์ž๋™ ์„ ํƒ

3-5. ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ตฌ์กฐ ์กฐ์‚ฌ

ER ๋‹ค์ด์–ด๊ทธ๋žจ

erDiagram
    users ||--o{ payments : "has"
    payments ||--o{ payment_logs : "logs"
    payments ||--o{ webhook_callback : "receives"
    payments ||--o{ refunds : "may have"

    users {
        BIGINT id PK
        VARCHAR name
        VARCHAR email
        DATETIME created_at
    }

    payments {
        BIGINT id PK
        BIGINT user_id FK
        VARCHAR order_id UK
        INT amount
        VARCHAR status
        VARCHAR method
        DATETIME created_at
        DATETIME updated_at
    }

    payment_logs {
        BIGINT id PK
        BIGINT payment_id FK
        VARCHAR log_type
        TEXT message
        DATETIME created_at
    }

    webhook_callback {
        BIGINT id PK
        BIGINT payment_id FK
        TEXT pg_data
        DATETIME created_at
    }

    refunds {
        BIGINT id PK
        BIGINT payment_id FK
        INT refund_amount
        VARCHAR reason
        DATETIME created_at
    }
Loading

ํ…Œ์ด๋ธ” ์ƒ์„ธ ์„ค๋ช…

1) users (์‚ฌ์šฉ์ž ํ…Œ์ด๋ธ”)
์ปฌ๋Ÿผ๋ช… ํƒ€์ž… ์„ค๋ช…
id BIGINT ๊ธฐ๋ณธํ‚ค(PK), AUTO_INCREMENT
name VARCHAR(50) ์‚ฌ์šฉ์ž ์ด๋ฆ„
email VARCHAR(100) ์‚ฌ์šฉ์ž ์ด๋ฉ”์ผ
created_at DATETIME ์ƒ์„ฑ์ผ (๊ธฐ๋ณธ๊ฐ’: CURRENT_TIMESTAMP)
2) payments (๊ฒฐ์ œ ํ…Œ์ด๋ธ”)
์ปฌ๋Ÿผ๋ช… ํƒ€์ž… ์„ค๋ช…
id BIGINT ๊ธฐ๋ณธํ‚ค(PK), AUTO_INCREMENT
user_id BIGINT ์‚ฌ์šฉ์ž ์‹๋ณ„์ž (FK โ†’ users.id)
order_id VARCHAR(100) ์ฃผ๋ฌธ ์‹๋ณ„์ž (UNIQUE) - ORD-{timestamp} ํ˜•์‹
amount INT ๊ฒฐ์ œ ๊ธˆ์•ก (NOT NULL)
status VARCHAR(20) ๊ฒฐ์ œ ์ƒํƒœ (๊ธฐ๋ณธ๊ฐ’: 'ready')
method VARCHAR(20) ๊ฒฐ์ œ ๋ฐฉ์‹ (CARD/VBANK ๋“ฑ)
created_at DATETIME ์ƒ์„ฑ์ผ
updated_at DATETIME ์ˆ˜์ •์ผ (ON UPDATE ์ž๋™ ๊ฐฑ์‹ )

๊ฒฐ์ œ ์ƒํƒœ(status) ๊ฐ’:

PayFlow ์„ค๋ช…
ready ๊ฒฐ์ œ ๋Œ€๊ธฐ
paid ๊ฒฐ์ œ ์™„๋ฃŒ
failed ๊ฒฐ์ œ ์‹คํŒจ

์ฐธ๊ณ : ์—”ํ‹ฐํ‹ฐ ํด๋ž˜์Šค(Payment.java)์—๋Š” pg_tid, pg_response ์ปฌ๋Ÿผ์ด ์ •์˜๋˜์–ด ์žˆ์œผ๋‚˜, ์ดˆ๊ธฐ DB ์Šคํ‚ค๋งˆ์—๋Š” ํฌํ•จ๋˜์ง€ ์•Š์•˜๋‹ค. ์ด๋Š” JPA์˜ ddl-auto: update ์„ค์ •์— ์˜ํ•ด ์ž๋™์œผ๋กœ ์ถ”๊ฐ€๋˜๊ฑฐ๋‚˜, ์ถ”ํ›„ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ํ†ตํ•ด ์ถ”๊ฐ€๋  ์˜ˆ์ •์ด๋‹ค.

3) payment_logs (๊ฒฐ์ œ ๋กœ๊ทธ ํ…Œ์ด๋ธ”)
์ปฌ๋Ÿผ๋ช… ํƒ€์ž… ์„ค๋ช…
id BIGINT ๊ธฐ๋ณธํ‚ค(PK), AUTO_INCREMENT
payment_id BIGINT ๊ฒฐ์ œ ์‹๋ณ„์ž (FK โ†’ payments.id)
log_type VARCHAR(20) ๋กœ๊ทธ ์œ ํ˜• (REQUEST, RESPONSE, ERROR ๋“ฑ)
message TEXT ๋กœ๊ทธ ๋ฉ”์‹œ์ง€ (PG ์‘๋‹ต ๋ฐ์ดํ„ฐ ํฌํ•จ)
created_at DATETIME ์ƒ์„ฑ์ผ

๊ฒฐ์ œ ๊ณผ์ •์˜ ๋ชจ๋“  ๋กœ๊ทธ๋ฅผ ๊ธฐ๋กํ•˜์—ฌ ๋””๋ฒ„๊น… ๋ฐ ๊ฐ์‚ฌ(Audit) ๋ชฉ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

4) webhook_callback (PG Callback ์ €์žฅ ํ…Œ์ด๋ธ”)
์ปฌ๋Ÿผ๋ช… ํƒ€์ž… ์„ค๋ช…
id BIGINT ๊ธฐ๋ณธํ‚ค(PK), AUTO_INCREMENT
payment_id BIGINT ๊ฒฐ์ œ ์‹๋ณ„์ž (FK โ†’ payments.id)
pg_data TEXT PG์‚ฌ๋กœ๋ถ€ํ„ฐ ๋ฐ›์€ Webhook ์ฝœ๋ฐฑ ๋ฐ์ดํ„ฐ (JSON)
created_at DATETIME ์ƒ์„ฑ์ผ

ํฌํŠธ์›์˜ ๊ฒฝ์šฐ ๊ฐ€์ƒ๊ณ„์ขŒ ์ž…๊ธˆ ํ™•์ธ, ๊ฒฐ์ œ ์ทจ์†Œ ๋“ฑ์˜ ์ด๋ฒคํŠธ๋ฅผ Webhook์œผ๋กœ ์ „๋‹ฌ๋ฐ›์„ ์ˆ˜ ์žˆ๋‹ค. ๋ณธ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ์•„์ง ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•˜์œผ๋‚˜, ํ–ฅํ›„ ํ™•์žฅ์„ ์œ„ํ•ด ํ…Œ์ด๋ธ”์„ ๋ฏธ๋ฆฌ ์„ค๊ณ„ํ•˜์˜€๋‹ค.

5) refunds (ํ™˜๋ถˆ ํ…Œ์ด๋ธ”)
์ปฌ๋Ÿผ๋ช… ํƒ€์ž… ์„ค๋ช…
id BIGINT ๊ธฐ๋ณธํ‚ค(PK), AUTO_INCREMENT
payment_id BIGINT ๊ฒฐ์ œ ์‹๋ณ„์ž (FK โ†’ payments.id)
refund_amount INT ํ™˜๋ถˆ ๊ธˆ์•ก (NOT NULL)
reason VARCHAR(255) ํ™˜๋ถˆ ์‚ฌ์œ 
created_at DATETIME ์ƒ์„ฑ์ผ

ํฌํŠธ์› ํ™˜๋ถˆ API ํ˜ธ์ถœ ํ›„ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•œ๋‹ค. ๋ณธ ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ์•„์ง ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•˜์œผ๋‚˜, ํ–ฅํ›„ ํ™•์žฅ์„ ์œ„ํ•ด ํ…Œ์ด๋ธ”์„ ๋ฏธ๋ฆฌ ์„ค๊ณ„ํ•˜์˜€๋‹ค.


3-6. ๊ธฐ์ˆ ์  ์กฐ์‚ฌ (Spring Boot ๋‚ด๋ถ€ ๊ตฌ์กฐ)

ํ”„๋กœ์ ํŠธ ํŒจํ‚ค์ง€ ๊ตฌ์กฐ

com.payflow
โ”œโ”€โ”€ PayFlowApplication.java          # Spring Boot ๋ฉ”์ธ ํด๋ž˜์Šค
โ”œโ”€โ”€ controller
โ”‚   โ””โ”€โ”€ WelcomeController.java       # ๋ฉ”์ธ ํŽ˜์ด์ง€ ์ปจํŠธ๋กค๋Ÿฌ
โ”œโ”€โ”€ payment
โ”‚   โ”œโ”€โ”€ PaymentController.java       # ๊ฒฐ์ œ ํŽ˜์ด์ง€ ๋ Œ๋”๋ง
โ”‚   โ”œโ”€โ”€ PaymentRestController.java   # ๊ฒฐ์ œ REST API
โ”‚   โ”œโ”€โ”€ bo
โ”‚   โ”‚   โ””โ”€โ”€ PaymentBO.java           # ๊ฒฐ์ œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง
โ”‚   โ”œโ”€โ”€ client
โ”‚   โ”‚   โ”œโ”€โ”€ PgClient.java            # PG ํด๋ผ์ด์–ธํŠธ ์ธํ„ฐํŽ˜์ด์Šค
โ”‚   โ”‚   โ”œโ”€โ”€ PortOneClient.java       # ํฌํŠธ์› V2 ๊ตฌํ˜„์ฒด
โ”‚   โ”‚   โ””โ”€โ”€ PgResponse.java          # PG ์‘๋‹ต DTO
โ”‚   โ”œโ”€โ”€ domain
โ”‚   โ”‚   โ””โ”€โ”€ Payment.java             # ๊ฒฐ์ œ ์—”ํ‹ฐํ‹ฐ
โ”‚   โ””โ”€โ”€ repository
โ”‚       โ””โ”€โ”€ PaymentRepository.java   # ๊ฒฐ์ œ JPA Repository
โ””โ”€โ”€ user
    โ”œโ”€โ”€ UserController.java          # ์‚ฌ์šฉ์ž ์ปจํŠธ๋กค๋Ÿฌ
    โ”œโ”€โ”€ bo
    โ”‚   โ””โ”€โ”€ UserBO.java              # ์‚ฌ์šฉ์ž ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง
    โ”œโ”€โ”€ domain
    โ”‚   โ””โ”€โ”€ User.java                # ์‚ฌ์šฉ์ž ์—”ํ‹ฐํ‹ฐ
    โ””โ”€โ”€ repository
        โ””โ”€โ”€ UserRepository.java      # ์‚ฌ์šฉ์ž JPA Repository

๊ณ„์ธต๋ณ„ ์—ญํ• 

flowchart LR
    subgraph Presentation["Presentation Layer"]
        A[PaymentController]
        B[PaymentRestController]
    end

    subgraph Business["Business Layer"]
        C[PaymentBO]
        D[PgClient Interface]
    end

    subgraph Data["Data Access Layer"]
        E[PaymentRepository]
    end

    subgraph External["External - PG์‚ฌ"]
        F[ํฌํŠธ์› V2 API]
    end

    A --> C
    B --> C
    C --> D
    C --> E
    D --> F
Loading
๊ตฌ์„ฑ ์š”์†Œ ์—ญํ• 
PaymentController ๊ฒฐ์ œ ์ƒ์„ฑ/์š”์ฒญ/๊ฒฐ๊ณผ ํŽ˜์ด์ง€ ๋ Œ๋”๋ง, Thymeleaf ๋ทฐ ๋ฐ˜ํ™˜
PaymentRestController REST API ์—”๋“œํฌ์ธํŠธ ์ œ๊ณต, JSON ์‘๋‹ต (/api/pay/create)
PaymentBO ํ•ต์‹ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ๋‹ด๋‹น, ๊ฒฐ์ œ ์ƒ์„ฑ/์ƒํƒœ ์—…๋ฐ์ดํŠธ/๋ชฉ๋ก ์กฐํšŒ
PgClient PG์‚ฌ ์—ฐ๋™ ์ธํ„ฐํŽ˜์ด์Šค (Strategy Pattern)
PortOneClient ํฌํŠธ์› V2 ๊ตฌํ˜„์ฒด (Checkout V2๋Š” ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ์—์„œ ์ฒ˜๋ฆฌ๋˜๋ฏ€๋กœ ์ธํ„ฐํŽ˜์ด์Šค๋งŒ ๊ตฌํ˜„)
PaymentRepository JPA๋ฅผ ํ†ตํ•œ ๊ฒฐ์ œ ๋ฐ์ดํ„ฐ CRUD

์ฃผ์š” ์„ค์ • (application.yml)

# PG์‚ฌ ์„ค์ •
pg:
  type: portOneClient
  
  portone:
    store-id: store-xxx
    channel-key: channel-key-xxx
    api-url: https://api.portone.io
    success-url: http://localhost/pay/success
    fail-url: http://localhost/pay/fail

3-7. ํฌํŠธ์› V2 ์—ฐ๋™ ์ƒ์„ธ

Checkout V2 SDK ์‚ฌ์šฉ๋ฒ•

ํ”„๋ก ํŠธ์—”๋“œ์—์„œ ํฌํŠธ์› V2 SDK๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒฐ์ œ์ฐฝ์„ ํ˜ธ์ถœํ•œ๋‹ค:

<!-- PortOne Checkout V2 SDK -->
<script src="https://cdn.portone.io/v2/browser-sdk.js"></script>

<script>
const response = await PortOne.requestPayment({
    storeId: "store-xxx",
    channelKey: "channel-key-xxx",
    paymentId: "PAY-" + Date.now(),
    orderName: "PayFlow ๊ฒฐ์ œ",
    totalAmount: 10000,
    payMethod: "CARD",
    currency: "KRW",
    customer: {
        fullName: "ํ…Œ์ŠคํŠธ์‚ฌ์šฉ์ž",
        phoneNumber: "01012345678",
        email: "test@example.com"
    },
    redirectUrl: "http://localhost/pay/success"
});
</script>

๊ฒฐ์ œ ์ˆ˜๋‹จ ๋งคํ•‘

PayFlow ํฌํŠธ์› V2
card CARD
vbank VBANK

ํฌํŠธ์› V2์˜ ์ฃผ์š” ํŠน์ง•

  1. ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๊ฒฐ์ œ: ์„œ๋ฒ„์—์„œ ๋ณ„๋„์˜ ์Šน์ธ API ํ˜ธ์ถœ ์—†์ด ํด๋ผ์ด์–ธํŠธ์—์„œ ์ง์ ‘ ๊ฒฐ์ œ ์ฒ˜๋ฆฌ
  2. ์ž๋™ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ: ๊ฒฐ์ œ ์™„๋ฃŒ ํ›„ ์ž๋™์œผ๋กœ successUrl ๋˜๋Š” failUrl๋กœ ์ด๋™
  3. ๊ฐ„ํŽธํ•œ ์—ฐ๋™: ๋ณต์žกํ•œ ์„œ๋ฒ„-์„œ๋ฒ„ ํ†ต์‹  ์—†์ด JavaScript SDK๋งŒ์œผ๋กœ ๊ตฌํ˜„ ๊ฐ€๋Šฅ
  4. ํ†ตํ•ฉ PG ๊ด€๋ฆฌ: ํ•˜๋‚˜์˜ ์ฑ„๋„ ํ‚ค๋กœ ์—ฌ๋Ÿฌ PG์‚ฌ๋ฅผ ์ž๋™ ์„ ํƒ

ํฌํŠธ์› V2 ์—ฐ๋™์˜ ์žฅ๋‹จ์ 

์žฅ์ :

  • ๊ตฌํ˜„์ด ๊ฐ„๋‹จํ•˜๊ณ  ๋น ๋ฆ„
  • ์„œ๋ฒ„ ๋ถ€ํ•˜ ๊ฐ์†Œ (ํด๋ผ์ด์–ธํŠธ์—์„œ ์ง์ ‘ ์ฒ˜๋ฆฌ)
  • ์‚ฌ์šฉ์ž ๊ฒฝํ—˜ ํ–ฅ์ƒ (๋น ๋ฅธ ์‘๋‹ต ์†๋„)

๋‹จ์ :

  • ์„œ๋ฒ„์—์„œ ๊ฒฐ์ œ ๊ฒ€์ฆ์ด ์–ด๋ ค์›€
  • ํด๋ผ์ด์–ธํŠธ ์กฐ์ž‘ ๊ฐ€๋Šฅ์„ฑ (์ถ”๊ฐ€ ๊ฒ€์ฆ ๋กœ์ง ํ•„์š”)
  • Webhook์„ ํ†ตํ•œ ์„œ๋ฒ„ ๊ฒ€์ฆ ๊ถŒ์žฅ

4. ์กฐ์‚ฌ ๊ฒฐ๊ณผ

๋ณธ ํ”„๋กœ์ ํŠธ ์กฐ์‚ฌ๋ฅผ ํ†ตํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๊ฒฐ๊ณผ๋ฅผ ๋„์ถœํ•˜์˜€๋‹ค.

  1. ๊ฒฐ์ œ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋‹จ์ผ ์š”์ฒญ์ด ์•„๋‹Œ ์—ฌ๋Ÿฌ ๋‹จ๊ณ„์˜ ์ƒํƒœ ์ „์ด๋ฅผ ํ†ตํ•ด ๋™์ž‘ํ•จ์„ ์ดํ•ดํ•˜์˜€๋‹ค.
  2. ready โ†’ paid/failed์™€ ๊ฐ™์€ ์ƒํƒœ ๋ชจ๋ธ๋ง์ด ๊ฒฐ์ œ ์‹œ์Šคํ…œ์˜ ํ•ต์‹ฌ์ด๋ผ๋Š” ์ ์„ ํ™•์ธํ•˜์˜€๋‹ค.
  3. PgClient ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ†ตํ•ด ๋‹ค์–‘ํ•œ PG์‚ฌ๋ฅผ ์ถ”์ƒํ™”ํ•˜์—ฌ ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ๊ตฌ์กฐ๋กœ ์„ค๊ณ„ํ•  ์ˆ˜ ์žˆ์Œ์„ ํ™•์ธํ•˜์˜€๋‹ค.
  4. ํฌํŠธ์› V2 Checkout SDK๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์‹ค์ œ PG์‚ฌ(์ด๋‹ˆ์‹œ์Šค) ์—ฐ๋™์„ ์„ฑ๊ณต์ ์œผ๋กœ ๊ตฌํ˜„ํ•˜์˜€๋‹ค.
  5. ๋‹ค์–‘ํ•œ PG์‚ฌ(ํ† ์ŠคํŽ˜์ด๋จผ์ธ , KCP, ์ด๋‹ˆ์‹œ์Šค, ์นด์นด์˜คํŽ˜์ด ๋“ฑ)์˜ ํŠน์ง•๊ณผ ์—ฐ๋™ ๋ฐฉ์‹์„ ์กฐ์‚ฌํ•˜์—ฌ ๋น„๊ตํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.
  6. ํฌํŠธ์› V2์˜ ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๊ฒฐ์ œ ๋ฐฉ์‹์„ ํ†ตํ•ด ์„œ๋ฒ„ ๋ถ€ํ•˜๋ฅผ ์ค„์ด๊ณ  ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์Œ์„ ํ™•์ธํ•˜์˜€๋‹ค.

5. ๊ฒฐ๋ก  ๋ฐ ๋А๋‚€ ์ 

PayFlow ํ”„๋กœ์ ํŠธ ์กฐ์‚ฌ๋ฅผ ํ†ตํ•ด ๊ฒฐ์ œ ์‹œ์Šคํ…œ์˜ ๊ธฐ๋ณธ ์›๋ฆฌ๋ฅผ ์ดํ•ดํ•˜๋Š” ๋ฐ ํฐ ๋„์›€์ด ๋˜์—ˆ์œผ๋ฉฐ, ํŠนํžˆ ์ƒํƒœ ๊ด€๋ฆฌ ๊ธฐ๋ฐ˜์˜ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๋ฐฉ์‹์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ๋†’์•„์กŒ๋‹ค.

์ด์ „ ์กธ์—…์ž‘ํ’ˆ Ignis ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ๊ฒฐ์ œ ๊ธฐ๋Šฅ์„ ๋‹จ์ˆœํžˆ ์—ฐ๋™ํ•˜๋Š” ์ˆ˜์ค€์—์„œ ๊ทธ์ณค๋‹ค๋ฉด, ์ด๋ฒˆ PayFlow ํ”„๋กœ์ ํŠธ๋ฅผ ํ†ตํ•ด ๊ฒฐ์ œ ์‹œ์Šคํ…œ์˜ ์ „์ฒด ๊ตฌ์กฐ์™€ ํ๋ฆ„์„ ์ง์ ‘ ์„ค๊ณ„ํ•˜๊ณ  ๊ตฌํ˜„ํ•ด๋ด„์œผ๋กœ์จ ๋” ๊นŠ์€ ์ดํ•ด๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

๋˜ํ•œ Spring Boot์˜ ๊ณ„์ธต ๊ตฌ์กฐ์™€ ์—ญํ•  ๋ถ„๋‹ด์„ ์ฒดํ—˜ํ•จ์œผ๋กœ์จ, ์‹ค๋ฌด์ ์ธ ๊ฐœ๋ฐœ ๊ณผ์ •์—์„œ ๋ฐฑ์—”๋“œ ๋กœ์ง์„ ์„ค๊ณ„ํ•˜๊ณ  ๊ตฌํ˜„ํ•˜๋Š” ๋Šฅ๋ ฅ์„ ๊ฐ•ํ™”ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

ํฌํŠธ์› V2 Checkout SDK๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ, ๊ธฐ์กด์˜ ์„œ๋ฒ„-์„œ๋ฒ„ ํ†ต์‹  ๋ฐฉ์‹๊ณผ ๋‹ฌ๋ฆฌ ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ์—์„œ ์ง์ ‘ ๊ฒฐ์ œ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์˜ ์žฅ๋‹จ์ ์„ ๊ฒฝํ—˜ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค. ์ด๋Š” ํ–ฅํ›„ ๋‹ค๋ฅธ PG์‚ฌ ์—ฐ๋™ ์‹œ์—๋„ ์œ ์šฉํ•œ ๊ฒฝํ—˜์ด ๋  ๊ฒƒ์ด๋‹ค.

ํ–ฅํ›„ ํ™•์žฅ ๊ณ„ํš

  • ๊ฒฐ์ œ ์ทจ์†Œ(Refund) ๊ธฐ๋Šฅ ๊ตฌํ˜„
  • Webhook ์ฝœ๋ฐฑ ๊ฒ€์ฆ ๋กœ์ง ์ถ”๊ฐ€
  • ๊ฒฐ์ œ ๋กœ๊ทธ ํ…Œ์ด๋ธ” ํ™œ์šฉ (payment_logs)
  • ๋‹ค๋ฅธ PG์‚ฌ(ํ† ์ŠคํŽ˜์ด๋จผ์ธ ) ์ง์ ‘ ์—ฐ๋™ ๋น„๊ต ๊ตฌํ˜„
  • ์˜ˆ์™ธ ์ฒ˜๋ฆฌ ๊ฐ•ํ™” ๋ฐ ์—๋Ÿฌ ํ•ธ๋“ค๋ง ๊ณ ๋„ํ™”
  • pg_tid, pg_response ์ปฌ๋Ÿผ์„ DB ์Šคํ‚ค๋งˆ์— ์ถ”๊ฐ€

์ฐธ๊ณ  ์ž๋ฃŒ

๋ณธ ์กฐ์‚ฌ๋Š” ๊ฒฐ์ œ ์‹œ์Šคํ…œ ๊ฐœ๋ฐœ์˜ ๊ธฐ์ดˆ๋ฅผ ๋‹ค์ง€๋Š” ์ข‹์€ ์ถœ๋ฐœ์ ์ด ๋˜์—ˆ์œผ๋ฉฐ, ์ด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋” ๋†’์€ ์ˆ˜์ค€์˜ ์›น ์„œ๋น„์Šค ๊ฐœ๋ฐœ ์—ญ๋Ÿ‰์„ ๊ฐ–์ถ”๋Š” ๋ฐ ๊ธฐ๋ฐ˜์ด ๋  ๊ฒƒ์ด๋‹ค.