Next.js에서 NICEPAY JS SDK 연동하기

짜장킴·2026년 7월 6일

실무

목록 보기
13/16
  • NICEPAY는 별도의 React 라이브러리나 npm 패키지를 제공하지 않는다.
  • 대신 브라우저에서 JS SDK를 로드한뒤 AUTHNICE.requestPay()를 호출하는 방식으로 결제 진행
  • 공식 문서에서도 JS SDK URL(https://pay.nicepay.co.kr/v1/js/)을 로드한 후 AUTHNICE.requestPay()를 사용하도록 안내하고 있다.

요구 사항

  • 사용자가 충전 금액 선택
  • 주문 생성 API 호출
  • NICEPAY 카드 결제 진행
  • 결제 성공 시 백엔드 검증 후 결과 페이지 이동
  • 결제 실패 시 실패 페이지로 이동

1. 결제 금액 선택

  • 먼저 사용자가 충전 금액을 선택할 수 있도록 구현했다.
  • 백엔드에서 충전 상품 목록을 조회한 뒤 버튼 형태로 렌더링하였다.
const [selected, setSelected] = useState<number | null>(null);
const [selectedIdx, setSelectedIdx] = useState<number | null>(null);
  • 선택된 상품의 가격과 상품 ID를 상태로 관리하였다.

2. 주문 생성 API 호출

  • 실제 결제 요청 전에 백엔드에서 주문 정보를 생성한다.
const { data: orderInfo } = useQuery({
  queryKey: ["productOrder", selectedIdx],
  enabled: open && selectedIdx !== null,
  queryFn: () =>
    getAdjustmentOrder({
      productInfoIdx: selectedIdx!,
    }),
});
  • 주문 생성 API를 통해 다음 정보를 받아온다.
    - orderId
    - amount
  • NICEPAY는 결제 요청 시 orderId가 반드시 필요하기 때문에 사전에 생성해두어야 한다.

3. NICEPAY 스크립트 로드

  • NICEPAY는 외부 스크립트를 통해 결제 창을 제공한다.
  • Next.js에서는 Script 컴포넌트를 사용하여 로드했다.
  • 스크립트가 로드되지 않은 상태에서 결제를 시도하면 오류가 발생할 수 있으므로 별도의 상태값으로 관리했다.
<Script
  src="https://pay.nicepay.co.kr/v1/js/"
  strategy="afterInteractive"
  onLoad={() => setScriptLoaded(true)}
/>

if (!scriptLoaded || !window.AUTHNICE) {
  alert("결제 모듈을 불러오는 중입니다.");
  return;
}

4. 결제 요청

  • 실제 결제는 AUTHNICE.requestPay를 호출하여 진행한다.
  • returnUrl : 결제 완료 후 이동할 URL => 백엔드로 전달할 api 요청
window.AUTHNICE.requestPay({
  clientId,
  method: "card",
  orderId: orderInfo.orderId,
  amount: orderInfo.amount,
  goodsName: `캐시 ${formatPrice(selected)} 충전`,
  returnUrl: `${process.env.NEXT_PUBLIC_API_BASE_URL}/adjustment?redirectBaseUrl=${encodeURIComponent(redirectBaseUrl)}`,
  
   fnError: (result) => {
       const params = new URLSearchParams({
         code: result.errorCode,
         message: result.errorMsg,
        });

      window.location.href = `/billing/payment/fail?${params.toString()}`;
      },
});

5. 결제 완료 후 처리

  • 결제가 완료되면 NICEPAY는 returnUrl로 결과를 전달한다.
const redirectBaseUrl = window.location.origin;

returnUrl =
  `${API_BASE_URL}/adjustment?redirectBaseUrl=${encodeURIComponent(
    redirectBaseUrl
  )}`;
  • 백엔드는 NICEPAY로부터 전달받은 결제 정보를 검증한 뒤 최종 결제 승인 처리를 수행한다.
  • 이후 성공 여부에 따라 프론트의 성공 페이지 또는 실패 페이지로 리다이렉트한다.
  • 또한 window.location.origin을 함께 전달하여 로컬, 테스트 서버, 운영 서버 환경에 따라 올바른 페이지로 이동할 수 있도록 처리하였다.

6. 결제 실패 처리

  • 결제 실패도 별도로 처리했다.
fnError: (result) => {
  const params = new URLSearchParams({
    code: result.errorCode,
    message: result.errorMsg,
  });

  window.location.href =
    `/billing/payment/fail?${params.toString()}`;
}
  • 실패 시 에러 코드, 에러 메시지를 전달하여 사용자에게 실패 사유를 표시할 수 있도록 구성했다.

토스페이먼츠와의 차이점

  • 토스는 프론트 중심의 흐름이라면 NICEPAY는 백엔드 중심의 흐름에 가깝다.

토스페이먼츠

  • 토스페이먼츠는 결제 완료 후 성공 URL 또는 실패 URL로 이동한다.
  • 프론트엔드에서 결제 결과를 직접 받아 백엔드 승인 API를 호출하는 구조를 사용할 수 있다.

결제창

성공 URL 이동

프론트엔드

백엔드 승인 API 호출

NICEPAY

  • 반면 NICEPAY는 결제 결과를 먼저 returnUrl로 전달한다.
  • 일반적으로 returnUrl은 백엔드 API로 구성하며, 백엔드에서 결제 검증 및 승인 처리를 수행한 후 최종 페이지로 리다이렉트한다.

결제창

returnUrl 호출

백엔드

결제 검증 및 승인

성공/실패 페이지 이동

profile
프론트엔드

0개의 댓글