전체 글 58

Stripe, Paypal 결제기능 간편하게 구현하기 : JS + node.js

기존 진행하던 예제에 간편한 카드결제를 위해Stripe, Paypal을 붙여보았다.  이런저런 디테일한 우여곡절은 있었지만막연히 결제 시스템 구현에 대해 두려웠던 것에 비해서는 생각보다 순조롭게 진행했다. 이번에 결제 시스템 구현을 하게 되면서 알게된 부분인데페이팔의 경우 한국계정에서 한국계정으로는 결제 요청이 안된다고 한다.(한국-해외 or 해외-한국은 가능) 반면 스트라이프의 경우는 한국 계정끼리도 가능하다.그래서 일단 스트라이프로 최종 구축해 보았다. 먼저 스트라이프 계정생성을 해야한다. 계정생성 시 국가 선택에 한국이 없어서 당황스러웠는데;;ai에게 물어보니 일단 미국이나 다른나라로 했다가 나중에 바꿀 수 있다고 한다. 스트라이프든 페이팔이든 모두 실제 결제 시스템 안정성을 위해Sandbox라는 ..

로딩 및 예외처리 vanilla JS로 만들어보기 (Pending, Fulfilled, Failed)

쇼핑몰 프로젝트를 해보면서 서버 호출을 많이 함에 따라로딩 및 예외처리도 중요하겠다고 느껴졌다. 강의를 봤을 때도 Pending, Fulfilled, Failed 세 케이스를 체계적으로 관리하는 부분이 나왔는데나도 향후 프로젝트 부터는 이 부분을 체계적으로 관리해보고자 vanilla JS로 이 부분을 관리하는 방법을 gpt와 연구해보았다. fetchUtils.js라는 파일을 만들어주고그 파일 안에 있는 fetchWithStatus라는 함수를 통해 모든 fetch와 그에 따른 status를 관리하는 방식이다.(html에서 추가로 불러와야 함) async function fetchWithStatus(url) { const status = { pending: true, fulfilled: false, fail..

[구글 OAuth 로그인 만들기] js+node.js로 구현 (credential을 보내고 jwt를 받는 방식)

기존에 구현해 둔 이메일-패스워드 로그인 방식이 백엔드로부터 jwt 토큰을 받고 로컬 스토리지에 저장하는 방식으로 제작 되어있었는데, 이 방식을 유지하면서 구글 OAuth 로그인을 추가로 구현해보았다. 방식을 간단하게 설명하면, 구글 로그인 관련 프론트엔드 코드에서 credential 코드를 보내고 백엔드에서는 이걸 받아서 기존 방식과 같은 jwt로 토큰을 만들어서 응답 데이터로 반환해서 기존 로그인 방식과 구글 로그인 방식이 한 로직으로 다 구현되도록 만들어보았다. 참고로 이번에 구글 로그인 기능을 구현해보면서 알게 된 부분이지만 지금 설명하는 이 방식은 여러가지 구글 오어스 구현 방식 중 하나일 뿐이며, 실제로 개발 방식에 따라 여러 방식으로 구현할 수 있긴 했다. 구글 OAuth 로그인을 구현하기 ..

카테고리 없음 2024.11.17

주문완료 - 랜덤한 문자열 생성 함수, 완료와 동시에 카트 비우기 (javascript, node.js, mongoDB)

주문 완료 페이지를 만들면서 주문 성공 시 주문번호를 생성해야했다.그에 따라 랜덤한 번호 생성 함수 코드를 가져와서 사용.//orderNum 생성에 사용const randomStringGenerator = () => { const randomString = Array.from(Array(10), () => Math.floor(Math.random() * 36).toString(36) ).join(""); return randomString;};module.exports = { randomStringGenerator };  이 함수를 사용하면 랜덤한 스트링이 생성되는데 이걸 이용해서 order 컨트롤러에서 응답해야하는 값을 만들었다.const orderController = {};const Order = ..

카테고리 없음 2024.11.12

간편한 방식의 웹컴포넌트 사용기.

쇼핑몰 예제를 진행하면서 헤더나 검색창 부분이 중복 사용되면서 이전에 연구해봤던 웹컴포넌트를 사용해보기로 했다. 이전에 포스팅했던 방식으로 진행을 해보았는데 막상 실전에서 사용해보니 shadow.root로 컴포넌트에 벽을 쳐 두니 생각보다 번거로운 부분이 너무 많았다. 그래서 그냥 모두 오픈시켜서 사용해보았고 이렇게 해도 큰 탈 없이 잘 진행되었다. class HeaderComponent extends HTMLElement { constructor() { super(); } connectedCallback() { this.innerHTML = `   home 로그인 로그아웃 admin `; // 버튼 이벤트 리스너 추가 this.querySelector('#home-btn').addEventList..

프론트엔드 페이지 라우팅 정리 - window.addEventListener("DOMContentLoaded"), window.addEventListener("popstate")

인덱스 페이지(메인 홈 화면) 한 html 안에서 여러 함수를 통해서 페이지 변화를 보여주는 SPA 방식을 구현하려다보니 그 페이지가 늘어남에 따라 url주소와 페이지 간의 매칭이 점점 엉키게 되었다. 예를들어 버튼으로 페이지는 띄울 수 있지만 url주소를 새로고침하면 전혀 다른 곳으로 간다거나, 뒤로가기나 앞으로가기 시 에러가 발생하는 등 여러모로 url주소와 페이지 간의 라우팅 처리가 필요했다. 이 부분은 생각보다 굉장히 난해했고gpt랑도 감정소모?를 많이 했다...그래도 씨름끝에 나름 내 방식 안에서 최적화 된 방법을 찾았고 일단 이 방식으로 구현해보았다.// 주소 정보에 맞게 페이지를 반영하는 함수function handleRoute() { const path = window.location.pa..

카트 페이지, 주문 내역 만들기 - javascript + node.js (feat. 가격 숫자에 콤마 표시하기)

카트 가격 합산리듀스 어큐뮬레이트 합산법포맷커런시 적용 카트에 담았으니 이제 카트에 있는 리스트의 가격 총합을 이용해서 주문 내역을 만들고 결제를 해야한다.카트 페이지를 가져오기 위해서 장바구니 버튼을 누르면 이렇게 getCartPage라는 함수를 실행시키게 했다.//장바구니 버튼const cartBTN = document.getElementById('cart-btn');cartBTN.addEventListener('click', () => { getCartPage();});  getCartPage라는 함수는 이렇게 길게 구성되었는데 이는 주문내역까지 한번에 구성하느라 길어진 것도 있고 가격들의 합산을 위해서 코드가 좀 복잡해졌다.function getCartPage() { history.pushStat..

카테고리 없음 2024.11.04

URL 경로에 맞게 함수 실행시켜서 경로에 따라 페이지 변화시키기

상품 상세나 카트가 추가되면서 경로가 꽤 많아졌다.효과적인 js파일들 관리를 위해 index.html이라는 하나의 html파일의 콘텐츠 컨네이너 안에서 상품 콘텐츠나 카트 콘텐츠 같은 것들이 바뀌도록 구성을 했는데, 이렇게하다보니 문제가 해당 경로로 갔을 때 새로고침을 하면 에러가 발생했다. 경로를 다시 불러들이면서 발생한 에러인듯했다. 따라서 해당 경로를 다시 불러들일 때 거기에 맞는 해당 경로에 맞는 함수를 실행시켜서 문제가 안생기도록 세팅을 했다. 일단 public파일들의 라우팅 처리를 해주는 코드 경로 설정을 추가해주었다.여기서 product/* 라고 설정되어있으면 product 다음에 어떤 경로가 더 있든 index.html로 보내준다는 뜻이다.//상품 페이지apiRouter.get('/pro..

장바구니 기능 구현 - javaScript + node.js

드디어 평소에 궁금했었던 장바구니 기능을 진행해보았다.   (일단 최대한 기능 위주로 진도를 나가고자 디자인은 정말 하나도 안건드렸다;;)먼저 홈 화면에서 상품 목록을 클릭하면 getProductDetail(item._id)를 실행시키도록 했다.이 함수에 인자로 선택한 상품 아이디를 넣어서 실행하면 해당 아이디를 가지고 get요청을 해서 상품 상세페이지를 가져오게된다.  상세페이지에서는 사이즈를 선택해서 장바구니에 추가를 할 수 있다.사이즈 정보를 선택하는 방법으로 라디오버튼 방식을 해보았다.원래 드랍다운으로 하는게 일반적이나 당장은 이러한 컴포넌트 구현이 공부 주제는 아닌지라;;최대한 간단하게 할 수 있는 라디오 방식으로 했다.//사이즈 선택 라디오 Object.keys(data.data.stock)...

수정과 삭제 기능 - URL에 params(path parameter)로 api 요청하고 응답받기

이어서 상품의 수정 및 삭제 기능 작업을 진행했는데 상품의 경우 api로 주고받는 값들이 많아보니 CRUD를 구현했을 때 코드가 상당히 복잡하고 길어졌다. 그에따라 JS파일을 기능별로 페이지를 분할하는 작업도 병행했다. 모달관련 페이지, 일반 페이지, 겟, 포스트, 업데이트, 딜리트 이렇게 6개 페이지로 나누어보았다. 각 페이지에 대한 js소스는 html에서 하나로 통합된다. script src="/adminProductModal.js">script> script src="/adminProductPost.js">script> script src="/adminProductPut.js">script> script src="/adminProductDelete.js">script> script src="/adm..