React

결제 프로세스

일반적으로 인터넷에서 결제를 통해 포인트를 충전하는 과정은

  1. 사용자가 브라우저에서 충전하기 버튼을 클릭
  2. 충전하기 창에서 원하는 금액을 선택하고 결제 진행
  3. 개인 결제수단(신용카드/카카오페이)에서 빠져나간 금액 만큼 사용자의 포인트가 증가

결제 프로세스의 흐름

1. 카드사

최종적으로 결제가 이루어지는 곳

2. PG (Payment Gateway)

각각의 카드사와 연결하는 작업을 대신해줌

대표적으로 NHN, 나이스, KG이니시스 등이 있음

카드사들과 결제 연결 방법을 정해놓고, 통합해서 관리할 수 있는 대행 시스템을 구축해놨기 때문에, 해당 PG사의 가이드에 맞추서 결제 시스템을 개발하면 된다

3. 결제 솔루션

PG사의 가이드에 맞춰 결제 시스템을 구축하는 작업을 대신 해주는 결제 솔루션 업체
PG사마다 다른 개발 가이드를 가지고 있기 때문에 한 업체와 거래하는 시스템을 구축한 후에는 다른 업체로 옮기기가 힘든데, 이런 문제를 보완해준다

결제 솔루션 업체를 이용하면 개발환경과 상관없이 원하는 PG사와의 결제 시스템을 연결할 수 있다

대표적인 결제 솔루션 업체는 아임포트, 부트페이 등이 있음

포인트 충전 과정

아임포트를 이용하는 경우, 사용자가 결제 포인트를 충전하는 과정은 다음과 같다

  1. 사용자가 브라우저에서 충전하기 버튼을 클릭
  2. 충전하기 창에서 원하는 금액을 선택하고 결제 버튼 클릭
  3. 아임포트에서 제공하는 Rest-API를 이용해 결제 요청
  4. 결제 성공 시 해당 결제에 대한 imp_uid와 결제 금액 등의 데이터를 돌려받음
  5. 성공한 결제 정보를 백엔드 서버로 mutation
  6. db의 유저 포인트 정보에 결제 내역을 업데이트

외부 API 아임포트 사용하기

회원가입 후 관리자 페이지에서 PG사 설정

웹훅노티피케이션

가장 계좌를 이용한 무통장 입금 진행 과정

  1. 사용자가 무통장 입금을 선택
  2. 아임포트에서 제공하는 API를 이용해 가상 계좌 생성
  3. 결제 중이던 웹브라우저를 실행 종료하고, 가상 계좌를 발급한 은행 서비스에 접속
  4. 가상 계좌 유효기간 내에 입금 완료

브라우저에서 결제가 이루어지는 것이 아니기 때문에, 결제 완료 시점에 결제된 금액과 imp_uid를 받아서 백엔드로 보내주는 것이 불가능하다
=> 이걸 해결하기 위해 아임포트가 웹훅노티피케이션을 제공해줌

  1. 결제가 승인되었을 때, 2. 가상계좌가 발급되었을 때, 3. 가상계좌에 결제 금액이 입금되었을 때, 4. 예약결제가 시도되었을 때 5. 환불

이런 이벤트들이 발생했을 때 아임포트가 타 서비스나 응용 프로그램으로 알림을 보내준다 !

아임포트 적용

import Head from "next/head";

declare const window: typeof globalThis & {
  IMP: any;
};

export default function PaymentPage() {
  const requestPay = () => {
    // 3. 결제 준비하기 (init 안에는 가맹점 식별코드 넣어줌)
    const IMP = window.IMP; // 생략 가능
    IMP.init(""); // 예: imp00000000

    // 4. 결제 요청하기 (결제버튼 클릭 시 PG사의 결제 페이지가 열리게)
    IMP.request_pay(
      {
        // param
        pg: "html5_inicis",
        pay_method: "card",
        // merchant_uid: "ORD20180131-0000011",
        // merchant_uid(상품 아이디) : 중복되면 안되기 때문에, 주석처리 해주면 자동으로 생성됨!
        name: "",
        amount: 100,
        buyer_email: "",
        buyer_name: "",
        buyer_tel: "",
        buyer_addr: "",
        buyer_postcode: "",
      },
      (rsp: any) => {
        // callback
        if (rsp.success) {
          console.log(rsp);
          alert("결제 성공");
          // ...,
          // // 결제 성공 시 로직,
          // ...
        } else {
          // ...,
          // // 결제 실패 시 로직,
          // ...
        }
      }
    );
  };

  return (
    <div>
      <Head>
        {/* 2.아임포트 라이브러리 추가하기 */}
        {/* <!-- jQuery --> */}
        <script
          type="text/javascript"
          src="https://code.jquery.com/jquery-1.12.4.min.js"
        ></script>
        {/* <!-- iamport.payment.js --> */}
        <script
          type="text/javascript"
          src="https://cdn.iamport.kr/js/iamport.payment-1.2.0.js"
        ></script>
      </Head>
      <button onClick={requestPay}>결제하기</button>
    </div>
  );
}

?? 근데 모바일에서 페이지에 들어간다면
결제 버튼 눌렀을 때 다른페이지로 이동해버림
그래서 결제 해도 실행이 안된다..! 이 때 사용해야 하는게 웹훅노티피케이션
그리고 모바일 결제가 끝난 뒤 다시 페이지로 돌아올 수 있도록 m_redirect_url 적어주기 !

시간

결제를 완료해서 백엔드로 api 요청을 보낼 때, 결제된 시간을 db에 함께 저장하게 된다

이때 이 시간을 new Date() 해서 프론트 서버에서 하면 안됨!
(사용자마다 설정한 pc 시간이 다르기 때문에)

그래서 시간을 생성하는 작업은 반드시 백엔드에서 해야 하고, 통상적 국제 표준시인 UTC를 이용

Moment.js

시간 관련 처리를 도와주는 라이브러리 자세한건 docs 참고

시간 관련 결제 이벤트

이벤트 할인 상품 판매, 정기결제, 경매 마감 등

이벤트를 발생시키는 방법
1. 클릭, 내용 입력 등 직접 이벤트 발생
2. 특정 시간에 자동으로 이벤트 발생

2번 같은 방법을 해주는 기능 : 크론탭(Crontab)

특정 날짜, 특정 시간 등에 특정 기능을 실행
(ex. 특정 시간에 API실행시켜줘, 특정 시간에 특정 스크립트 실행시켜줘(파일 등록))

시간 관련 결제 이슈

프론트엔드 서버에서 코드를 실행했을때 처리 순서

  1. callStack에서 onClickTimer 함수가 실행됩. (Stack - Last In First Out / LIFO 구조)
  2. Background에 setTimeout()을 보내서 실행
  3. setTimeout()이 TaskQueue로 전달되어 쌓임 (Queue - First In First Out / FIFO 구조)
  4. TaskQueue에 쌓이는 함수는 CallStack이 다 비워진 다음 가장 마지막에 실행

이벤트 루프 과정 위와 같은 순서에 따라 onClickTimer 함수 내에서 setTimeout이 가장 마지막에 실행되는 것

여기서 TaskQueue에 있는 함수를 CallStack으로 보내는 역할을 하는 일꾼이 있는데 스레드(Thread)라고 함

싱글 스레드

이벤트 루프 일꾼은 한명이라서 싱글 이벤트 루프 스레드 라고 함

Callstack이 비어야만 TaskQueue에 있는 작업을 CallStack으로 가져온다
= > Callstack이 작업중이라면, setTimeout에 설정한 1초가 이미 지났다고 하더라도 TaskQueue안의 작업이 CallStack으로 들어오지 못함

setInterval, setTimeout처럼 CallStack에 쌓이지 않고 Background, TaskQueue로 넘겨지는 작업을 비동기 작업이라고 한다(ex. axios는 비동기의 대표적인 라이브러리)

프로세스와 스레드

프로세스 : 실행되어있는 프로그램
스레드 : 프로세스 안에서 동작하는 일꾼

자바스크립트는 싱글 스레드 언어!
멀티 스레드 언어에는 자바, 파이썬 등이 있음

멀티스레드 언어 동작방식

이렇게 보면 멀티스레드는 여러 일꾼이 동시에 처리하는거니까 싱글 스레드보다 더 좋고 빠른 것 같지만!?

멀티 스레드의 경우에도 하나의 요청에 대한 응답을 기다렸다가 다음 작업으로 이동해야 하는 것은 동일하기 때문에(이러한 작업을 컨텍스트 스위칭이라고 함) 멀티 스레드라고 해서 싱글 스레드보다 두드러지게 빠르지는 않다

오히려 자바스크립트와 같은 이벤트 루프 싱글 스레드의 경우
오래 걸리는 작업을 TaskQueue로 빼서 처리하기 때문에 높은 퍼포먼스를 낼 수 있다

블로킹 vs 논블로킹

멀티스레드처럼 하나의 요청에 대한 응답이 와야만 다음 작업을 시작할 수 있는 방식을 블로킹 방식이라고 하고

이벤트 루프 싱글 스레드처럼 하나의 작업이 진행되는 동안 시간이 오래 걸리는 작업은 따로 마련한 공간에 보내서 실행하는 방식을 논블로킹 방식이라고 한다

자바스크립트는?
싱글 이벤트 루브 스레드 / 논블로킹 방식

++ 오늘 수업 참고자료

백엔드 api로 데이터 넘겨줄 때 참고

profile
어제보다 오늘 발전하는 프론트엔드 개발자

0개의 댓글