-
Notifications
You must be signed in to change notification settings - Fork 3
issue reservation
저희 티켓 예약 서비스에서 핵심인 예약하기 기능을 구현하기 위해서 다른 서비스들의 예약 방식들을 한번 찾아보았습니다.
크게 2가지 방식이 있었습니다.
1. 선좌석 예약방식
2. 선결제 예약방식
결제 전에 먼저 좌석을 선택한 사용자에게 우선권을 부여한 후에 결제를 하는 방식입니다.
장점으로는 같은 좌석에 대해서 동시에 결제하는 경우를 배제할 수 있기 때문에 비교적 쉬운 구현이라고 생각했습니다.
단점으로는 사용자 입장에서 좌석을 계속 결제하지 않고 예약할 수 있기 때문에 계속 예약 좌석을 선점하여 악용할 수가 있습니다.
따라서 사용자 별로 미결제인 예약 좌석 수를 제한하고, 결제 마감시간을 부여하여 결제가 늦어지는 예약 건에 대해서 자동으로 예약 취소가 되도록 하는 기능들을 부수적으로 만들어야 하는 단점이 있습니다.
먼저 결제를 완료한 사용자에게 우선권을 부여하는 방식입니다.
장점은 직관적인 예약방식으로 앞서 선좌석 예약방식에서 부수적으로 만들어야 하는 부분이 필요 없습니다.
단점은 다수의 사용자가 동시에 결제 요청을 한 경우에 대해서 신경쓸 부분이 많습니다.
결제완료가 늦은 사용자들에게는 다시 환불 되도록 하는 구조는 사용자 경험을 떨어트리므로 결제가 진행이 되지 않도록 해야하고, 결제가 외부 시스템일 경우 트랜잭션 처리가 복잡하기 때문에 구현 난이도가 높다는 단점이 있습니다.
저희는 일단 외부 결제 시스템을 사용할 것이기 때문에, 후자의 경우를 선택한다면 복잡한 트랜잭션 처리를 하고 기능을 안정적으로 구현하는데에 시간이 많이 들 것이라 판단되어 전자인 선좌석 예약방식
을 채택했습니다.
선좌석 예약방식의 프로세스는 아래와 같습니다.
- 1단계. 선좌석 예약 API 호출
- 예약 가능한 좌석인 경우 예약 데이터 추가 후 2단계 진행
- 예약 가능한 좌석이 아닌 경우 에러 처리
- 2단계. 결제 모듈 호출
- 결제에 성공했다면 3단계 진행
- 결제에 실패했다면 에러 처리
- 3단계. 예약 API 호출
- 예약 데이터와 결제 모듈 영수증 데이터가 일치하면 예약 상태 완료로 변경
- 예약 데이터와 결제 모듈 영수증 데이터가 일치하지 않으면 결제 취소 후 에러 처리
좌석을 동시에 예약하는 경우에 대해서는 중복되는 데이터가 발생하지 않도록 좌석 id와 공연 id에 mysql 복합키를 주어 해결했습니다.
결제 모듈의 호출을 front 쪽에서 하기 때문에 악성 사용자가 결제 가격을 조작하는 일말의 가능성이 있다고 생각을 했습니다.
그래서 예약 API에서 해당 예약 데이터와 영수증 데이터의 좌석 id
, 공연 id
, 사용자 id
비교 뿐만이 아니라,
해당 예약 좌석의 가격과 영수증 데이터의 가격도 비교하는 부분을 추가했습니다.
미결제 예약의 경우 계속 해당 사용자에게 좌석에 대한 우선권을 부여하면 안되기 때문에, 미결제 예약에 대한 삭제 처리가 필요하다고 생각했습니다.
아직 기능이 완성되지는 않았지만 5분의 결제 시간을 주고 결제 마감시간을 경과하면 좌석 예약 데이터를 삭제하는 배치 프로그램을 추가할 예정입니다.