결제 로직 설계1
결제 로직 설계1
결제 로직을 어떻게 구현할 수 있을지를 고찰해보고자 합니다.
결제 단계
인터넷에서 상품을 주문하는 과정을 단순화해서 생각해봅시다.
- 상품을 고르고, 수량을 입력한 후 [주문하기] 버튼을 누릅니다.
- 결제 팝업이 뜬 후, 결제를 진행합니다.
- 결제가 완료되면, 완료 창으로 redirect 됩니다.
구매자 입장에서는, 상품 주문하기 버튼을 클릭하고, 결제 창을 통해 결제를 진행하면, 상품 구매가 완료됩니다. 판매자(쇼핑몰 운영자) 입장에서는 어떨까요?
- 상품 주문에 대한 결제 요청이 들어오면, PG 사 api 를 호출합니다.
- PG 사 api 의 호출 인자에는 어떤 상품을, 얼마의 금액으로, 어떤 결제 수단으로 결제할지 와 같은 정보들을 담아서 요청합니다.
- pg 사로부터 결제가 완료됐다는 successurl 이 호출되고, 결제를 요청한 페이지에서 해당 이동을 감지해서 적절한 화면을 띄워줍니다.
pg 사 api 호출은 이런 형태일 것입니다. 토스 페이먼츠를 참고했습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
tossPayments
.requestPayment('카드', {
// 결제수단 파라미터 (카드, 계좌이체, 가상계좌, 휴대폰 등)
// 결제 정보 파라미터
// 더 많은 결제 정보 파라미터는 결제창 Javascript SDK에서 확인하세요.
// https://docs.tosspayments.com/reference/js-sdk
amount: 100, // 결제 금액
orderId: '4O6TcGH5l8FxyTBhsfTEq', // 주문번호(주문번호는 상점에서 직접 만들어주세요.)
orderName: '테스트 결제', // 구매상품
customerName: '김토스', // 구매자 이름
successUrl: 'https://docs.tosspayments.com/guides/payment/test-success', // 결제 성공 시 이동할 페이지(이 주소는 예시입니다. 상점에서 직접 만들어주세요.)
failUrl: 'https://docs.tosspayments.com/guides/payment/test-fail', // 결제 실패 시 이동할 페이지(이 주소는 예시입니다. 상점에서 직접 만들어주세요.)
})
결제와 csrf 공격
그렇다면 결제를 구현하기 위해서는 클라이언트에서 pg 사에 적절한 api 를 호출하고, 해당 api 의 결과만 기다리면 될까요? 아닙니다. 해당 방법으로만 구현한다면 CSRF 공격에 취약하기에, 결제 정보를 내 서버와 pg 사 서버 간에 동기화를 할 수 있어야 합니다.
csrf 란 웹 보안 공격의 일종으로, 인증된 사용자의 웹 애플리케이션을 사용하여 악의적인 요청을 보내는 공격 기법입니다. 이 공격은 사용자가 악의적인 웹 사이트를 방문하거나 악성 이메일을 통해 트리거될 수 있습니다.
예를 들어, 사용자가 인증된 상태에서 온라인 상점에서 결제를 진행하는 경우, 해당 결제 요청은 사용자의 세션 정보를 이용하여 서버에 전송됩니다. 이때, 악의적인 웹 페이지나 악성 이메일을 통해 사용자의 브라우저가 CSRF 공격자의 요청을 수행하도록 유도될 수 있습니다. 이러한 공격에서는 사용자가 의도하지 않은 결제를 실행하거나 결제 정보가 탈취될 수 있습니다.
결제 상태 관리
따라서, 우리는 결제 정보를 서버에서 관리해야 합니다. 결제 정보를 서버에서 관리 하기 위해서 서버에서는 주문 엔티티를 생성하고, 해당 주문에는 주문 코드와 csrf 토큰을 발급할 수 있습니다.
주문 발급 api 를 내 서버에서 처리한다면 어떤 로직으로 결제를 처리할 수 있을까요?
- 결제 버튼 클릭
- 주문 발급 api 호출
- 주문 발급 완료
- 클라이언트에서 pg 호출
- pg 팝업 오픈 및 결제 처리
- 결제 결과 redirect
주문 발급 api 를 호출하고, pg api 를 호출할 때 전달해야 하는 정보는 어떤걸까요? 가장 먼저 결제 금액이 들어갈 것이고, csrf 공격을 방지하기 위한 csrf 토큰도 포함될 것입니다. 이 토큰을 통해서 pg 에서 관리한 주문과 우리 서버에서 관리하는 주문의 동등성을 확인할 수 있습니다.
우리는 pg 에서 어떻게 결제가 처리되고 있는지를 모릅니다. 따라서 자체적으로 결제 단계에 따른 주문의 상태 관리를 해야 합니다. 우리가 생성한 주문은 pg 사와의 api 호출에 따라서 다음과 같은 상태를 가질 수 있을 것입니다.
- prepay : pg api 호출 전
- inprogress : pg api 호출 후, pg 처리 진행
- cancel / success / fail : pg api 호출 결과
- complete : success 이후, pg api 호출 결과에 대한 주문 처리 완료 ack 전송
주문 상태를 관리함으로서 pg api 와의 연동을 비동기적으로 처리하며, pg 의 결제 단계에 덜 의존할 수 있습니다.
재고 관리
그렇다면 주문과 연동된 재고 관리는 어떻게 진행해야 할까요? 다음 포스트에서 이어서 고려해보겠습니다.
다음에 다룰 내용..
재고 관리 - 배치
재고 관리 - Queue
재고 관리 - 코드