구매하기 기능은 구매하기로 이동할 수 있는 버튼이 여러개였기 때문에 작성해야할 코드가 많아 구현하는 데 까다로웠던 부분이기도 했다.
상품의 정보를 어떻게 해서 가져오고, 주문 페이지에서 어떤 방식으로 데이터를 렌더링하고, 주문 정보를 어떤 형식으로 저장할지 많은 부분에 대해 고민해 구현하려 노력했다.
최종적으로 로컬 스토리지를 사용해 주문할 상품의 데이터를 저장하고 구매하기 페이지에서 상품 정보를 불러오도록 코드를 구현했다.
구매하기는 총 2가지 방법으로 가능하다.
첫째, 각 상품 페이지에서 상품 별로 바로 구매하기
둘째, 장바구니에서 선택 상품 또는 전체 상품 구매하기
각각의 방법에 대해 설명해보려 한다.
1. 상품 페이지에서 개별로 구매하기
구매하기 버튼을 누르면 상품 인덱스를 clikedIndex 변수에 저장하고,
axios 요청을 보내서 상품에 대한 정보를 받아와 로컬 스토리지 selectedProduct에 저장해 구매 페이지로 이동한다.
새로운 상품을 구매하려 할때에는 다시 로컬스토리지를 removeItem을 이용해 비우고 다시 setItem으로 저장해 계속해서 로컬스토리지에 주문할 상품 정보가 저장될 수 있도록 했다.
상품 정보를 데이터 베이스에서 받아오기 위해 axios GET 요청으로 서버에 데이터를 요청하고,
서버 측에서는 SELECT 문을 사용해 조건에 맞는 상품 정보를 가져와 클라이언트에 반환한다.
2. 장바구니에서 상품 주문하기
상품 페이지 뿐만 아니라 장바구니에서도 자유롭게 선택 상품을 주문하고, 전체 상품을 주문할 수 있도록 기능을 넣어봤다.
먼저, 선택한 상품을 주문하기 위해 1번과 유사하게 체크된 아이템들의 상품 id를 추출해 selectedProducts 배열로 로컬스토리지에 저장했다.
axios POST 요청으로 selectedProducts 배열을 전달하고 SELECT 문을 사용해 조건에 맞는 상품 정보를 데이터베이스에서 가져와 다시 클라이언트 측으로 전달한다.
서버 측에서 전달받은 데이터베이스 정보를 활용해 주문 페이지에 상품 정보를 표시하여 주문이 가능하도록 만들었다.
총가격 또한 각 상품 가격과 수량을 계산해 표시되도록 했고, 상품을 여러개 주문할 시에도 totalPrice 더해 총 가격이 되도록 했다.
전체 상품 주문하기는 버튼을 누르면 모든 상품의 체크박스를 선택해 selectedProducts 배열에 데이터들이 들어가도록 해서 간단하게 구현했다.
이후의 모든 주문하기 로직은 선택 상품 주문하기 로직과 동일하다.
3. 배송지 입력 (Daum 우편번호 API 연결)
상품을 주문하기 위해 사용자의 정보를 입력하는 과정에서 배송지를 입력 받기 위해 다음 우편번호 api를 사용했다.
api를 사용하기 위해 개발 환경에 맞춰 JavaScript 코드를 받아와서 프로젝트에 맞게 코드를 변경해주었다.
- new daum.Postcode({ oncomplete: function(data) { ... } }).open(); : Daum 우편번호 서비스를 초기화하고, 우편번호 검색 창을 열고, 사용자가 주소를 선택하면 oncomplete 콜백 함수가 실행
- oncomplete: function(data) : 사용자가 주소 검색을 완료했을 때 실행되는 콜백 함수로 data 매개변수는 사용자가 선택한 주소 정보를 포함
- if (data.userSelectedType === 'R') { addr = data.roadAddress; } else { addr = data.jibunAddress; } : 사용자가 도로명 주소를 선택했는지 지번 주소를 선택했는지에 따라 addr 변수에 각각의 주소를 할당
- if(data.userSelectedType === 'R'){ ... } : 도로명 주소를 선택했을 경우 추가 주소 정보를 처리
4. 결제하기 (PortOne API 연결)
배송지 입력과 마찬가지로 주문을 위해 결제하기 기능을 넣고자 포트원 api를 활용하게 됐다.
포트원에서 제공하는 테스트 결제 api를 사용했으며 jQuery를 이용해 코드를 작성했다.
- $('#payment').change(function () { ... });: 결제 방법을 선택하는 드롭다운 메뉴에서 선택이 변경될 때 실행되는 함수
- if ($(this).val() == 'creditcard') { ... }: 선택된 값이 신용카드일 경우 #paymentBtn 버튼에 클릭 이벤트를 바인딩하여 payment 함수를 호출
- else if ($(this).val() == 'payin') { ... }: 선택된 값이 무통장입금일 경우 #paymentBtn 버튼에 클릭 이벤트를 바인딩하여 processPayIn 함수를 호출
- else { $('#paymentBtn').off('click'); }: 그 외의 경우 클릭 이벤트를 제거
- IMP.init('imp37630382');: 아임포트 결제 모듈을 초기화합니다.
- const productData = JSON.parse(localStorage.getItem('selectedProduct'));: 로컬 스토리지에서 'selectedProduct' 데이터를 가져옴
- if (!productData) { alert('오류: 제품 정보를 불러올 수 없습니다.'); return; }: 제품 정보가 없으면 오류 메시지를 표시하고 함수 종료
- IMP.request_pay({ ... }, function (rsp) { ... });: 결제 요청, 결제 기본정보를 스틸스 정보로 변경함
- if (rsp.success) { ... }: 결제가 성공하면 결제 정보를 서버에 전송
- else { ... }: 결제가 실패하면 오류 메시지를 표시
주문을 완료하면 axios POST 요청을 통해 주문정보를 서버로 전송하고 서버에서 INSERT INTO로 데이터베이스에 주문 정보를 저장할 수 있도록 했다.
따라서 데이터베이스에 주문정보까지 저장이 되면 클라이언트 측에 주문이 완료되었음을 알리는 메세지를 전달하고 완료된 주문은 마이페이지에서 확인할 수 있도록 해주었다.
'프로젝트 > [스틸스] 디지털 약자를 위한 쇼핑몰(Steels)' 카테고리의 다른 글
[스틸스] 마이페이지 구현 (axios, innerHTML, timeZone, alert) (0) | 2024.06.11 |
---|---|
[스틸스] 고객 지원 페이지 구현 (axios, Date, slice) (0) | 2024.06.11 |
[스틸스] 장바구니 구현 (localStorage, reduce, map, filter, axios) (0) | 2024.06.11 |
[스틸스] 로그인, 회원가입 구현 (axios, session) (0) | 2024.06.11 |
[스틸스] 최종 결과물 및 기능 소개 (0) | 2024.03.25 |