Skip to content
수익화>토스페이

정기결제 개발하기

미니앱에서 토스페이 정기결제를 연동하는 방법을 안내해요.
빌링키 생성 → 사용자 인증 → 결제 승인 → 해지 순서로 전체 플로우를 설명해요.


사전 준비 사항

콘솔 설정이 필요해요

API를 호출하기 전에 아래 절차를 먼저 완료해야 해요.

  1. 청약을 진행해 주세요.
  2. 콘솔에서 토스페이 키 값을 등록해 주세요.

꼭 확인해 주세요

  • 기존에 토스페이를 사용하고 있더라도, 앱인토스에서는 별도의 토스페이 가맹점 키 발급이 필요해요.
  • 앱인토스에서 토스페이를 사용 중이더라도, 정기결제(자동결제)는 추가 청약이 필요해요.

청약/수수료/설정 방법은 토스페이 소개 문서를 참고해 주세요.

결제 대상 사용자 식별하기

토스페이는 아래 2가지 방법 중 하나로 결제 대상을 식별해요. 두 값을 동시에 전달하지 말고 하나만 선택해 주세요.

구분발급 방법
x-toss-user-key토스 로그인으로 받은 userKey 값이에요.
x-anon-key사용자 식별키 발급으로 받은 hash 값이에요.

목적에 따라 선택해 주세요.

  • 이미 토스 로그인을 연동했거나, 이름·이메일 같은 회원 정보와 묶어 통합 관리하려면 토스 로그인을 사용해요.
  • 로그인 연동 없이 가볍게 사용자만 식별하려면 사용자 식별키 발급 기능을 사용해요.

x-anon-key(hash)가 유효한 값인지 미리 확인하고 싶다면 식별키 검증하기 API를 사용해 주세요.


기본 정보

항목
Base URLhttps://pay-apps-in-toss-api.toss.im
서버 인증mTLS (클라이언트 인증서)
Content-Typeapplication/json

서버 간 통신에는 mTLS 인증서가 필요해요

정기결제 API는 파트너 서버에서 앱인토스 서버로 호출하는 서버 간 통신이에요.
보안을 위해 서버에 mTLS 인증서를 설정한 뒤 호출해 주세요.
인증서 발급 방법은 mTLS 인증서 발급 방법을 참고해 주세요.


테스트하기

결제 생성 요청 시 isTestPayment: true로 설정하면 샌드박스 환경에서 결제를 테스트할 수 있어요.
콘솔에 별도로 설정하지 않아도 되고, 청약 전에도 테스트할 수 있어요.

단, 샌드박스 환경에는 아래 제한이 있어요.

  • 빌링키 생성(1단계)까지만 가능하고, 결제 승인(3단계)은 지원하지 않아요.
  • 샌드박스에서 생성된 wrappedToken은 운영 환경에서 사용할 수 없어요.
  • 실제 결제 흐름 검증은 운영 키로 전환한 뒤 진행해야 해요.

1. 빌링키 생성하기

사용자의 정기결제 수단을 등록해요. 응답으로 받은 wrappedToken을 클라이언트에 전달해서 사용자 인증을 진행해요.

  • Content-Type: application/json
  • Method: POST
  • URL: /api-partner/v1/apps-in-toss/pay/create-billing-key

요청 헤더

결제 대상을 식별하는 헤더는 아래 2가지 중 하나를 사용해요. 두 헤더를 동시에 전달하지 마세요.

이름타입필수설명
x-toss-user-keystring택 1토스 로그인으로 받은 userKey예요. 사용자 정보 받기를 통해 획득할 수 있어요.
x-anon-keystring택 1사용자 식별키 발급으로 받은 hash 값이에요.

요청 파라미터

필드타입필수설명
productDescStringY정기결제 상품명 (예: "월간 구독")
isTestPaymentBooleanY테스트 결제 여부
json
{
  "productDesc": "월간 구독",
  "isTestPayment": false
}

응답 파라미터

필드타입설명
wrappedTokenString정기결제 토큰이에요. 이후 모든 API 호출 시 사용해요.
json
{
  "resultType": "SUCCESS",
  "success": {
    "wrappedToken": "550e8400-e29b-41d4-a716-446655440000"
  }
}

꼭 확인해 주세요

wrappedToken은 결제 승인, 상태 조회, 해지 시 모두 사용되므로 반드시 저장해야 해요.


2. 사용자 인증하기

SDK를 통해 연동해 주세요.

빌링키 생성 응답으로 받은 wrappedToken을 클라이언트에 전달해요.
클라이언트는 앱인토스 SDK를 사용해서 토스페이 인증을 수행해요.

typescript
import { TossPay } from '@apps-in-toss/web-framework';

const { success, reason } = await TossPay.requestTossPayPaysBilling({ wrappedToken });

if (success) {
  // 인증 성공 → 서버에 결제 승인 요청
} else {
  // 인증 실패 (reason에 실패 사유)
}

반환 값

필드타입설명
successboolean인증 성공 여부
reasonstring?실패 시 사유

SDK 최소 지원 버전

  • Android: 5.256.0
  • iOS: 5.256.0

3. 정기결제 실행하기

등록된 결제수단으로 결제를 승인해요.

  • Content-Type: application/json
  • Method: POST
  • URL: /api-partner/v1/apps-in-toss/pay/execute-billing

요청 헤더

결제 대상을 식별하는 헤더는 아래 2가지 중 하나를 사용해요. 두 헤더를 동시에 전달하지 마세요.

이름타입필수설명
x-toss-user-keystring택 1토스 로그인으로 받은 userKey예요. 사용자 정보 받기를 통해 획득할 수 있어요.
x-anon-keystring택 1사용자 식별키 발급으로 받은 hash 값이에요.

요청 파라미터

필드타입필수설명
wrappedTokenStringY빌링키 생성 시 받은 토큰
orderNoStringY주문번호
productDescStringY상품 설명
spreadOutIntY할부 개월 수 (0=일시불)
amountLongY결제 금액
amountTaxFreeLongY비과세 금액
amountTaxableLongN과세 금액
amountVatLongN부가세
amountServiceFeeLongN봉사료
cashReceiptBooleanN현금영수증 발급 여부 (기본: true)
sendFailPushBooleanN실패 시 푸시 발송 여부 (기본: true)
cashReceiptTradeOptionStringN현금영수증 타입 (기본: GENERAL)
isTestPaymentBooleanY테스트 결제 여부
json
{
  "wrappedToken": "550e8400-e29b-41d4-a716-446655440000",
  "orderNo": "ORDER-20260416-001",
  "productDesc": "월간 구독 결제",
  "spreadOut": 0,
  "amount": 9900,
  "amountTaxFree": 0,
  "isTestPayment": false
}

응답 파라미터

필드타입설명
codeInt응답 코드예요. 0이면 성공이에요.
modeString결제 모드예요.
payTokenString결제 토큰이에요.
orderNoString주문번호예요.
payMethodString결제 수단이에요. (CARD, TOSS_MONEY 등)
amountInt승인 금액이에요.
transactionIdString거래 ID예요.
approvalTimeString승인 시각이에요.
discountedAmountInt할인 금액이에요.
paidAmountInt실결제 금액이에요.
cardCompanyNameString승인 카드사명이에요.
cardCompanyCodeString승인 카드사 코드예요.
cardAuthorizationNoString구매자가 확인할 수 있는 카드사 승인번호예요. 라이브 키 결제에서 확인할 수 있어요.
salesCheckLinkUrlString신용카드 매출전표 호출 URL이에요.
noInterestString카드 무이자 적용 여부예요. true: 무이자, false: 일반
cardNumberString마스킹된 카드번호예요. 카드번호 16자리 중 중간 자리는 마스킹돼요.
cardUserTypeString카드 사용자 구분이에요. PERSONAL: 본인카드, PERSONAL_FAMILY: 가족카드, CORP_PERSONAL: 법인지정 결제계좌 임직원, CORP_PRIVATE: 법인 공용, CORP_COMPANY: 법인지정 결제계좌 회사(하나카드만)
cardBinNumberString카드 BIN 번호예요.
cardNum4PrintString사용자가 선택한 카드의 끝 4자리예요.
json
{
  "resultType": "SUCCESS",
  "success": {
    "code": 0,
    "mode": "LIVE",
    "payToken": "7W3000019000001",
    "orderNo": "ORDER-20260416-001",
    "payMethod": "CARD",
    "amount": 9900,
    "transactionId": "20260416000001",
    "approvalTime": "20260416120000",
    "discountedAmount": 0,
    "paidAmount": 9900,
    "cardCompanyName": "삼성",
    "cardCompanyCode": 3,
    "cardAuthorizationNo": "87654321",
    "salesCheckLinkUrl": "https://pay.toss.im/payfront/web/external/sales-check?payToken=example-payToken",
    "noInterest": false,
    "cardNumber": "654321******1234",
    "cardUserType": "NONE",
    "cardBinNumber": "654321",
    "cardNum4Print": "1234"
  }
}

4. 정기결제 환불하기

정기결제 건을 환불해요.

  • Content-Type: application/json
  • Method: POST
  • URL: /api-partner/v1/apps-in-toss/pay/refund-billing

요청 헤더

결제 대상을 식별하는 헤더는 아래 2가지 중 하나를 사용해요. 두 헤더를 동시에 전달하지 마세요.

이름타입필수설명
x-toss-user-keystring택 1토스 로그인으로 받은 userKey예요. 사용자 정보 받기를 통해 획득할 수 있어요.
x-anon-keystring택 1사용자 식별키 발급으로 받은 hash 값이에요.

요청 파라미터

필드타입필수설명
payTokenStringY정기결제 실행(3단계) 응답에서 받은 결제 토큰
reasonStringY환불 사유
isTestPaymentBooleanY테스트 결제 여부
json
{
  "payToken": "string",
  "reason": "string",
  "isTestPayment": true
}

응답 파라미터

이름타입설명
refundNoString환불 번호예요.
approvalTimeString환불 처리 시간이에요. (yyyy-MM-dd HH:mm:ss)
cashReceiptMgtKeyString현금영수증 관리번호 식별값이에요.
refundableAmountInteger환불 가능 금액이에요.
discountedAmountInteger할인된 금액이에요.
paidAmountInteger지불수단 승인금액이에요.
refundedAmountInteger환불 요청 금액이에요.
refundedDiscountAmountInteger환불 요청 금액 중 실 차감된 할인 금액이에요.
refundedPaidAmountInteger환불 요청 금액 중 실 차감된 지불수단 금액이에요.
payTokenString환불된 결제 토큰이에요.
transactionIdString거래 트랜잭션 아이디예요.
cardMethodTypeString카드 타입이에요. CREDIT: 신용카드, CHECK: 체크카드, PREPAYMENT: 선불카드
cardNumberString마스킹된 카드번호예요.
cardUserTypeString카드 사용자 구분이에요. PERSONAL: 본인카드, PERSONAL_FAMILY: 가족카드, CORP_PERSONAL: 법인지정 결제계좌 임직원, CORP_PRIVATE: 법인 공용, CORP_COMPANY: 법인지정 결제계좌 회사(하나카드만)
cardNum4PrintString사용자가 선택한 카드의 끝 4자리예요.
cardBinNumberString카드 BIN 번호예요.
accountBankCodeString은행 코드예요. 토스머니 결제의 경우 토스가 정의한 은행 코드를 전달해요.
accountBankNameString은행명이에요.
accountNumberString마스킹된 계좌번호예요.
json
{
  "resultType": "SUCCESS",
  "success": {
    "refundNo": "string",
    "approvalTime": "string",
    "cashReceiptMgtKey": "string",
    "refundableAmount": 0,
    "discountedAmount": 0,
    "paidAmount": 0,
    "refundedAmount": 0,
    "refundedDiscountAmount": 0,
    "refundedPaidAmount": 0,
    "payToken": "string",
    "transactionId": "string",
    "cardMethodType": "string",
    "cardNumber": "string",
    "cardUserType": "string",
    "cardNum4Print": "string",
    "cardBinNumber": "string",
    "accountBankCode": "string",
    "accountBankName": "string",
    "accountNumber": "string"
  }
}

5. 빌링키 상태 조회하기

등록된 정기결제 수단의 상태를 조회해요.

  • Content-Type: application/json
  • Method: POST
  • URL: /api-partner/v1/apps-in-toss/pay/get-billing-key-status

요청 헤더

결제 대상을 식별하는 헤더는 아래 2가지 중 하나를 사용해요. 두 헤더를 동시에 전달하지 마세요.

이름타입필수설명
x-toss-user-keystring택 1토스 로그인으로 받은 userKey예요. 사용자 정보 받기를 통해 획득할 수 있어요.
x-anon-keystring택 1사용자 식별키 발급으로 받은 hash 값이에요.

요청 파라미터

필드타입필수설명
wrappedTokenStringY정기결제 토큰
isTestPaymentBooleanY테스트 결제 여부
json
{
  "wrappedToken": "550e8400-e29b-41d4-a716-446655440000",
  "isTestPayment": false
}

응답 파라미터

필드타입설명
codeInt응답 코드예요. 0이면 성공이에요.
billingKeyStatusString빌링키 상태예요.
cardCompanyNameString승인 카드사명이에요.
cardCompanyNoString승인 카드사 코드예요.
cardNumberString마스킹된 카드번호예요. 카드번호 16자리 중 중간 자리는 마스킹돼요.
cardImgUrlString카드 이미지예요.
accountBankNameString은행명이에요.
accountBankCodeString은행 코드예요. 토스머니 결제의 경우 토스가 정의한 은행 코드를 전달해요.
accountNumberString계좌번호예요. 일부 마스킹이 포함돼요.
accountNameString은행명이에요.
accountImgUrlString은행 이미지예요.

6. 빌링키 해지하기

등록된 정기결제 수단을 해지해요.
해지 후에는 해당 wrappedToken으로 결제를 승인할 수 없어요.

  • Content-Type: application/json
  • Method: POST
  • URL: /api-partner/v1/apps-in-toss/pay/remove-billing-key

요청 헤더

결제 대상을 식별하는 헤더는 아래 2가지 중 하나를 사용해요. 두 헤더를 동시에 전달하지 마세요.

이름타입필수설명
x-toss-user-keystring택 1토스 로그인으로 받은 userKey예요. 사용자 정보 받기를 통해 획득할 수 있어요.
x-anon-keystring택 1사용자 식별키 발급으로 받은 hash 값이에요.

요청 파라미터

필드타입필수설명
wrappedTokenStringY정기결제 토큰
isTestPaymentBooleanY테스트 결제 여부
json
{
  "wrappedToken": "550e8400-e29b-41d4-a716-446655440000",
  "isTestPayment": false
}

응답 파라미터

필드타입설명
codeInt응답 코드예요. 0이면 성공이에요.
msgString결과 메시지예요.

코드 및 에러 목록

은행코드 리스트

토스머니 결제의 경우 사용자가 선택한 계좌 정보를 함께 전달해요.

은행 코드은행 명
002KDB산업은행
003IBK기업은행
004KB국민은행
005KEB하나은행
007수협은행
011NH농협은행
020우리은행
023SC은행
027씨티은행
031대구은행
032부산은행
034광주은행
035제주은행
037전북은행
039경남은행
045MG새마을금고
048신협
050저축은행
064산림조합
071우체국
081하나은행
088신한은행
089케이뱅크
090카카오뱅크
092토스뱅크
103SBI저축은행
218KB증권
230미래에셋증권
238미래에셋증권
240삼성증권
243한국투자증권
247NH투자증권
261교보증권
262하이투자증권
263현대차투자증권
264키움증권
265이베스트증권
266SK증권
267대신증권
269한화투자증권
270하나증권
271토스증권
278신한투자증권
279DB금융투자
280유진투자
287메리츠증권
888토스머니
889토스포인트

카드사코드 리스트

카드사 이름카드(매입사) 코드
신한1
현대2
삼성3
국민4
롯데5
하나6
우리7
농협8
씨티(미지원)9
비씨(BC)10

빌링키 상태 리스트

상태빌링키 상태 코드
빌링키 생성 완료CREATED
사용자 인증 진행중AUTHENTICATING
사용자 인증 완료ACTIVE
빌링키 삭제REMOVED
유효하지 않은 빌링키FAILED

에러 케이스

code상황에러 메시지
5001토스페이 청약이 되어 있지 않은 상태토스페이 청약이 되어 있지 않습니다.
5005해지된 토큰으로 결제 시도비활성화된 빌링키에요.
5006유효하지 않은 토큰으로 호출빌링키를 찾을 수 없어요.
40000요청 데이터가 유효하지 않은 경우요청 데이터가 유효하지 않아요.
-토스페이 측 오류토스페이 에러코드와 메시지가 전달돼요.