홈으로 돌아가기
TossPayments logo

토스페이먼츠 TossPayments

토스페이먼츠 결제 위젯

토스페이먼츠 간편결제 서비스입니다. Client Key를 입력하면 실제 결제 위젯을 테스트해볼 수 있습니다.

[추천] 공식 예제 보기

토스페이먼츠 샌드박스에서 다양한 결제 시나리오와 상세한 예제를 확인하세요. (여기가 더 잘만들었어요.)

토스페이먼츠 샌드박스 바로가기

API 키 설정

보안 경고

테스트용 키만 사용하세요. 라이브 키는 절대 입력하지 마세요!

설정 가이드

1

토스페이먼츠 회원가입

토스페이먼츠 웹사이트에서 가맹점 계정을 생성하세요.

2

Client Key 확인

토스페이먼츠 개발자센터에서 Client Key를 확인하세요.

3

결제 방법 설정

사용할 결제 수단을 설정하고 승인을 받으세요.

4

웹사이트에 적용

아래 코드를 웹사이트에 추가하세요.

실시간 데모

API 키를 입력하면 실시간 데모를 확인할 수 있습니다.

SDK 설치 및 설정

토스페이먼츠 SDK를 설치하고 초기 설정을 진행합니다.

SDK 설치

bash
npm install @tosspayments/tosspayments-sdk --save

React 컴포넌트 사용법

@tosspayments/tosspayments-sdk를 사용한 React 컴포넌트 구현 방법입니다.

결제 위젯 컴포넌트

tsx
'use client';

import { useState, useEffect, useRef } from 'react';
import { loadTossPayments } from '@tosspayments/tosspayments-sdk';

export default function TossPaymentsComponent() {
  const [amount, setAmount] = useState(50000);
  const [widgets, setWidgets] = useState<any>(null);
  const [isInitialized, setIsInitialized] = useState(false);
  const paymentMethodsRef = useRef<HTMLDivElement>(null);
  const agreementRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    initializeTossPayments();
  }, []);

  useEffect(() => {
    if (widgets && amount > 0) {
      updateAmount();
    }
  }, [widgets, amount]);

  const initializeTossPayments = async () => {
    try {
      const clientKey = 'test_gck_';
      const tossPayments = await loadTossPayments(clientKey);
      
      const widgetsInstance = tossPayments.widgets({
        customerKey: 'customer-' + Date.now()
      });

      // 결제 금액 설정
      await widgetsInstance.setAmount({
        value: amount,
        currency: 'KRW'
      });

      // 결제 UI 렌더링
      await widgetsInstance.renderPaymentMethods({
        selector: '#payment-methods',
        variantKey: 'DEFAULT'
      });

      // 약관 동의 UI 렌더링
      await widgetsInstance.renderAgreement({
        selector: '#agreement'
      });

      setWidgets(widgetsInstance);
      setIsInitialized(true);
    } catch (error) {
      console.error('TossPayments 초기화 실패:', error);
    }
  };

  const updateAmount = async () => {
    if (!widgets) return;
    
    try {
      await widgets.setAmount({
        value: amount,
        currency: 'KRW'
      });
    } catch (error) {
      console.error('금액 업데이트 실패:', error);
    }
  };

  const handlePayment = async () => {
    if (!widgets) {
      alert('결제 위젯이 준비되지 않았습니다.');
      return;
    }

    try {
      await widgets.requestPayment({
        orderId: 'order-' + Date.now(),
        orderName: '테스트 상품',
        customerName: '김토스',
        customerEmail: 'test@example.com',
        customerMobilePhone: '01012341234',
        successUrl: `${window.location.origin}/tosspayments/success`,
        failUrl: `${window.location.origin}/tosspayments/fail`
      });
    } catch (error) {
      console.error('결제 요청 실패:', error);
    }
  };

  return (
    <div className="max-w-md mx-auto p-4">
      <div className="mb-4">
        <label className="block text-sm font-medium mb-2">결제 금액</label>
        <input
          type="number"
          value={amount}
          onChange={(e) => setAmount(Number(e.target.value))}
          className="w-full px-3 py-2 border rounded-md"
          min="100"
        />
      </div>
      
      {/* 결제 수단 선택 UI */}
      <div id="payment-methods" ref={paymentMethodsRef}></div>
      
      {/* 약관 동의 UI */}
      <div id="agreement" ref={agreementRef}></div>
      
      <button
        onClick={handlePayment}
        disabled={!isInitialized}
        className="w-full mt-4 px-4 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:bg-gray-400"
      >
        {isInitialized ? `${amount.toLocaleString()}원 결제하기` : '초기화 중...'}
      </button>
    </div>
  );
}