Giter Site home page Giter Site logo

kpayment's Introduction

# 카드결제 / 결제취소 / 결제 정보 조회 REST API

# 사용 스펙( Spec )

순번 이름 버전
1 Spring Boot 3.2.3
2 Java 21
3 Jasypt 3.0.5
4 postgresql 42.7.2
5 gradle 8.5
6 redis redis:6-alpine

# 테이블 설계

1. 결제

컬럼명 코멘트 타입 길이
1 id 아이디 bigint
2 card_data 카드 정보 varchar 300
3 installment_month 할부개월수 varchar 2
4 payment_id 관리번호 varchar 20
5 payment_kind 결제 종류(결제, 취소) enum
6 price 결제(취소)금액 double
7 tax (취소)부가가치세 bigint
8 remain_price 남은 금액 double
9 remain_tax 남은 부가가치세 bigint
10 paid_by 결제자 varchar 255
11 paid_at 결제 시각 datetime
12 parent_id 부모 식별자 bigint

2. 카드 데이터

컬럼명 코멘트 타입 길이
1 id 식별자 bigint
2 card_data 카드 정보 varchar 255
3 management_id 관리 번호 varchar 20
4 created_by 등록자 varchar 255
5 created_at 등록일자 datetime

# 빌드 방식

1. 테스트 코드 실행시

1-1. docker 를 실행시킨다.
1-2. 테스트 코드를 실행시킨다.

테스트 컨테이너로 postgres 와 redis 가 자동으로 뜨게 되어 있으므로 도커만 실행시킨 다음에 테스트 코드를 실행하면 정상 작동.
로그인 사용자 역시 WithMockJwtAuthentication 으로 주입하고 있으므로 자동 로그인 처리.

2. 어플리케이션 실행시

2-1. docker 를 실행시킨다.
2-2. (redis 컨테이너가 6379포트로 실행된 것이 없다면) docker run -d --name redis -p 6379:6379 redis 로 레디스를 실행시킨다.
2-3. SpringBoot 를 시작한다.
2-4. postman 을 실행시켜서 resources 하위의 kakaoinsurance.postman_collection.json 을 collections 에 import 한다.
2-5. Environments 에 새로운 환경을 등록하고 ACCESS_TOKEN 을 등록한다.
2-6. login 을 선행한 이후 다른 API 들을 진행한다.

# 문제 해결 전략

1. 남은 금액 확인

남은 금액을 확인 하기 위해서는 취소 금액을 더해서 최초 결제 금액에서 빼거나 취소를 할때마다 남은 금액을 업데이트 해 주는 방법이 있다.
남은 금액 조회는 취소 혹은 결제를 할때마다 확인해야 하는데, 여러 건의 취소 된 금액을 매번 조회해서 합산하는 것 보다는 취소할때마다 한번의 쓰기 연산이 발생하는 것이 더 효율적으로 생각 됐다.
따라서 쓰기와 읽기의 트레이트 오프에서 약간의 쓰기 성능을 포기하고 읽기 성능을 선택했다.
최초 결제가 일어날 때 원본 결제 테이블에 동일한 금액의 남은 금액 필드에 금액을 저장하고, 취소 요청이 올때마다 취소 금액만큼 남은 금액에서 차감한다.

2. 카드 결제 / 전체 취소

카드 결제와 전체 취소는 동시에 실행이 되지 않아야 하고, 전체 취소는 한번만 가능하기 때문에 현재 실행중인 건이 있다면 대기하지 않고 바로 종료 되도록 로직을 장성해야 한다.
그래서 Lock 을 거는 방식 중에 Redis 의 Lettuce 를 사용해서 사용중인 카드 번호나 관리번호가 있다면 로직이 종료되도록 작성했다.

3. 카드 부분 취소

카드 부분취소는 동시에 실행되지 않아야 하지만 대기 이후 처리가 가능해야 하기 때문에 Redis 의 Redisson 을 활용해서 pub-sub 기반의 lock 구현을 통해 동시에 요청이 들어오더라도 한번에 한 건씩만 동작하도록 로직을 작성했다. ( lettuce 는 spin lock 방식으로 redis 자체에 무리를 주기 때문 )

4. 카드 데이터

카드 데이터를 만들기 위해 리플렉션 API 를 사용했다. 카드 데이터는 변경이 될 가능성이 있기 때문에 하드코딩 보다는 동적으로 변경이 가능한 것이 여러모로 유지보수에도 편할 것으로 생각되었다. @PayType 이라는 어노테이션을 만들고 데이터 타입과 길이를 정의하고 값이 전부 세팅 된 이후에 필드가 선언된 순서대로 StringBuilder 에 추가하여 문자열을 만들어 줬다. 리플렉션은 JVM 에 따라 순서가 늘 보장되지 않기 때문에 @PayType 어노테이션에 순서 필드(order)를 주고 선언된 필드를 가져오는 시점에 정렬을 해서 가져오는 방식으로 해결했다. 또, 데이터 타입에 맞게 빈 자리 공백은 String.format API 를 통해서 해결했다.

kpayment's People

Contributors

seunggulee1007 avatar

Stargazers

 avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.