쇼핑몰에서 상품을 결제하는 기능을 구현하는 /order
페이지를 만들었다. 전체 화면은 다음과 같다.
그 중, 쿠폰/포인트를 적용하는 부분을 구현하는 방법에 대해 정리해보고자 한다.
쿠폰은 쿠폰 셀렉 인풋과 쿠폰 번호를 입력하여(쿠폰 번호 입력 부분은 기능 구현하지 않음) 적용할 수 있도록 했고, 포인트는 직접 입력하거나 전액사용 버튼을 통해 적용할 수 있도록 했다.
(디자인은 아임웹 결제페이지 UI를 참고)
쿠폰/포인트 적용을 구현할 때 가장 중요하게 고려해야 하는 부분은 쿠폰과 포인트를 중복해서 적용할 때 쿠폰과 포인트 중 어떤 것이 우선시되어 적용되어야 하는지이다.
처음에 이를 고려하지 않고 구현했더니, 같은 포인트와 쿠폰을 적용하더라도 사용자가 적용한 순서에 따라 최종 가격이 달라지는 문제가 생겼다. 이를 발견하게 되고는 다시 구현했다.
쿠폰과 포인트가 적용되는 방법에는 두 가지가 있을 것이다.
예를 들어,
원가 41,000원에 20% 할인 쿠폰과 1,000포인트를 적용했을 때,
첫 번째의 경우
① 쿠폰 적용: 41,000 - 8,200(20% 쿠폰
) = 32,800원
② 포인트 적용: 32,800 - 1,000(포인트
) = 31,800원
두 번째의 경우 (v)
① 포인트 적용: 41,000 - 1,000(포인트
) = 40,000원
② 쿠폰 적용: 40,000 - 8,000(20% 쿠폰
) = 32,000원
이렇게 되면 두 경우에 총 가격(31,000 ≠ 32,000)이 같지 않게 된다.
그래서 이 두 방법 중 어떤 방법을 적용해야 하는지를 정해서 구현해야 한다.
어떤 방법을 적용해야 하는지 정할 때는 구매자의 입장보다는 회사의 입장에서 생각해야 할 것이다. 회사의 입장에서는 할인 적용이 적게 되는 쪽이 더 이윤이 남을 것이다. 따라서 위의 예시만 봐도 알 수 있듯이, 두 번째의 경우(포인트를 먼저 적용)를 선택하는 방법을 취해야 할 것이다.
또한 쿠폰의 종류에는 정률 쿠폰과 정액 쿠폰이 있기 때문에 이를 알고 구현할 때 고려해야 한다.
정률 쿠폰: 일정 비율이 할인되는 %(퍼센트) 쿠폰
정액 쿠폰: 일정 금액이 할인되는 $ 쿠폰
사용자가 선택한 쿠폰이 정액 쿠폰이라면 쉽게 해당 금액 그대로를 적용(뺄셈)하면 되지만, 정률 쿠폰이라면 해당 쿠폰의 퍼센트를 고려한 금액을 계산하여 적용해야 한다.
사용자가 쿠폰 셀렉 인풋에서 쿠폰을 선택했을 때, 다음과 같은 단계가 이루어져야 할 것이다.
// 정률제 쿠폰인지 여부 반환
function isFlatRateCupon(value: string) {
return value.includes("%");
}
/*
정액제일 경우: 쿠폰 금액 반환
정률제일 경우: 쿠폰 할인율 반환
*/
function getAmountOfCupon(value: string): number {
let amount;
amount = userInfo.cupon.find((cupon) => cupon.name === value)?.amount;
if (amount === undefined) {
alert("쿠폰이 유효하지 않습니다.");
return 0;
}
return amount;
}
onSelectCupon
<Select onValueChange={onSelectCupon}>
function onSelectCupon(value: string) {
let amount;
let cuponPrice;
setCuponToUse(value);
// 1. 정률제일 경우 (%)
if (isFlatRateCupon(value)) {
amount = getAmountOfCupon(value);
// * 포인트 먼저 적용된 금액으로!
cuponPrice = (shippingInfo.productPrice - pointToUse) * (amount / 100);
}
// 2. 정액제일 경우 (원)
else {
amount = getAmountOfCupon(value);
cuponPrice = amount;
}
setSelectedCuponPrice(cuponPrice);
}