[D+240] 리액트로 토스페이 이용하기

ga_ding·2022년 8월 7일
2

TIL

목록 보기
55/55

토스페이먼츠를 활용하여 카드, 가상계좌, 계좌이체로 결제하는 코드를 기록해 보려 한다.

먼저 결제에 있어서 필요한 페이지는 3개가 있다.

  1. 결제 요청 페이지 (프론트-토스)
  2. 결제 요청 성공 페이지 (프론트-백)
  3. 결제 요청 실패 페이지 (프론트-백)

먼저 토스페이먼츠에 로그인한 후 클라이언트키(프론트)시크릿키(백) 이 필요하다.

결제 요청 페이지

const Payment = () => {
	const [name, setName] = React.useState("");

  const clientKey = process.env.REACT_APP_CLIENT_KEY;

  const tossPay = () => {
    
    //orderId가 필요해서 만든 랜덤 아이디값
    const random = new Date().getTime() + Math.random()
    const randomId = btoa(random)

    if (radio === '가상계좌') {
      loadTossPayments(clientKey).then(tossPayments => {
        // 카드 결제 메서드 실행
        tossPayments.requestPayment(`${radio}`, {
          amount: 1, // 가격
          orderId: `${randomId}`, // 주문 id
          orderName: `gagyeong`, // 결제 이름
          customerName: `${name}`, // 판매자, 판매처 이름
          successUrl: 'http://localhost:3000/success', // 성공시 리다이렉트 주소
          failUrl: 'http://localhost:3000/failed', // 실패시 리다이렉트 주소
          validHours: 24, // 유효시간
          cashReceipt: {
            type: '소득공제',
          },
        })
      })
    } else {
      loadTossPayments(clientKey).then(tossPayments => {
        // 카드 결제 메서드 실행
        tossPayments.requestPayment(`${radio}`, {
          amount: 1, // 가격
          orderId: `${randomId}`, // 주문 id
          orderName: `gagyeong`, // 결제 이름
          customerName: `${name}`, // 판매자, 판매처 이름
          successUrl: 'http://localhost:3000/success', // 성공시 리다이렉트 주소
          failUrl: 'http://localhost:3000/failed', // 실패시 리다이렉트 주소
        })
      })
    }
  }

결제 요청이 토스페이먼츠로 전송되고 성공했을 때 url로 orderId, paymentKey, amount가 나오는데 그 값들을 백엔드에게 넘겨줘야한다.

결제 성공 페이지

  let orderId = new URL(window.location.href).searchParams.get("orderId");
  let paymentKey = new URL(window.location.href).searchParams.get("paymentKey");
  let amount = new URL(window.location.href).searchParams.get("amount");

  useEffect(() => {
    axios
      .get(process.env.REACT_APP_BASE_URL + `/success?paymentKey=${paymentKey}&amount=${amount}&orderId=${orderId}`)
      .then((res) => {
        if (res.status == 200 && res.data.method === '가상계좌') {
          sessionStorage.setItem("accountNumber", res.data.virtualAccount.accountNumber);
          sessionStorage.setItem("bank", res.data.virtualAccount.bank);
          sessionStorage.setItem("dueDate", res.data.virtualAccount.dueDate);
          navigate('/deposit')
        } else if (res.status == 200 && (res.data.method === '카드' || res.data.method === '게좌이체')) {
          window.alert({
            position: 'center',
            icon: 'success',
            text: '결제가 완료되었습니다!',
            showConfirmButton: false,
            timer: 1500
          })
          navigate('/')
        }
      })
      .catch((err) => {
        navigate('/failed')
      })
  }, [])

백엔드와 method 그리고 데이터를 바디에 담을건지 쿼리스트링으로 담을건지 약속하고 실험을 해보면 될 것이다.
또한, 우린 페이지를 닫으면 결제 정보를 날라가게 할 예정이므로 sessionStorage에 담아 뒀다.

결제 요청 실패 페이지
실패 페이지에서는 이정도면 적당할 듯 하다!

   <span>※ 만약 같은 문제가 지속적으로 발생한다면 문의 부탁드립니다.</span>
profile
大器晩成

0개의 댓글