쿠팡, 네이버 스마트 스토어와 같은 e-commerce 기능을 개발하게 되었다.
처음으로 e-commerce 기능들을 설계, 개발하게 되면서 했던 고민과 생각들을 정리해서 작성해 보려한다.
이렇게 상세하게는 작성할 생각이 없었는데 그래도 많은 사람들이 도움이 됐으면 해서 정리를 한다.
상품 설계하기
먼저 상품을 크게 상품과 판매 상품으로 나누었다. 상품을 상품과 판매 상품으로 나눈다는 말이 이상하기도 하고 어색하기도 하다. 상품은 상품만의 고유한 특성만을 갖고 있는 것이고, 판매 상품은 판매 되고 있는 상품들을 뜻한다. 이렇게 분리한 이유는 아래의 예를 통해 설명하겠다.
쇼핑몰에서 상품을 관리하고 있는 A씨가 있다. A씨는 단일 상품으로 [티셔츠] 와 [바지] 를 따로 팔고 있었다. 그러나 두 개를 같이 사면 좀 더 할인을 해주기 위해 [티셔츠 + 바지] 를 하나의 "패키지 상품" 으로 묶었다. 이 때 A 씨는 [티셔츠의 재고가 100개] 가 있었고, [바지의 재고는 50개] 밖에 없었다. [티셔츠], [바지] 둘 중 하나라도 재고가 소진되면 둘 중 하나라도 포함하고 있는 판매 상품은 판매 중지가 되어야 했다.
위의 예로 인해 나는 "상품" 과 "판매 상품" 으로 구분했다. 그리고 상품에는 재고라는 특성이 존재하며, "1개의 상품"을 "N개의 판매 상품" 과 연동할 수 있다. 때문에 모든 "판매 상품" 에는 "상품" 들에 대한 재고도 같이 연동되어야 한다. 또한, 가격은 항상 유동적으로 변경 가능하기에 "상품" 에 대한 "가격" 이 아닌 "판매 상품" 에 대한 가격으로 설정할 수 있도록 했으며 했다.
또한, "판매 상품" 에는 여러 타입이 존재한다. 위에서 예로 들었던 [티셔츠 + 바지], [티셔츠] 처럼 상품들을 조합하는 것처럼 말이다. 우리는 이 타입들을 구분하는 것들을 크게 보면 환불 규정으로 구분하였다.
[티셔츠 + 바지] 는 "옷" 으로 구성 돼 있기에 환불 규정이 같다. 그렇다면 이것은 "주 상품 + 주 상품" 으로 이루어져 있으며 이것을 "패키지 상품" 으로 정의하겠다.
[티셔츠] 는 "주 상품" 하나로 "단일 상품" 이다.
[정기 구독 상품 + 일반 결제 상품] 은 환불 규정이 다르기에 "주 상품 + 부 상품" 으로 이루어져 있으며 이것을 "번들 상품" 으로 정의하겠다. 우리는 번들 상품일 경우 먼저 오는 상품을 "주 상품" 으로 정하였다.
상품 환불
사용자가 구매한 "판매 상품" 은 환불이 가능하다. 크게 보면 일반 결제 상품에 대해서 환불하는 것과 정기 구독 상품에 대해서 환불하는 것으로, 이런 환불 규정들은 법적으로 존재한다.
"번들 상품" 을 환불 시에는 "주 상품" 을 기준으로 환불하도록 하였다. 그렇다면 [정기 구독 상품 + 일반 결제 상품] 을 환불 할 시에는 "주 상품" 인 [정기 구독 상품] 에 대한 환불 규정을 지키도록 하였다.
증정품 (어떤 상품을 구매했을 때 구매 행위에 대한 감사의 표시로 끼워 주는 물품)
판매 상품에는 "티셔츠를 구매하면 바지까지 증정합니다" 와 같이 증정품이 따라올 수 있다. 또한 증정품은 재고가 존재하는 상품이 될 수 있다. 왜냐하면 관리자가 "증정품 소진 시까지 판매" 라고 설정할 수 있기 때문이다. 물론, 관리자가 수동으로 처리하는 것처럼 단순 텍스트로 처리할 수도 있다.
상품 옵션
판매 상품에는 옵션이 존재한다. "티셔츠" 라는 판매 상품에 "사이즈" 와 "색상" 을 선택할 수 있는 것처럼 말이다. 이 옵션들에 따라서 상품의 재고는 달라진다.
첫 번째 옵션인 "사이즈" 로는 [95, 100, 105] 를 선택할 수 있고, 두 번째 옵션인 "색상" 에는 [빨강, 노랑, 초록] 이 있다면 다음과 같이 재고를 설정할 수 있어야 한다.
- [95 - 빨강 : 재고 100]
- [100 - 빨강 : 재고 95]
...
- [105 - 노랑 : 재고 0]
모든 경우에 수에 따라 상품이 연결 돼 있다고 생각하면 된다. (물론 상품이 연결되지 않을 수도 있다)
여기서 알 수 있 듯이 첫 번째 옵션을 선택해야만 두 번째 옵션을 선택할 수 있기에 두 번째 옵션은 항상 첫 번째 옵션에 의존한다. 물론 옵션 자체가 없을 수도 있으며 첫 번째 옵션만 존재할 수도 있다. 또한 옵션은 필수 옵션, 선택 옵션이 존재할 수 있다.
이렇게 되면서 재고의 설계는 복잡해진다. 기획에 따라서 달라지지만 판매 상품 자체에도 재고를 설정할 수 있으며, 옵션에 연결된 상품들에도 재고를 설정할 수 있어야 한다.
여기서 한 가지가 더 있다. 옵션에는 추가, 할인 금액이 존재한다는 것이다. 특정 옵션을 선택하면 "+9000원" 과 같이 설정을 할 수 있어야 한다.
옵션, 증정품에 정기 구독 상품을 연결할 순 없도록 한다.
정기 구독 상품을 옵션, 증정품에 넣을 수 있게 하려고 했으나 결론부터 말하면 넣을 수는 없도록 정했다. 환불과 옵션 금액으로 인해서 정해야 하는 정책들에 대한 경우의 수가 너무 많아지기 때문이었다.
1. 옵션에 정기 구독 상품을 연결 했을 때 정해야 하는 정책들 예시
- N 달 동안 금액 M원! 이후 C원!
- 매 달 금액 N원!
- N개월 유지마다 M원 할인! (최소 금액 C원)
2. 증정품에 정기 결제 상품 연결
- 증정품에 정기 결제 상품이 연결된 "판매 상품" 을 N개 구매 시
벌써 부터 머리가 아프다. 나의 경우는, 견고하고 여러 경우의 수를 모두 생각해야 하는 복잡한 e-commerce 를 만드는 것이 아니였으며 저렇게 개발할 시 테스트, 구현, 관리까지 힘들어지기 때문에 애초에 옵션에 넣지 못하도록 했다 (옵션에 정기 구독 상품 자체를 연결한 곳은 보지 못했기도 하다).
이제, 크게 상품에 대한 대략적인 내용들을 정리했다. 조금 비워진 내용도 있긴 한데 지금은 상세 구현 내역을 작성하는 것이 아닌 개발 일지이기 때문에 내가 고민한 내용들 위주로 정리를 하였다.
대략 45일 내에 설계부터 시작해서 개발, 테스트를 완료하여 배포해야 했기 때문에 완전 세세한 부분까지는 고려하지 않으며 설계를 했고 개발을 진행했다.
이 다음 작성할 글은 [장바구니에 '정기 결제 상품', '일반 결제 상품' 을 같이 담아 한 꺼번에 결제할 수 있도록 개발하게 되면서 생긴 부분들] 에 대하여 작성하려고 한다.