✅ 신용・체크 카드, 가상계좌, 계좌이체, 휴대폰, 상품권 결제를 웹 페이지에 한번에 연동할 수 있어요.
✅ 결제위젯 SDK를 사용해서 내 상점의 주문서 페이지에 최적의 주문서 UI를 만들 수 있어요.
토스페이먼츠에 회원가입하기 전이라면, 다음 문서 테스트 키로 결제위젯을 연동할 수 있어요.
토스페이먼츠에 회원가입했다면, 로그인 후 다음 내 테스트 키로 결제위젯을 연동하고 개발자센터에서 테스트 결제내역을 확인하세요. 커스터마이징 기능은 어드민 체험하기에서 살펴보세요.
// 문서 테스트 키
// 토스페이먼츠에 회원 가입하기 전이라면 아래 키로 자동결제를 연동하세요.
const clientKey = 'test_ck_D5GePWvyJnrK0W0k6q8gLzN97Eoq'
const secretKey = 'test_sk_zXLkKEypNArWmo50nX3lmeaxYG5R'
// 내 테스트 키
// 토스페이먼츠에 회원 가입하고 자동결제를 추가 계약한 뒤 아래 키로 자동결제를 연동하세요.
// 로그인하면 문서의 API 키가 모두 내 테스트 키로 변경됩니다.
const clientKey = 'test_ck_D5GePWvyJnrK0W0k6q8gLzN97Eoq'
const secretKey = 'test_sk_zXLkKEypNArWmo50nX3lmeaxYG5R'
토스페이먼츠와 계약을 완료했다면 상점 테스트 키로 결제위젯을 연동하고 상점관리자에서 커스터마이징을 해보세요. 상점 테스트 키는 '상점관리자 > 매출 · 정산 관리 > 내 상점 이름 > 개발 정보'에서 확인하세요.
계약 문의는 토스페이먼츠 고객센터(1544-7772, support@tosspayments.com)로 해주세요.
아래 예제 코드는 주문서 페이지에 결제위젯, 이용약관 UI를 그립니다. 결제하기 버튼을 눌러서 결제창을 띄워보세요. 실제로 결제되지 않으니 안심하세요.
<head>
<meta charset="utf-8" />
<!-- 결제위젯 SDK 추가 -->
<script src="https://js.tosspayments.com/v1/payment-widget"></script>
</head>
<body>
<!-- 결제위젯, 이용약관 영역 -->
<div id="payment-method"></div>
<div id="agreement"></div>
<!-- 결제하기 버튼 -->
<button id="payment-button">결제하기</button>
<script>
const clientKey = "test_ck_D5GePWvyJnrK0W0k6q8gLzN97Eoq"
const customerKey = "" // 내 상점에서 고객을 구분하기 위해 발급한 고객의 고유 ID
const button = document.getElementById("payment-button")
// ------ 결제위젯 초기화 ------
// 비회원 결제에는 customerKey 대신 ANONYMOUS를 사용하세요.
const paymentWidget = PaymentWidget(clientKey, customerKey) // 회원 결제
// const paymentWidget = PaymentWidget(clientKey, PaymentWidget.ANONYMOUS) // 비회원 결제
// ------ 결제위젯 렌더링 ------
// 결제수단 UI를 렌더링할 위치를 지정합니다. `#payment-method`와 같은 CSS 선택자와 결제 금액 객체를 추가하세요.
// DOM이 생성된 이후에 렌더링 메서드를 호출하세요.
// https://docs.tosspayments.com/reference/widget-sdk#renderpaymentmethods선택자-결제-금액-옵션
paymentWidget.renderPaymentMethods(
"#payment-method",
{ value: 15000 },
{ variantKey: "DEFAULT" } // 렌더링하고 싶은 결제 UI의 variantKey
)
// ------ 이용약관 렌더링 ------
// 이용약관 UI를 렌더링할 위치를 지정합니다. `#agreement`와 같은 CSS 선택자를 추가하세요.
// https://docs.tosspayments.com/reference/widget-sdk#renderagreement선택자
paymentWidget.renderAgreement('#agreement')
// ------ '결제하기' 버튼 누르면 결제창 띄우기 ------
// 더 많은 결제 정보 파라미터는 결제위젯 SDK에서 확인하세요.
// https://docs.tosspayments.com/reference/widget-sdk#requestpayment결제-정보
button.addEventListener("click", function () {
paymentWidget.requestPayment({
orderId: "", // 주문 ID(직접 만들어주세요)
orderName: "토스 티셔츠 외 2건", // 주문명
successUrl: "https://my-store.com/success", // 결제에 성공하면 이동하는 페이지(직접 만들어주세요)
failUrl: "https://my-store.com/fail", // 결제에 실패하면 이동하는 페이지(직접 만들어주세요)
customerEmail: "customer123@gmail.com",
customerName: "김토스"
})
})
</script>
</body>
결제위젯 SDK는 Web, Native Android, Native iOS를 지원하고 있어요. Flutter, React Native에서는 웹뷰로 결제위젯 SDK를 구현하세요.
customerKey
는 내 상점에서 고객을 구분하기 위해 발급한 고객의 고유 ID입니다. 다른 사용자가 이 값을 알게 되면 악의적으로 사용할 수 있어 자동 증가하는 숫자는 안전하지 않습니다. UUID와 같이 충분히 무작위적인 고유 값으로 생성해주세요. 또, 고객에게 할당된 customerKey는
변경없이 항상 같은 값을 사용해주세요. customerKey
는 재구매율, 이탈률, 구매전환율 등을 측정하거나 결제창에서 이탈한 고객을 다시 결제로 유도하는데 이용됩니다.
아니요. 커스텀 파라미터를 보내거나 결제 승인 응답에 커스텀 파라미터를 포함시키는 기능은 지원되지 않습니다.
대신 다음과 같은 방법을 사용할 수 있습니다. 첫 번째 방법은 결제 성공 후 이동하는 successUrl
로 받는 방법입니다. 적은 양의 데이터라면 successUrl
의 쿼리 파라미터로 추가해서 확인할 수 있습니다. 만약 전달하고자 하는 데이터가 많거나 결제 완료 전에 데이터를 처리해야 한다면, 결제 요청을 하기 전에 데이터베이스에 저장하세요. 예를 들면 orderId
등과 데이터를 맵핑해서 가맹점 데이터베이스에 저장하는 방식입니다. 또는 세션이나 쿠키를 활용하거나 Promise를 사용해서 객체로 데이터를 받을 수 있습니다. 다만 Promise 방식은 모바일에서 사용할 수 없으니 유의하세요.
아니요. 렌더링이 완료되었을 때 이벤트를 제공하지 않습니다.
애플페이는 iPhone 및 Mac Safari 에서만 노출돼요. 어드민 페이지에서는 예상 이미지를 확인할 수 있습니다.
네. getSelectedPaymentMethod()
를 호출해서 고객이 선택한 결제수단을 확인할 수 있습니다.
토스페이먼츠에서 발급하지 않은 클라이언트 키 혹은 시크릿 키를 사용했을 때 발생합니다. 개발자센터에 들어가서 키 값을 다시 확인하고 시크릿 키 인증을 올바르게 했는지 확인해주세요.
결제위젯을 생성하지 않은 클라이언트 키로 연동을 시도하면 발생합니다. 상점관리자에서 결제위젯 UI를 추가하세요.
결제 금액이 바뀐다면 updateAmount()
를 사용해서 결제위젯을 업데이트하세요.
// 새로운 결제 금액을 넣어주세요.
paymentMethods.updateAmount(50000)
여러 UI를 만들고 상황에 따라 다른 결제 UI를 노출해보세요. 계정이나 상품별로 다른 결제수단을 보여주고 싶을 때 사용하세요.
상점관리자의 결제 UI 설정 메뉴에서 UI 추가하기 버튼을 누르고 팝업창에서 키값을 설정하세요. 추가한 UI를 선택해서 커스터마이징하세요.

렌더링하고 싶은 결제 UI의 키값을 variantkey
파라미터로 넣으세요. 키값을 넣지 않으면 기본 UI가 렌더링됩니다.
paymentWidget.renderPaymentMethods(
"#payment-method",
{ value: 10000 },
{ variantKey: "widgetA" }
)
결제 요청 결과를 확인할 차례에요. 결제 요청이 성공하면 requestPayment()
의 파라미터로 설정했던 (successUrl
)을 통해 결제 성공 페이지로 이동합니다. 성공 리다이렉트 URL을 나타내는 success
뒤에 네 가지 쿼리 파라미터가 들어있습니다.
https://my-store.com/success?paymentKey={PAYMENT_KEY}&orderId={ORDER_ID}&amount={AMOUNT}&paymentType={PAYMENT_TYPE}
paymentKey
: 결제의 키 값입니다. 결제를 식별하는 역할로, 중복되지 않는 고유한 값입니다. 결제 데이터 관리를 위해 반드시 저장해야 합니다. 결제 상태가 변해도 값이 유지됩니다. 결제 승인에 사용됩니다.orderId
:주문 ID입니다. 주문한 결제를 식별하는 역할로, 결제를 요청할 때 가맹점에서 만들어서requestPayment()
에 담아 보낸 값입니다. 결제 데이터 관리를 위해 반드시 저장해야 합니다. 중복되지 않는 고유한 값을 발급해야 합니다. 결제 상태가 변해도 값이 유지됩니다.amount
: 실제로 결제된 금액입니다.paymentType
: 결제 유형입니다.NORMAL
,BRANDPAY
,KEYIN
중 하나입니다.
renderPaymentMethods()
메서드에 담아 보낸 결제 금액과 successUrl
로 돌아온 amount
값이 같은지 반드시 확인해보세요. 클라이언트에서 결제 금액을 조작해 승인하는 행위를 방지할 수 있습니다.
만약 값이 다르다면 결제를 취소하고 구매자에게 알려주세요. 적립금이나 쿠폰이 적용된 금액이 맞는지도 확인해보세요.
결제 요청이 실패하면 설정했던 결제 실패 페이지(failUrl
)로 이동합니다. 에러 목록을 확인하세요.
https://my-store.com/fail?code={ERROR_CODE}&message={ERROR_MESSAGE}&orderId={ORDER_ID}
결제를 요청하면 차례로 인증과 승인 과정이 진행됩니다.
- 인증: 결제를 승인하기 전 결제 정보가 올바른지 검증하는 과정입니다.
- 승인: 인증에 성공한 결제를 최종 승인하는 과정입니다. 승인 요청에 성공하면 결제 요청 과정이 끝납니다.
결제 요청 과정에 대한 더 자세한 설명은 결제 흐름 이해하기에서 확인해보세요.
인증과 승인 사이에 리다이렉트 과정이 있습니다. 두 단계로 나누어져 있는 결제 요청 과정에서 첫 번째 단계인 인증 결과를 받아 다음 단계로 넘어가기 위해 리다이렉트 URL 처리가 필요합니다. 토스페이먼츠에서 인증 결과를 URL의 쿼리 파라미터에 담아 리다이렉트하면, 상점에서는 리다이렉트 URL을 받아 결제 승인을 처리할 수 있게 됩니다.
인증에 성공했다면 성공 리다이렉트 URL(successUrl
)에 쿼리 파라미터로 담긴 결제 정보를 이용해 승인 API를 호출합니다. 인증에 실패했다면 이동한 실패 리다이렉트 URL(failUrl
)에 쿼리 파라미터로 담긴 에러 정보를 보며 디버깅합니다.
더 자세한 내용은 리다이렉트 처리하기에서 확인해보세요.
결제 승인 API를 호출해서 마지막 단계를 완료합니다. 먼저 API 인증을 위해 아래와 같이 인증 헤더 값을 만듭니다.
시크릿 키 뒤에 :
을 추가하고 base64로 인코딩합니다. :
을 빠트리지 않도록 주의하세요.
base64('test_sk_zXLkKEypNArWmo50nX3lmeaxYG5R:')
─────────────────┬───────────────── ┬
secretKey :
발급받은 시크릿 키 콜론
아래 명령어를 터미널에서 실행하면 인코딩된 값을 얻을 수 있습니다.
echo -n 'test_sk_zXLkKEypNArWmo50nX3lmeaxYG5R:' | base64
인코딩된 값을 Basic 인증 헤더에 넣고 요청 본문도 추가하세요. 앞 단계에서 리다이렉트 URL로 받은 paymentKey
, orderId
, amount
를 넣어주세요.
아래 예제 코드에는 내 테스트 결제의 paymentKey
값을 넣어 실행해주세요.
curl --request POST \
--url https://api.tosspayments.com/v1/payments/confirm \
--header 'Authorization: Basic dGVzdF9za196WExrS0V5cE5BcldtbzUwblgzbG1lYXhZRzVSOg==' \
--header 'Content-Type: application/json' \
--data '{"paymentKey":"{PAYMENT_KEY}","amount":15000,"orderId":"sUt20na9SCZMOQDMyfR2i"}'
성공 페이지로 리다이렉트 된 후 10분 이내에 결제 승인 API를 호출하지 않았거나, 결제창을 iframe 안에서 호출했기 때문입니다. 브라우저의 보안 정책에 따라 성공 페이지로 이동이 차단될 수 있으니 iframe은 사용하지 말아주세요.
결제 승인에 성공하면 HTTP 200 OK
와 Payment 객체를 받습니다.
{
"mId": "tosspayments",
"version": "2022-11-16",
"paymentKey": "",
"status": "DONE",
"lastTransactionKey": "",
"orderId": "",
"orderName": "토스 티셔츠 외 2건",
"requestedAt": "2022-06-08T15:40:09+09:00",
"approvedAt": "2022-06-08T15:40:49+09:00",
"useEscrow": false,
"cultureExpense": false,
"card": {
"issuerCode": "61",
"acquirerCode": "31",
"number": "12345678****789*",
"installmentPlanMonths": 0,
"isInterestFree": false,
"interestPayer": null,
"approveNo": "00000000",
"useCardPoint": false,
"cardType": "신용",
"ownerType": "개인",
"acquireStatus": "READY",
"amount": 15000
},
"virtualAccount": null,
"transfer": null,
"mobilePhone": null,
"giftCertificate": null,
"cashReceipt": null,
"cashReceipts": null,
"discount": null,
"cancels": null,
"secret": null,
"type": "NORMAL",
"easyPay": null,
"country": "KR",
"failure": null,
"isPartialCancelable": true,
"receipt": {
"url": "https://dashboard.tosspayments.com/sales-slip?transactionId=KAgfjGxIqVVXDxOiSW1wUnRWBS1dszn3DKcuhpm7mQlKP0iOdgPCKmwEdYglIHX&ref=PX"
},
"checkout": {
"url": "https://api.tosspayments.com/v1/payments//checkout"
},
"currency": "KRW",
"totalAmount": 15000,
"balanceAmount": 15000,
"suppliedAmount": 13636,
"vat": 1364,
"taxFreeAmount": 0,
"method": "카드"
}
✔️ 응답 객체에 선택한 결제수단 필드가 있는지 확인하세요.
✔️ 응답 객체의 method
가 선택한 결제수단인지 확인하세요.
✔️ 간편결제를 테스트했다면 선택한 결제수단에 따라 돌아오는 응답 객체가 달라집니다. 간편결제 응답 처리를 참고하세요.
✔️ 가상계좌를 테스트했다면 입금하고 결제를 완료하세요. 환불 계좌를 입력받았다면 환불 계좌 정보도 확인하세요.