30분 안에 결제 페이지 개발하기 (ft. 결제위젯)

by 토스페이먼츠

결제 페이지는 개발할 요소가 많아요. 제품 정보, 결제 금액, 결제 수단, 이용약관 모두 하나부터 열까지 디자인하고 개발해야 돼요. 특히 여러 결제 수단을 연동하고 있다면, 각 수단의 결제창을 따로 연동해야 돼요.

이렇게 어려운 결제 연동, 토스페이먼츠가 결제위젯으로 쉽게 풀어드려요! 😊 결제위젯은 한 번 연동하면 다양한 결제 수단과 커스텀 디자인을 노코드(No-code)로 제공하는 서비스입니다. 이번 포스트에는 결제위젯으로 간단한 온라인 결제 페이지를 만들어볼게요.

SDK 추가

결제 페이지의 <script> 태그 안에 결제위젯 SDK 파일을 추가하세요.

<head>
<meta charset="utf-8" />
  <script src="<https://js.tosspayments.com/v1/payment-widget>"></script>
</head>

1️⃣ 위젯 렌더링

먼저 결제 페이지에 위젯만 렌더링해볼게요.

<body> 태그 안에 상품 정보 영역과 결제 방법 영역을 만들어 줘요. 상품 정보에는 주문명, 결제 금액을 보여주고 결제 방법에는 결제 위젯과 이용약관 위젯을 렌더링할 섹션을 정의해요. 이용약관 위젯에는 기본으로 토스페이먼츠 이용약관이 있고, 상점관리자에서 내 상점의 이용약관도 추가할 수 있어요.

<!-- 상품 정보 영역-->
<div class="title">상품 정보</div>
<p>토스 티셔츠</p>
<p>결제 금액: 15,000원</p>

<!-- 결제 방법 영역-->
<div class="title">결제 방법</div>
<div id="payment-method"></div>
<div id="agreement"></div>

<script> 태그 안에 위젯을 렌더링할게요. 먼저, 필수 파라미터를 정의하고 결제위젯 SDK를 초기화해요. 다음, 결제 위젯과 이용약관 위젯을 렌더링하세요. 메서드와 자세한 파라미터는 결제 위젯 SDK 가이드에서 확인할 수 있어요. 이제 페이지에 결제 방법 영역에 결제위젯, 이용약관 위젯이 생겼어요.

<script>
  const clientKey = 'test_ck_D5GePWvyJnrK0W0k6q8gLzN97Eoq' // 상점을 특정하는 키
  const customerKey = 'YbX2HuSlsC9uVJW6NMRMj' // 결제 고객을 특정하는 키
  const amount = 15_000 // 결제 금액

  /*결제위젯 영역 렌더링*/
  const paymentWidget = PaymentWidget(clientKey, customerKey) // 회원 결제 초기화
  // const paymentWidget = PaymentWidget(clientKey, PaymentWidget.ANONYMOUS) // 비회원 결제 초기화
  paymentMethods = paymentWidget.renderPaymentMethods('#payment-method', amount)

  /*약관 영역 렌더링*/
  const paymentAgreement = paymentWidget.renderAgreement('#agreement')
</script>

2️⃣ 결제 버튼 만들기

좋은 시작이지만 중요한 결제하기 버튼이 없어요. 😱 결제 방법 영역 맨 밑에 결제하기 버튼을 추가할게요.

<!-- 결제 방법 영역-->
<div class="title">결제 방법</div>
<div id="payment-method"></div>
<div id="agreement"></div>

<!-- 결제 버튼 -->
<button id="payment-button">결제하기</button>

버튼을 누르면 결제창이 떠야겠죠? 버튼의 클릭 이벤트로 결제창을 호출하는 requestPayment() 메서드를 등록할게요. 결제창 호출하는 메서드의 자세한 파라미터는 결제 위젯 SDK 가이드에서 확인해 보세요. 결제위젯에서 에러를 처리하는 방법도 더 자세히 알아보세요.

잘 따라왔다면 위 그림과 같이 토스페이를 선택하고 결제하기 버튼을 누르면 토스페이 결제창이 열려요.

<body>
	...
	<script>
		// ...
		/*결제요청 함수 정의*/
		document.querySelector("#payment-button").addEventListener("click",()=>{
		    paymentWidget.requestPayment({
		    	orderId: 'AD8aZDpbzXs4EQa-UkIX6',
		    	orderName: '토스 티셔츠 외 2건',
		    	successUrl: '<http://localhost:8080/success>',
		    	failUrl: '<http://localhost:8080/fail>',
		    	customerEmail: 'customer123@gmail.com',
		    	customerName: '김토스'
		    }).catch(function (error) {
		    	if (error.code === 'USER_CANCEL') {
		    	// 결제 고객이 결제창을 닫았을 때 에러 처리
		    	} if (error.code === 'INVALID_CARD_COMPANY') {
	            // 유효하지 않은 카드 코드에 대한 에러 처리
	          }
	      })
	  })
	</script>
</body>

3️⃣ 할인 쿠폰 적용

이제 기본적인 결제 페이지는 완성됐어요. 근데 실제 결제에는 쿠폰을 적용할 수도 있고, 제품 수량이 변경될 수도 있고, 다양한 이유로 결제 금액이 바뀌어요. 결제위젯을 이미 렌더링했는데, 금액을 어떻게 바꿀까요? 쿠폰을 적용하는 예시로 알아볼게요.

일단 쿠폰 금액을 정의해요.

const amount = 15_000
const couponAmount = 5_000 // 할인 쿠폰 금액

쿠폰을 적용하는 체크박스 UI를 만들어요.

<form id="discount-coupon">
	<input type="checkbox" id="coupon"/>5,000원 할인받기
</form>

쿠폰 박스가 체크되어 있으면 할인 금액으로 위젯을 업데이트하고, 체크가 안 되어 있으면 기존 가격으로 업데이트해요. 금액 업데이트는 SDK의 updateAmount() 메서드를 사용해요.

할인 박스를 체크하고 토스페이를 선택하면, 토스앱에서 결제 금액이 10,000원으로 잘 바뀐 걸 볼 수 있어요.

/*할인 쿠폰 적용*/
document.querySelector("#coupon").addEventListener("click", applyDiscount)

function applyDiscount(e) {
  if (e.target.checked) {
    paymentMethods.updateAmount(amount - couponAmount, "쿠폰")
  } else {
    paymentMethods.updateAmount(amount)
  }
 }

고객이 토스앱에서 결제하면 설정한 successUrl로 리다이렉트돼요. successUrl로 돌아온 쿼리 파라미터를 확인하고 결제 승인을 요청하세요. 결제 승인을 성공해야만 결제가 정상적으로 완료돼요.

노코드 운영

연동이 벌써 끝났다고요? 이제 토스페이먼츠 상점관리자에서 노출할 결제 수단을 선택하고, 내 쇼핑몰에 맞는 디자인을 적용해 보세요. 더 자세한 기능은 결제위젯 이해하기에서 확인하세요. 상점관리자는 토스페이먼츠와 계약한 뒤에 사용할 수 있습니다.

전체 코드 복사하기

<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charSet="utf-8"/>
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>결제 위젯</title>
  <script src="<https://js.tosspayments.com/v1/payment-widget>"></script>
  <style>
    #payment-button{ width:100%; padding:15px; background-color:#3065AC; color:white; border-radius:3px; font-size:16px; border:none; margin-top:10px}
	.title {margin: 0 0 4px; font-size: 24px; font-weight: 600;color: #4e5968;}
  </style>
</head>
<body>
  <!-- 상품 정보 영역-->
  <div class="title">상품 정보</div>
  <p>토스 티셔츠</p>
  <p>결제 금액: 15,000원</p>
  <form id="discount-coupon">
    <input type="checkbox" id="coupon"/>5,000원 할인받기
  </form>
  <hr>

  <!-- 결제 방법 영역-->
  <div class="title">결제 방법</div>
  <div id="payment-method"></div>
  <div id="agreement"></div>
  <button id="payment-button">결제하기</button>
</body>

<script>
  const clientKey = 'test_ck_D5GePWvyJnrK0W0k6q8gLzN97Eoq' // 상점을 특정하는 키
  const customerKey = 'YbX2HuSlsC9uVJW6NMRMj' // 결제 고객을 특정하는 키
  const amount = 15_000 // 결제 금액
  const couponAmount = 5_000 // 할인 쿠폰 금액

  /*결제위젯 영역 렌더링*/
  const paymentWidget = PaymentWidget(clientKey, customerKey) // 회원 결제
  // const paymentWidget = PaymentWidget(clientKey, PaymentWidget.ANONYMOUS) // 비회원 결제
  paymentMethods = paymentWidget.renderPaymentMethods('#payment-method', amount)

  /*약관 영역 렌더링*/
  const paymentAgreement = paymentWidget.renderAgreement('#agreement')

  /*결제창 열기*/
  document.querySelector("#payment-button").addEventListener("click",()=>{
    paymentWidget.requestPayment({
      orderId: 'AD8aZDpbzXs4EQa-UkIX6',
      orderName: '토스 티셔츠',
      successUrl: '<http://localhost:8080/success>',
      failUrl: '<http://localhost:8080/fail>',
      customerEmail: 'customer123@gmail.com',
      customerName: '김토스'
      }).catch(function (error) {
          if (error.code === 'USER_CANCEL') {
          // 결제 고객이 결제창을 닫았을 때 에러 처리
          } if (error.code === 'INVALID_CARD_COMPANY') {
            // 유효하지 않은 카드 코드에 대한 에러 처리
          }
      })
  })

  /*할인 쿠폰 적용*/
  document.querySelector("#coupon").addEventListener("click", applyDiscount)

  function applyDiscount(e) {
    if (e.target.checked) {
      paymentMethods.updateAmount(amount - couponAmount, "쿠폰")
    } else {
      paymentMethods.updateAmount(amount)
    }
  }
</script>
</html>

📍 함께 읽으면 좋을 콘텐츠

Writer 박수연 Graphic 이은호, 이나눔

ⓒ토스페이먼츠, 무단 전재 및 배포 금지

의견 남기기
토스페이먼츠

고객사의 성장이 곧 우리의 성장이라는 확신을 가지고 더 나은 결제 경험을 만듭니다. 결제가 불편한 순간을 기록하고 바꿔갈게요.