기술/웹 개발

[PortOne/react] 통합 결제 연동 솔루션 포트원 react 프로젝트에 이식하기

하기싫지만어떡해해야지 2024. 8. 30. 00:07

이번애 배정받은 업무는

개발하고 있는 웹 사이트의 결제 기능 개발이었다

 

결제를 위해서는 PortOne API

연동을 알아봐달라고 요청받아서

이번에 기능을 구현해보면서

티스토리에도 남겨보려고 한다


PortOne이란?

포트원은 여러 가지 결제대행사들을

연동해서 결제를 도와주는

서비스이다

https://portone.io/korea/ko

 

포트원 | 온라인 비즈니스 성장을 돕는 기업

포트원이 제공하는 단 한 줄의 코드로 세상의 모든 결제를 손쉽게 연동해보세요. PG사 통합결제 연동, 해외결제, 파트너 정산 관리, 결제 애널리틱스, 수수료 혜택까지, 포트원의 맞춤 컨설팅을

portone.io

 

설명에 따르면

신용카드, 간편결제, 해외결제까지 모두

손쉽게 연동이 가능하다고 한다


PortOne 회원가입

회원가입이 되어있지 않다면

당연히 회원가입부터 해야한다

 

email과 비밀번호만 설정해주면 간단하다

 

연동 채널 추가

회원가입을 해주고 PortOne에 접속하면

PortOne Console 페이지가 뜬다

 

이 때 왼쪽의 메뉴 사이드바에서

 

연동관리 -> 연동 정보에 접속해준다

 

그럼 아래와 같은 창이 뜨는데

연동을 시도해 볼 채널을 설정해주는 창이다

 

 

연동모드는 실제와 테스트모드가 있는데

테스트 모드로 하려고 테스트 모드

 

결제 대행사는

가장 무난하다고 생각한

나이스페이먼츠

 

결제모듈은 신모듈을 선택했다

 

그런 다음

다음 버튼을 누르면

 

오른쪽에 사이드바로

아래와 같은 화면이 뜨는데

 

PG상점아이디(MID)를 클릭하면

아래에 공용 MID가 3개 뜨는데

나는 가장 위에 있는

일반 결제를 선택해주었다

 

PG상점아이디를 선택해주면

채널 이름, Key, 결제취소비밀번호가

자동으로 생성된다

 

 

그리고 저장 버튼을 눌러주면

 

 

 

 

위와 같이 연동정보 채널이 추가 된다

 

 

PortOne SDK 설치

이제 우리의 프로젝트로 돌아와서

프로젝트에 포트원 SDK를 설치해줘야한다

 

npm이나 yarn으로 설치할 수도 있고

<script>요소로 추가할 수도 있다

 

나는 npm으로 설치해줬다

npm i @portone/browser-sdk

 

패키지 설치를 완료해주면

portone을 써야하는 파일의 위에

import * as PortOne from "@portone/browser-sdk/v2";

 

위와 같이 import를 해준다

 

API 호출 버튼 만들기

내가 담당하고 있는 결제 창은

 

위와 같은 Choose Plan 이라는 버튼을 누르면

결제창으로 넘어가는 방식이었다

 

따라서 저 버튼을 누르면

결제 API를 호출하도록 작성해보았다

 

 

우선 새로운 js 파일을 만들어서

PricingButton 컴포넌트를 작성해주었다

import React from 'react';
import * as PortOne from "@portone/browser-sdk/v2";

const PricingApiButton= ({ title, price, storeId, channelKey }) => {
   // Payment request function
  const handlePayment = async () => {
    try {
        const paymentId = `payment-${crypto.randomUUID()}` // Generate unique payment ID
        const response = await PortOne.requestPayment({
            storeId: storeId, 
            channelKey: channelKey, 
            paymentId: paymentId, 
            orderName: title, 
            totalAmount: price, 
            currency: "CURRENCY_KRW",
            payMethod: "CARD", 
        });
        console.log('Payment successful:', response);
        alert('Payment was successfully completed.');
        } catch (error) {
        console.error('Payment failed:', error);
        alert('Payment failed. Please try again.');
        }
    };
    return (
        <div>
            <button
            onClick={handlePayment}
            className="choose-plan-button">
                Choose Plan
            </button>
        </div>
      );
};

export default PricingApiButton;

 

결제 요청을 할 때

storeId와 channelKey가 필요한데

 

우선 storeId는

PortOne Console창을 띄운다음

가장 상단 우측에 상점 아이디가 있다

 

위 사진에서 카톡개가

가리키고 있는 곳 ..

 

그리고 channelKey는

아까 우리가 추가해주었던 채널을

확인해보면 알 수 있다

MID 옆에 채널키가 나와있어서

복사해서 그대로 넣어주면 된다

 

 

그리고 paymentId는 공식문서의 설명에 따르면

 

그렇다고 한다

 

그래서 자동으로 RandomUUID를

생성하는 공식문서의 방식을

그대로 사용했다

 

 

그런 다음 해당 Button을

불러줘야할 컴포넌트에

파라미터들과 함께 넘겨줬다

 

price를 숫자로 넘겨주지않으면

에러뜬다

 

 

 

그런 다음 버튼을 클릭해서

테스트 해봤더니

 

짜잔

 

이렇게 나이스페이먼츠 화면이

뜨는 것을 알 수 있다

 

 

10원으로 하니 결제최소금액보다 아래라고해서

1000원으로 변경한 후 테스트를 해봤다

 

이런 화면이 뜨고

뭘로 할까 고민하다가 카카오페이로 했다

 

카카오페이를 선택하면 QR로 넘어가는 화면이 뜨고

모바일 카카오페이에서 결제를 완료해줬다

 

 

결제 내용 확인 후

결제내용을 확인했다는 거에 동의 누르고

결제 완료 버튼을 누르면

 

결제 성공 시 띄우게 해줬던

alert창이 정상적으로 뜨는 것을 확인할 수 있다

 

 

테스트모드를 켜놓고 결제했는데

실제로 결제가 됐길래

 

이러고 있었는데

https://faq.portone.io/9fb1462e-94b1-4d1f-86fb-66262306e066

 

테스트모드에서 결제했는데 환불되나요?

가상계좌와 에스크로 결제를 제외한 모든 테스트 결제는 카드사 매입전 자동적으로 취소 됩니다. (예외 : 허브형 간편결제는 자동취소가 되지 않으니 반드시 직접 취소처리해주시기 바랍니다)

faq.portone.io

 

테스트모드에선 카카오페이는

실출금이 되지않는다는데

난 왜 됐지?

내 1000원 빠져나갔는데??

 

??????

 

이건 이제 지금부터 알아봐야됨 ㅋㅋ

내 돈 ㅠ


 

아무튼

급하게 테스트해보려고 띄워봤는데

생각보다 쉽게 됐다

 

이제 결제 성공시, 실패시 등등

결제 이후의 로직을 좀 더 

구체적으로 구현해야할 것 같다

 

 

그럼 빠져나간 내 1000원 찾으러

이만-!