Easy Understanding

스프링부트로 페이 시스템 구축 도전해보기(초보 난이도) (3) - 결제 시스템 개발 본문

Spring

스프링부트로 페이 시스템 구축 도전해보기(초보 난이도) (3) - 결제 시스템 개발

appleg1226 2020. 10. 22. 20:14

초보 주의

예전 개발 경험이 적을 때 작성한 거라서 지금 저의 시점으로 보니 너무 도움이 안 되는 글이네요...

솔직히 지우고 싶으나 풋풋함을 기억하기 위해서 남겨둡니다. 

(심지어 지금 결제 도메인 개발 중이라 더 부끄러움)

 

프로젝트 개요

사실 이렇게 모듈로 나눠서 서비스를 구성했지만 아직까지는 나눈 의미를 크게 찾기는 힘듭니다.

왜냐하면 이번 결제 시스템은 말 그대로 결제 하나의 기능만 처리하기 때문입니다.

 

그래서 이번 시스템은 단일 컨트롤러단일 서비스 클래스를 가진 정말 간단한 클래스가 될 것입니다.


결제 시스템 동작 순서

제가 생각한 결제 시스템 동작의 순서는 다음과 같습니다.

1. 여기에서 구현하지는 않지만, 바코드를 찍거나 다른 결제 시스템에서 페이 시스템에 결제를 요청하는 API 호출이

   이루어진다.

2. 포인트를 사용할 경우, 사용한 포인트만큼 실제 사용자의 차감 금액이 변하기 때문에 계산을 해준다.

   이 과정에서 포인트를 사용 가능한지 Validation 작업을 한 번 진행해준다.(프런트에서 하긴 하겠지만 그래도)

3. 사용자의 페이머니와 포인트를 차감하여 기록한다.

4. 영업점의 페이머니 결제액을 기록한다.(이는 이후에 매월 일정한 날짜에 지급한다)

5. 해당 결제 내역을 데이터베이스에 기록한다.

6. 결제 내역을 사용자에게 보내준다.(금액, 영업점 이름)

 

결제 과정이 생각보다는 쉬울 거라곤 생각을 안 했는데, 막상 아이디어를 나열해보니

생각보다 복잡한 과정은 없었습니다.

 

결제는 이미 등록되어 있는 페이머니만 신경쓰면 되기 때문입니다.

 

결제 기능이 여러 가지로 확장될 필요도 없기 때문에,

당장 확장성을 고려한 아키텍쳐를 만들 필요는 없겠다는 판단으로 간단하게 구성을 하기로 했습니다.


구현 내용

PaymentController는 {ip-address}/payment 주소로 POST 요청을 받습니다.

요청 받을 Body는 다음과 같이 구성되어 있습니다.

String userId;
String shopId;
int money;
boolean doesUsePoint;
int usingPoint;
LocalDateTime dateTime;

 

그리고 이것을 가지고 PaymentService에서는 결제를 진행하게 됩니다.

public PaymentResponse runPayment(PaymentRequest paymentRequest){
    updateExchangeRecord(paymentRequest, exchangeRepository);
    PayUser userResult = updatePayUser(paymentRequest, getOnlyPayMoney(paymentRequest, pointValidator), payUserRepository);
    Shop shopResult = updateShop(paymentRequest, shopRepository);

    return PaymentResponse.builder()
            .userId(paymentRequest.getUserId())
            .shopName(shopResult.getShopName())
            .money(userResult.getPayMoney()).build();
}

updateExchangeRecord: 거래 내역을 기록하여 DB에 저장합니다.

updatePayUser: 유저의 DB를 업데이트합니다.(페이머니 차감)

updateShop: 영업점의 DB를 업데이트합니다.(페이머니 증가)

이렇게 세 가지는 같은 클래스 내에 있는 static 메서드로, 각자 이름대로 써있는 기능을 구현합니다.

 

그리고 그 결과를 다시 컨트롤러에 넘겨주게 되는 간단한 흐름으로 진행됩니다.


결론

이번 모듈은 금방 구현을 하게 된 데다가, 생각보다 간단해서 이걸 굳이 다른 서버에 띄워야하는가 라는 고민을 하게 됐습니다. 그렇지만 실제로는 결제라는 서비스가 가장 많은 트래픽을 감당하기 때문에, 결제 하나만 심플하게 구성하는 서버라는 개념 자체는 그렇게 나쁘지 않은 것 같다고 결론을 내렸습니다.

 

다음에는 송금 시스템을 구현해볼 것인데, 이 시스템은 특별히 Kotlin과 Springboot를 이용해서 구현해 볼 것입니다.

 

p.s. TDD 도전 후기

이번 클래스는 처음으로 TDD를 도입해서 진행을 해봤는데 참 쉽지는 않습니다.

그리고 기록을 해두기엔 너무나도 자주 바뀌었기 때문에 무리가 있었습니다.

 

TDD를 간단하게 말하면 아무것도 없는 상태에서, 마치 뭐라도 있는 것처럼 테스트 코드를 짜는 겁니다.

그래서 틀을 먼저 잡아서 테스트 코드를 괜찮아 보이게 만든 다음 실제 코드를 채워넣는 식으로 이루어집니다.

 

당장 이것을 통해서 무엇인가를 깨닫기보다는 조그만한 것부터 실천하고자 살짝 써보았습니다.

실제로 테스트와 함께 진행하니 생기는 안정감은 무조건 TDD의 장점인 것 같습니다.

 

(실제 구현 코드)

github.com/appleg1226/sample-pay-system