wonderLand/상점파트

Springboot+vue.js 구매시스템만들기!(1) 카드결제요청 with 세틀뱅크

디비드킴 2021. 10. 29. 15:09

쿠폰/할인 코드/포인트 적용하는데

처음 적용해서 그런가

아 진짜 힘들었다..

 

규칙

1. 한 상품의 최대 할인율이 정해져 있다

2. 쿠폰+할인 코드=총 할인금액이 

최대 할인율을 넘어서면 안 된다

3. 포인트는 총금액에서 마이너스한다

4. 쿠폰/할인코드드중 퍼센트인 게 먼저 적용되고

그다음 마이너스가 적용된다

ex) 쿠폰=퍼센트/할인=금액 마이너스인 경우

쿠폰 적용 후 할인 적용

반대라면 반대로 적용

둘 다일 경우

마이너스 든 퍼센트 든 합해서 계산하면 된다

5. 쿠폰/할인 코드는 개별 적용/포인트는 총금액에서 마이너스

 

구현중 어려웠던 건..

예를 들어 3잔의 커피를 주문하고 

3장의 쿠폰/혹은 할인 코드가 적용된다면

총금액에 적용되는 게 아니라 

개별 상품에 적용되게 하는 것이 힘들었다..

일단 구현은 했다

 

제품 사진을 클릭하면 구매창이 나타난다

디자인할 시간이 없었다

쿠폰/할인/포인트 적용하느라...

 

프런트 서버

html

html

css

css

볼품없는 css이다

js

js
js

나중에 디자인하자

 

백엔드 서버

productService

productService.java

구매를 위해 정보를 검증하고 가져오자

 

getTotalPriceAndOther(tryBuyDto tryBuyDto) 

productService.java

구매 제품에 따라 프런트에서 받는 

배열 구성이 다를 수 있으므로 

어떤 제품인지 나눠서 정보를 들고 온다

음식은 대분류는 product로 했고 

중분류는 nowFood로 했다 

중분류는 가상계좌 주문 시

입금 시간을 짧게 주려고 하기 때문이다

 

getTotalPriceAndOther(Object[][] itemArray,String point) 

productService.java

제품의 종류 개수만큼 반복한다

for(int i=0;i<itemArraySize;i++)

여기서 개수는 아메리카노 2잔/아이스티 4잔

해서 6개가 아니라 아메리카노/아이스티 2개가 되는 것이다

쿠폰/할인 코드가 있는지 가져온다

String couponName=itemArray[i][2].toString();

String codeName=itemArray[i][3].toString();

없어도 일단 가져온다

사용자 보유 포인트/제품 정보를 가져온다

getPointAndProducts getPointAndProducts=productDao.findProductJoinPoints(email,Integer.parseInt(itemArray[i][0].toString()));

주문 개수를 검사하는 함수

confrimCount(count, getPointAndProducts.getCount());

포인트를 검사하고 담는 함수

onlyPoint=confrimPoint(point,getPointAndProducts.getPo_having());

쿠폰을 검사하고 담는 함수

confrimCount(count, getPointAndProducts.getCount());

할인 코드를 검사하는 함수

confrimCode(codeName, count, eventmap);

결제할 현금을 받아오는 함수

쿠폰/할인 코드 적용이 일어나는 함수이다

onlyCash=getOnlyCash(getPointAndProducts.getPrice(),count,eventmap,getPointAndProducts.getMax_discount_percent(),result);

마지막 제품이었다면

maps.add(getTotalPrice(totalCash, onlyPoint,itemNames));

결제할 총금액/사용된 포인트/제품들 이름을 담아준다

여기서 이제 포인트 계산을 하는 것이다

 

이제 세세하게 봐보자

confrimPoint

productService.java

포인트가 빈칸이 아닌데 

숫자도 아니라면 예외 발생

보유 포인트보다

사용 포인트가 더 크다면 예외 발생

 

confrimCount

productService.java

요청수가 0이거나

db 수보다 많이 요청했다면 예외 발생

 

confrimCode/confrimCoupon

둘이 어차피 똑같으므로 하나만 봐보자

일부로 함치진 않았다

나중에 서로 다른 기능을 넣고 싶을 수 있으니까

productService.java

빈칸이라면 

쿠폰/코드를 입력하지 않은 것이니

주문 개수만큼 가짜 쿠폰을 넣어주자

if(flag){

for(int i=0;i<count;i++){

아니라면

개수를 검사한다

if(splite.length>count){

예를 들어 아메리카노 3잔을 사는데

쿠폰을 3장 초과를 넣는다 예외가 발생

동일 쿠폰 검사

for(int i=0;i<size;i++){

for(int ii=0;ii<size;ii++){

예를 들어 쿠폰 이름이 '쿠폰 1'인데

쿠폰 창에 쿠폰 1을 두 번 적으면 예외 발생

입력한 쿠폰 개수만큼 넣어준다

for(String s:splite){

총개수랑 비교해서

쿠폰 개수가 총개수보다 적다면

if(temp<count){

추가로 가짜 쿠폰을 넣어준다

 

getOnlyCash

productService.java

둘 타 페선트 할인쿠폰이라면

if(codeAction.equals("percent")&&couponAction.equals("percent")){

둘 중 하나만 퍼센트 쿠폰이라면

}else if(codeAction.equals("percent")&&couponAction.equals("minus")){

}else if(couponAction.equals("percent")&&codeAction.equals("minus")){

둘다 마이너스 쿠폰이라면

}else if(couponAction.equals("minus")&&codeAction.equals("minus")){

할인 퍼센트 검사

if(maxDiscountPercent<totalDiscountPercent){

할인율이 0보다 크다면 계산

if(totalDiscountPercent>0.0){

이렇게 각각 제품에 대한 계산이 다 끝나면

최종 합 친가 격/포인트/합친 이름 만드는 함수

 

getTotalPrice

productService.java

포인트 계산 후 

최종금액이 0보다 적으면

if(temp<0){

금액=0

포인트=금액 재계산

 

settleService

settleService.java

결제수단별로 분리를 해주자

 

cardService

cardService.java

담은 후 임시 주문/임시 제품 테이블 저장하러 간다

paymentService.insertTemp(mchtTrdNo,email,"card",(int)map.get("totalCash"),(int)map.get("totalPoint"));

paymentService.insertTemp(maps, mchtTrdNo, email);

 

paymentService

paymentService.java

임시 주문 테이블에 저장해주는 함수

 

insertTemp(List<Map<String,Object>>maps,String mchtTrdNo,String email) 

paymentService.java

제품 별로 나눠준다

 

insertTempOrderProducts

paymentService.java

테스트

천 원짜리 2개 구매

그냥 구매 테스트

20% 쿠폰 테스트

50원 할인 코드 테스트

200포인트 테스트

20% 쿠폰+10% 할인 코드 테스트

100원 쿠폰+50원 할인 코드 테스트

100원 쿠폰+10프로 할인 코드 테스트

 

다 합해서 포인트 테스트

여러 장 테스트

3개 결재=3000원 결제

1잔에 쿠폰/코드 적용

2잔에 쿠폰 만적용

3잔에 x

마지막 포인트 마이너스

800+800+1000-500=2100

쿠폰/코드가 개별 적용되는 걸 알 수 있다

 

여러 제품 테스트

1500원 1개 추가

노 쿠폰/노 할인 코드

[{couponNum=0, couponName=emthy, code=code4,, coupon=test3,test1, coupone=test3,test1, count=3, bigKind=product, codeAction=minus, itemName=아메리카노-m, price=2600, codeName=emthy, codeNum=0, couponAction=minus}, {couponNum=0, couponName=emthy, code=, coupon=, coupone=, count=1, bigKind=product, codeAction=minus, itemName=아메리카노-r, price=1500, codeName=emthy, codeNum=0, couponAction=minus}, {totalPoint=500, totalCash=3600, itemNames=아메리카노-m,아메리카노-r}]

이렇게 제품별로 묶어서 다니기 때문에 정상작동!

 

진짜 힘들었다

 

근데 테스트하다 보니 

쿠폰/할인 코드 중복확인검사를 다시 해야 한다

이유는 이제 장바구니를 만들 때

예를 들어 

아메리카노/아이스티인데

test 1/test 1 쿠폰을 개별적으로 넣으면

중복확인이 불가능해서 아예

쿠폰 이름만 있는 배열을 하나 받아서 검사해야겠다!

 

++추가

소스를 개선했다 굳이 join을 하지않고

point조회는 한번만 일어날수 있게 밖으로 내보냈다

pointsVo pointsVo=pointsDao.findByPoEmail(email);

쿠드/쿠폰중복 알고리즘 범위를 넓혔다

이전까지는 아메리카노(coupon,coupon)은 검증해냈지만

아메리카노(coupon),아이스티(coupon)이렇게 들어오는걸 생각하지 못했다 그래서

List<String>couponNamesAndCodeNames=new ArrayList<>();

쿠폰이름 담는 배열을 하나만들어서

쿠폰/코드를 map에담기전 

if(couponNamesAndCodeNames.contains(s)){

존재 한다면 예외가 발생되게 만들었다