결제 연동/자동결제(빌링)/결제창 연동하기
목차

✅ 자동결제는 다른 이름으로 빌링, 또는 정기결제로 불리는 결제 방식입니다. 카드 등록창에서 고객의 카드를 처음 한 번 등록하고 나면, 이후 별도의 고객 인증 없이 간편하게 결제를 요청할 수 있습니다.

✅ 토스페이먼츠 결제창 SDK로 자동결제(빌링)를 연동할 수 있습니다.

✅ 만약 정기적으로 발생하는 결제가 아니라 원하는 시점에 결제를 내고 싶다면 자체 간편결제 서비스인 브랜드페이를 연동하세요.

샘플 프로젝트카드 자동결제 샘플 프로젝트입니다.

API 키 준비하기

자동결제는 API 개별 연동 키로 연동하세요.

토스페이먼츠에 회원가입하기 전이라면, 다음 문서 테스트 키로 연동할 수 있어요. 토스페이먼츠에 회원가입했다면, 로그인 후 다음 내 테스트 키로 결제를 연동하고 개발자센터에서 테스트 결제내역을 확인하세요.

JavaScript
// API 개별 테스트 연동 키
// 토스페이먼츠에 회원 가입하기 전이라면 아래 키는 문서 테스트 키입니다.
// 토스페이먼츠에 회원 가입하고 로그인한 상태라면 아래 키는 내 테스트 키입니다.
const clientKey = 'test_ck_D5GePWvyJnrK0W0k6q8gLzN97Eoq'
const secretKey = 'test_sk_zXLkKEypNArWmo50nX3lmeaxYG5R'

자동결제는 추가 계약 후 테스트 및 라이브 환경에서 사용할 수 있습니다. 추가 계약을 하고 싶다면 토스페이먼츠 고객센터(1544-7772, support@tosspayments.com)로 문의해주세요.

자동결제 연동 흐름 이해하기

카드 자동결제 흐름도

큰 흐름은 다음과 같습니다.

  • 카드 등록창 호출 (Client): SDK로 카드 등록창을 띄우고 고객의 카드 정보를 인증, 등록하세요.
  • 빌링키 발급 API 요청 (Server): API로 빌링키를 발급하고 데이터베이스에 저장하세요.
  • 빌링 결제 승인 요청 (Server): API로 발급한 빌링키로 원하는 주기, 시점에 자동결제를 실행하세요. 스케줄링 기능은 직접 구현해야 합니다.

이제 각 단계를 자세히 알아볼게요.

1. 고객 카드 등록하기

자동결제를 실행하려면 먼저 고객의 카드를 등록해서 빌링키를 발급해야 합니다. 아래 예제 코드를 실행하면 다음과 같은 카드 등록창을 띄울 수 있습니다.

카드 자동결제 결제수단 등록창 예시 이미지

<head>
<title>결제하기</title>
<meta charset="utf-8" />
<!-- 토스페이먼츠 결제창 SDK 추가 -->
<script src="https://js.tosspayments.com/v1/payment"></script>
</head>
<body>
<script> // ------ 클라이언트 키로 객체 초기화 ------ var clientKey = 'test_ck_D5GePWvyJnrK0W0k6q8gLzN97Eoq' var tossPayments = TossPayments(clientKey) tossPayments .requestBillingAuth('카드', { // 결제수단 파라미터 (자동결제는 카드만 지원합니다.) // 결제 정보 파라미터 customerKey: '', // 고객 ID로 상점에서 만들어야 합니다. 빌링키와 매핑됩니다. 자세한 파라미터 설명은 파라미터 설명을 참고하세요: https://docs.tosspayments.com/reference/js-sdk#결제-정보-5 successUrl: 'https://my-store.com/success', // 카드 등록에 성공하면 이동하는 페이지(직접 만들어주세요) failUrl: 'https://my-store.com/fail', // 카드 등록에 실패하면 이동하는 페이지(직접 만들어주세요) }) .catch(function (error) { if (error.code === 'USER_CANCEL') { // 결제 고객이 결제창을 닫았을 때 에러 처리 } }) </script>
</body>

SDK를 추가한 뒤 클라이언트 키를 사용해 객체를 초기화합니다. 초기화된 객체로 requestBillingAuth('카드')를 실행하면 카드 등록창이 뜹니다.

고객이 카드 등록창에 카드 정보를 입력하고 휴대폰 본인인증을 성공적으로 마치면 successUrl로 이동합니다. successUrl에는 쿼리 파라미터가 포함되어 있습니다. 이 파라미터를 이용해 빌링키를 발급 받습니다.

  • 테스트 환경에서는 본인인증 문자가 발송되지 않습니다. 본인인증창이 뜨면 인증번호로 000000을 입력하세요.

  • 테스트 환경에서는 카드 번호의 앞 여섯 자리(BIN 번호)만 유효해도 자동결제가 등록됩니다. 라이브 환경에서는 전체 카드 번호가 유효해야 등록됩니다.

  • 해외카드, 해외결제는 지원하지 않습니다.

requestBillingAuth('카드') 이해하기

자동결제에 사용할 카드 정보를 등록할 카드 등록창을 띄울 수 있는 메서드예요. 카드 등록창을 띄우려면 파라미터에 카드, 결제 정보를 추가해야 해요.

1️⃣ 현재 자동결제 결제수단은 국내에서 발급한 카드만 지원해요. 그래서 첫 번째 파라미터는 항상 카드로 고정되어 있어요.

2️⃣ 결제 정보는 두 번째 파라미터로 추가하세요. 고객을 특정하는 customerKey는 필수 파라미터에요. successUrlfailUrl은 카드 등록에 성공하거나 실패했을 때 이동하는 페이지에요. customerKey와 이동할 페이지는 직접 만들어야 해요. 파라미터에 대한 자세한 설명은 JavaScript SDK 레퍼런스를 참고하세요.

2. 카드 등록 요청 결과 확인하기

카드 등록 요청 결과를 확인할 차례에요. 카드 등록 요청이 성공하면 requestBillingAuth()의 파라미터로 설정했던 (successUrl)을 통해 빌링키 요청 성공 페이지로 이동합니다. 성공 리다이렉트 URL을 나타내는 success 뒤에 customerKey, authKey 두 가지 쿼리 파라미터가 들어있습니다.

https://my-store.com/success?customerKey={CUSTOMER_KEY}&authKey={AUTH_KEY}
  • customerKey: 상점에서 만든 고객의 고유 ID입니다.
  • authKey: 빌링키를 발급할 때 사용하는 일회성 인증 키입니다. 최대 길이는 300자입니다.

받은 쿼리 파라미터를 이용해 빌링키 발급 API를 호출할 수 있습니다.

requestBillingAuth()의 파라미터로 설정했던 customerKey 값과 리다이렉트 URL에 있는 customerKey 값이 같은지 확인해보세요. 값이 같다면 빌링키를 발급할 준비가 되었습니다.

카드 등록 요청이 실패했을 때

카드 등록 요청이 실패하면 다음과 같이 failUrl로 이동합니다. 에러 목록을 확인하세요.

https://my-store.com/fail?code={ERROR_CODE}&message={ERROR_MESSAGE}&orderId={ORDER_ID}

3. 빌링키 발급하기

이제 빌링키를 발급할 차례예요. 고객이 등록한 카드 정보는 저장할 수 없기 때문에 암호화해서 결제를 실행할 때 대신 사용합니다.

먼저 API 인증을 위해 아래와 같이 인증 헤더 값을 만듭니다.

시크릿 키 뒤에 :을 추가하고 base64로 인코딩합니다. :을 빠트리지 않도록 주의하세요.

base64('test_sk_zXLkKEypNArWmo50nX3lmeaxYG5R:')
─────────────────┬───────────────── ┬
secretKey :
발급받은 시크릿 키 콜론

아래 명령어를 터미널에서 실행하면 인코딩된 값을 얻을 수 있습니다.

echo -n 'test_sk_zXLkKEypNArWmo50nX3lmeaxYG5R:' | base64

인코딩된 값을 Basic 인증 헤더에 넣고 요청 본문도 추가하세요. 앞 단계에서 리다이렉트 URL로 받은 authKey, customerKey 값을 카드 자동결제 빌링키 발급 요청 API의 요청 본문으로 보냅니다.

요청
curl --request POST \
--url https://api.tosspayments.com/v1/billing/authorizations/issue \
--header 'Authorization: Basic dGVzdF9za196WExrS0V5cE5BcldtbzUwblgzbG1lYXhZRzVSOg==' \
--header 'Content-Type: application/json' \
--data '{"authKey":"q15xjm5HCxBkKG0CQAoIZ","customerKey":"liIqNdwQQqMNIFA2zchQu"}'

API 호출 결과로 HTTP 200 OK를 받으면 빌링키 발급 성공입니다. 응답 본문에 포함된 billingKey를 이용해 자동결제가 이루어집니다. 이 값은 가맹점에서 저장해두고 원하는 시점에 이 값을 가지고 결제 승인을 요청하면 자동결제가 이루어집니다.

응답
JSON
{
"mId": "tosspayments",
"customerKey": "",
"authenticatedAt": "2021-01-01T10:00:00+09:00",
"method": "카드",
"billingKey": "Z_t5vOvQxrj4499PeiJcjen28-V2RyqgYTwN44Rdzk0=",
"card": {
"issuerCode": "61",
"acquirerCode": "31",
"number": "43301234****123*",
"cardType": "신용",
"ownerType": "개인"
}
}

자동결제 계약이 안 되어 있는 클라이언트 키로 연동하면 발생합니다. 자동결제 계약이 되어있는 클라이언트 키를 사용하거나 토스페이먼츠 고객센터(1544-7772, support@tosspayments.com)로 문의해주세요.

빌링키 관리하기

빌링키를 고객을 특정하는 customerKey와 매핑해서 서버에 저장하세요. 한 번 발급된 빌링키는 다시 조회할 수 없습니다. 저장한 키 값으로 자동결제를 요청해주세요.

빌링키의 유효기간은 빌링키와 연결된 카드 유효기간과 같습니다. 발급된 빌링키를 삭제하는 기능은 제공하지 않습니다. 발급된 빌링키가 더 이상 필요하지 않으면 데이터베이스에서 삭제하고 더 이상 사용하지 않으면 됩니다. 혹시 누군가가 빌링키 정보를 알고 있더라도 빌링키와 매핑된 customerKey를 모른다면 결제가 불가능합니다. 빌링키를 사용한 결제는 빌링키를 발급할 때 같이 전달된 customerKey와 매핑이 되어있기 때문에, 결제 요청을 할 때 빌링키와 customerKey가 같이 전달되어야 결제가 진행됩니다.

별도로 제공하지 않습니다. 자동결제에 등록할 카드의 유효성 여부는 빌링키 발급을 요청할 때 카드사를 통해 확인합니다. 만약 유효하지 않다면 에러를 응답합니다. 카드 잔고 부족이나 한도 초과는 결제 승인을 요청할 때 카드사를 통해 확인합니다.

새로운 카드 정보로 빌링키를 다시 발급하세요. 별도로 빌링키를 갱신하는 과정은 없습니다.

4. 빌링키로 자동결제 실행하기

발급한 billingKey카드 자동결제 승인 API의 Path 파라미터로 추가합니다. 요청 본문에는 주문 정보와 함께 customerKey를 포함합니다.

요청
curl --request POST \
--url https://api.tosspayments.com/v1/billing/{billingKey} \
--header 'Authorization: Basic dGVzdF9za196WExrS0V5cE5BcldtbzUwblgzbG1lYXhZRzVSOg==' \
--header 'Content-Type: application/json' \
--data '{"customerKey":"liIqNdwQQqMNIFA2zchQu","amount":4900,"orderId":"CzG9Zki6rHs-AJ5274ZBa","orderName":"토스 프라임 구독","customerEmail":"customer@email.com","customerName":"박토스","taxFreeAmount":0}'

customerkey와 매핑되지 않은 billingKey를 사용하면 발생합니다.

구독 스케줄링 예제

토스페이먼츠에서는 자체적으로 스케줄링 기능을 제공하지 않습니다. 따라서 가맹점에서 직접 스케줄링 기능을 구현해서 원하는 주기, 시점에 결제를 실행해야 합니다.

만약 Node.js 애플리케이션에 스케줄링 로직을 추가하려면, node-cron과 같은 패키지를 사용할 수 있습니다. 이 패키지를 사용하면 스케쥴을 정의하고 그에 따라 특정 작업을 자동으로 실행할 수 있습니다. 각 언어나 프레임워크에서 제공하는 스케줄링 기능을 사용하세요.

먼저 node-cron 패키지를 설치해야 합니다. 프로젝트의 루트 디렉토리에서 다음 명령어를 실행하세요.

npm install --save node-cron

이제 node-cron을 사용하여 매월 1일에 자동결제를 진행하는 스케쥴러를 설정할 수 있습니다. 아래 코드는 기존 routes/index.js 파일에 스케쥴러를 추가하는 방법을 보여줍니다:

JavaScript
var express = require("express");
var got = require("got");
var cron = require("node-cron"); // 스케줄링을 위해 cron 잡을 수행할 수 있는 node-cron 패키지 추가
var uuid = require("uuid").v4;
var router = express.Router();
router.get("/", function (req, res) {
res.render("index");
});
router.get("/billing_confirm", function (req, res) {
// ...
}
// 매 달 1일 01:00에 스케줄링을 수행하는 cron 잡 추가
cron.schedule("0 0 1 * *", function() {
console.log("매월 1일 01:00에 결제 실행하기");
got.post("https://api.tosspayments.com/v1/billing/" + billingKey, {
headers: {
Authorization:
"Basic " + Buffer.from(secretKey + ":").toString("base64"),
"Content-Type": "application/json",
},
json: {
customerKey: "test_customer_key",
amount: 50000,
orderId: uuid(),
orderName: ‘토스 프라임 구독’,
customerEmail: "customer@email.com",
customerName: "박토스",
taxFreeAmount: 0
},
responseType: "json",
})
.then(function (response) {
console.log(response.body);
})
.catch(function (error) {
console.log(‘Error:, error);
});
})
// ...

위 코드는 매월 1일에 billingKey`를 사용하여 자동결제를 진행하는 스케쥴러입니다. 이러한 방식으로 스케줄링 로직을 추가하면, 매월 1일마다 자동으로 지정된 결제가 진행됩니다. 실제 서비스에서는 에러 처리, 로깅, 데이터베이스와의 통신 등이 추가로 필요할 수 있습니다.

다음 결제일에 구독을 취소한 고객의 빌링키, 고객키로 카드 자동결제 승인 API를 호출하지 않으면 됩니다.

카드 자동결제 승인 API를 호출할 때 amount 파라미터를 변경된 결제 금액으로 설정하면 됩니다.

카드 자동결제 승인 API를 호출하는 주기를 변경해주세요.

5. 결제 완료 후 응답 확인하기

API 호출 결과로 HTTP 200 OK를 받으면 결제 승인 성공입니다. 상태 코드와 함께 Payment 객체가 응답으로 돌아옵니다. 자동결제는 card 필드가 포함되어 있어야 합니다.

응답
JSON
{
"mId": "tosspayments",
"version": "2022-11-16",
"paymentKey": "",
"status": "DONE",
"lastTransactionKey": "",
"orderId": "",
"orderName": "토스 프라임 구독",
"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": "43301234****123*",
"installmentPlanMonths": 0,
"isInterestFree": false,
"interestPayer": null,
"approveNo": "00000000",
"useCardPoint": false,
"cardType": "신용",
"ownerType": "개인",
"acquireStatus": "READY",
"amount": 4900
},
"virtualAccount": null,
"transfer": null,
"mobilePhone": null,
"giftCertificate": null,
"cashReceipt": null,
"cashReceipts": null,
"discount": null,
"cancels": null,
"secret": null,
"type": "BILLING",
"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": 4900,
"balanceAmount": 4900,
"suppliedAmount": 4455,
"vat": 455,
"taxFreeAmount": 0,
"taxExemptionAmount": 0,
"method": "카드"
}

응답 객체의 필드는 API 버전에 따라 조금씩 달라집니다. 개발자센터에 설정된 API 버전을 확인하고, 원하는 필드가 있는 버전으로 변경해보세요.

API 버전 업데이트 사항은 릴리즈 노트에서 확인할 수 있습니다.

확인할 내용

✔️ 응답 객체에 card 필드가 있는지 확인하세요.

✔️ 응답 객체의 method가 '카드'인지 확인하세요.


👉 구독결제 간단히 구현하기 콘텐츠도 참고해보세요.

  • 더 궁금한 내용이 있나요?
  • 코드 샘플을 참고하세요
  • 기술지원이 필요한가요?
    실시간 문의|이메일 보내기