Skip to content

Payment API

토스 프론트에서 결제 및 환불을 처리하기 위한 API입니다. 카드, 애플페이, 삼성페이, 현금 영수증, 간편결제 등 다양한 결제 수단을 지원합니다.

주의 사항

프론트에서 카드 결제 테스트 시 실제 승인이 발생하여 주의가 필요합니다.

주의 사항

[카드 결제 테스트 시]

  • 테스트 후 반드시 즉시 취소 처리 필요
  • 결제 응답의 paymentKey, approvalNumber, timestamp 등 승인 취소를 위한 값을 저장하여 취소에 활용

[권장 테스트 방법]

  • 동작 확인 목적이라면 현금 결제 > 현금영수증 미발급으로 테스트 권장
  • 실제 금전적 부담 없이 결제 플로우 확인 가능

Methods

requestPayment

통합 결제를 요청합니다.

Parameters

파라미터타입필수기본값설명
paymentKeystring-중복되지 않는 고유한 결제 식별자
taxnumber-세금 (일반적으로 Math.floor(price / 11), 면세인 경우 0)
supplyValuenumber-공급가액 (결제 금액 - 세금)
tipnumber-봉사료
timeoutMsnumber60000타임아웃 (ms 단위)
localeCode'ko' | 'en''ko'언어 설정
excludePaymentTypes['CASH']-제외할 결제 수단 (현재 현금만 지원)

Example

js
/**
 * 통합 결제 요청
 * @param {Object} params 통합 결제 요청 파라미터
 * @returns {Object} 결제 결과
 */
const price = 10000;
const tax = Math.floor(price / 11);
const supplyValue = price - tax;

const result = await sdk.payment.requestPayment({
  paymentKey: "paymentKey",
  tax,
  supplyValue,
  tip: 0,
  timeoutMs: 60000,
  localeCode: "ko", // "ko" or "en" default "ko"
  excludePaymentTypes: ["CASH"], // 현금 결제 제외
});

if (result.type === "CANCELED" || result.type === "TIMEOUT") {
  return;
}

switch (result.response.paymentMethod) {
  case "CARD":
    console.log(result.response.card);
    break;
  case "CASH":
    console.log(result.response.cash);
    break;
  case "BARCODE":
    console.log(result.response.barcode);
    break;
}

Response

카드/삼성페이/애플페이 결제
js
{
    type: 'SUCCESS',
    response: {
        paymentMethod: 'CARD',
        card: {
            van: string,                // VAN사 코드
            timestamp: number,          // 승인 시간
            approvalNumber: string,     // 승인번호
            acquirerName: string,       // 매입사 명
            acquirerCode: string,       // 매입사 코드
            issuerName: string,         // 발급사 명
            issuerCode: string,         // 발급사 코드
            cardType: string,           // 카드 종류
            balance: number,            // 선불카드 잔액
            installment: number,        // 할부 개월
            maskedCardNumber: string,   // 마스킹된 카드 번호 (bin 8자리만 표시)
        },
    },
}
현금 영수증
js
// 현금영수증 발급 시
{
    type: 'SUCCESS',
    response: {
        paymentMethod: 'CASH',
        cash: {
            isCashReceipt: true,
            cashReceipt: {
                van: string,                                            // VAN사 코드
                timestamp: number,                                      // 승인 시간
                issuerType: 'CONSUMER' | 'BUSINESS',                    // 발급 대상 유형
                issuanceType: 'PHONE' | 'BUSINESS_NUMBER' | 'CARD',     // 발급 방식
                identityNumber: string,                                 // 현금영수증 번호 값
                maskedIdentityNumber: string,                           // 현금영수증 번호 값 (일부 별표 처리)
                approvalNumber: string,                                 // 승인번호
                isSelfIssuance: boolean,                                // 자진 발급 여부
            },
        },
    },
}

// 현금영수증 미발급 시
{
    type: 'SUCCESS',
    response: {
        paymentMethod: 'CASH',
        cash: {
            isCashReceipt: false,
        },
    },
}
간편결제
js
{
    type: 'SUCCESS',
    response: {
        paymentMethod: 'BARCODE',
        barcode: {
            van: string,              // VAN사 코드
            timestamp: number,        // 승인 시간
            approvalNumber: string,   // 승인번호
            acquirerName: string,     // 매입사 명
            acquirerCode: string,     // 매입사 코드
            issuerName: string,       // 발급사 명
            issuerCode: string,       // 발급사 코드
            cardType: string,         // 카드 종류
            balance: number,          // 선불카드 잔액
            installment: number,      // 할부 개월
            shopCode: string,         // 가맹점 번호 (숫자 9자리)
        },
        extraData: {
            vanTransactionManagementId: string, // 알리페이/위챗페이 취소 시 필요
        },
    },
}

requestBarcodePayment

QR, 바코드를 인식하는 간편결제를 요청합니다.

Parameters

파라미터타입필수기본값설명
paymentKeystring-중복되지 않는 고유한 결제 식별자
taxnumber-세금
supplyValuenumber-공급가액
tipnumber-봉사료
timeoutMsnumber60000타임아웃 (ms 단위)
localeCode'ko' | 'en''ko'언어 설정

Example

js
/**
 * 간편결제 요청
 * @param {Object} params 간편결제 요청 파라미터
 * @returns {Object} 결제 결과
 */
const price = 10000;
const tax = Math.floor(price / 11);
const supplyValue = price - tax;

const result = await sdk.payment.requestBarcodePayment({
  paymentKey: "barcodePaymentKey",
  tax,
  supplyValue,
  tip: 0,
  timeoutMs: 60000,
  localeCode: "ko", // "ko" or "en" default "ko"
});

if (result.type === "CANCELED" || result.type === "TIMEOUT") {
  return;
}

console.log(result.response.barcode);

requestCashPayment

현금 결제 후 현금영수증 발급을 요청합니다.

Parameters

파라미터타입필수기본값설명
paymentKeystring-중복되지 않는 고유한 결제 식별자
taxnumber-세금
supplyValuenumber-공급가액
tipnumber-봉사료
timeoutMsnumber60000타임아웃 (ms 단위)
localeCode'ko' | 'en''ko'언어 설정
identityNumberstring-현금영수증 번호 (휴대폰번호 또는 사업자번호)
issuerType'CONSUMER' | 'BUSINESS'-소득 구분

Example

js
/**
 * 현금 결제 요청
 * @param {Object} params 현금 결제 요청 파라미터
 * @returns {Object} 결제 결과
 */
const price = 10000;
const tax = Math.floor(price / 11);
const supplyValue = price - tax;

const result = await sdk.payment.requestCashPayment({
  paymentKey: "cashPaymentKey",
  tax,
  supplyValue,
  tip: 0,
  timeoutMs: 60000,
  localeCode: "ko", // "ko" or "en" default "ko"
  identityNumber: "01000000000",
});

if (result.type === "CANCELED" || result.type === "TIMEOUT") {
  return;
}

console.log(result.response.cash);

requestPaymentCancel

승인된 결제에 대한 환불을 요청합니다.

Parameters

파라미터타입필수기본값설명
paymentKeystring-원본 결제의 식별자
paymentMethod'CARD' | 'CASH' | 'BARCODE'-원본 결제 수단
taxnumber-취소할 세금
supplyValuenumber-취소할 공급가액
tipnumber-취소할 봉사료
timestampnumber-원본 결제의 승인 시간
approvalNumberstring-원본 결제의 승인번호
installmentnumber-원본 결제의 할부 개월
timeoutMsnumber60000타임아웃 (ms 단위)
localeCode'ko' | 'en''ko'언어 설정
extraData.vanTransactionManagementIdstring-알리페이/위챗페이 취소 시 필요한 값
isSelfIssuanceboolean-현금영수증 자진발급 여부
excludePaymentTypes['CASH']-제외할 결제 수단

Example

js
/**
 * 결제 취소 요청
 * @param {Object} params 결제 취소 요청 파라미터
 * @returns {Object} 취소 결과
 */
const price = 10000;
const tax = Math.floor(price / 11);
const supplyValue = price - tax;

const result = await sdk.payment.requestPaymentCancel({
  paymentKey: "결제했던 paymentKey",
  paymentMethod: "CARD", // "CASH" 또는 "BARCODE"
  tax,
  supplyValue,
  tip: 0,
  timestamp: 1723628943812, // 승인 시 timestamp
  approvalNumber: "000000000", // 승인 시 approvalNumber
  installment: 0, // 승인 시 installment
  timeoutMs: 60000,
  extraData: {
    vanTransactionManagementId: string, // 알리/위챗 승인 시 값
  },
  isSelfIssuance: false, // 현금영수증 자진발급여부
  localeCode: "ko",
});

if (result.type === "CANCELED" || result.type === "TIMEOUT") {
  return;
}

switch (result.response.paymentMethod) {
  case "CARD":
    console.log(result.response.card);
    break;
  case "CASH":
    console.log(result.response.cash);
    break;
  case "BARCODE":
    console.log(result.response.barcode);
    break;
}

사용 예시

결제 관리 클래스

js
class PaymentManager {
  /**
   * 통합 결제 요청
   * @param {number} amount 통합 결제 금액
   * @param {string} paymentKey 통합 결제 식별자
   */
  async requestPayment(amount, paymentKey) {
    const tax = Math.floor(amount / 11);
    const supplyValue = amount - tax;

    try {
      const result = await sdk.payment.requestPayment({
        paymentKey,
        tax,
        supplyValue,
        tip: 0,
        timeoutMs: 60000,
        localeCode: "ko",
      });

      if (result.type === "SUCCESS") {
        return this.handlePaymentSuccess(result.response);
      } else {
        return this.handlePaymentFailure(result.type);
      }
    } catch (error) {
      console.error("결제 요청 실패:", error);
      throw error;
    }
  }

  /**
   * 결제 취소 요청
   * @param {string} paymentKey 결제 식별자
   * @param {string} paymentMethod 결제 수단
   * @param {number} amount 취소 금액
   * @param {Object} originalPayment 원본 결제 정보
   */
  async requestPaymentCancel(
    paymentKey,
    paymentMethod,
    amount,
    originalPayment
  ) {
    const tax = Math.floor(amount / 11);
    const supplyValue = amount - tax;

    try {
      const result = await sdk.payment.requestPaymentCancel({
        paymentKey,
        paymentMethod,
        tax,
        supplyValue,
        tip: 0,
        timestamp: originalPayment.timestamp,
        approvalNumber: originalPayment.approvalNumber,
        installment: originalPayment.installment,
        timeoutMs: 60000,
      });

      if (result.type === "SUCCESS") {
        return this.handleCancelSuccess(result.response);
      } else {
        return this.handleCancelFailure(result.type);
      }
    } catch (error) {
      console.error("결제 취소 실패:", error);
      throw error;
    }
  }

  /**
   * 간편결제 요청
   * @param {number} amount 결제 금액
   * @param {string} paymentKey 결제 식별자
   */
  async requestBarcodePayment(amount, paymentKey) {
    const tax = Math.floor(amount / 11);
    const supplyValue = amount - tax;

    try {
      const result = await sdk.payment.requestBarcodePayment({
        paymentKey,
        tax,
        supplyValue,
        tip: 0,
        timeoutMs: 60000,
        localeCode: "ko",
      });

      if (result.type === "SUCCESS") {
        return this.handleBarcodePaymentSuccess(result.response);
      } else {
        return this.handlePaymentFailure(result.type);
      }
    } catch (error) {
      console.error("간편결제 요청 실패:", error);
      throw error;
    }
  }

  /**
   * 현금 결제 요청
   * @param {number} amount 결제 금액
   * @param {string} paymentKey 결제 식별자
   */
  async requestCashPayment(amount, paymentKey) {
    const tax = Math.floor(amount / 11);
    const supplyValue = amount - tax;

    try {
      const result = await sdk.payment.requestCashPayment({
        paymentKey,
        tax,
        supplyValue,
        tip: 0,
        timeoutMs: 60000,
        localeCode: "ko",
        identityNumber: "01000000000",
      });

      if (result.type === "SUCCESS") {
        return this.handleCashPaymentSuccess(result.response);
      } else {
        return this.handlePaymentFailure(result.type);
      }
    } catch (error) {
      console.error("현금 결제 요청 실패:", error);
      throw error;
    }
  }

  handlePaymentSuccess(response) {
    // 결제 성공 처리
    console.log("결제 성공:", response);
  }

  handleBarcodePaymentSuccess(response) {
    // 간편결제 성공 처리
    console.log("간편결제 성공:", response);
  }

  handleCashPaymentSuccess(response) {
    // 현금 결제 성공 처리
    console.log("현금 결제 성공:", response);
  }

  handlePaymentFailure(type) {
    // 결제 실패 처리
    console.log("결제 실패:", type);
  }

  handleCancelSuccess(response) {
    // 취소 성공 처리
    console.log("취소 성공:", response);
  }

  handleCancelFailure(type) {
    // 취소 실패 처리
    console.log("취소 실패:", type);
  }
}

// 사용 예시
async function processPayment() {
  const paymentManager = new PaymentManager();

  // 통합 결제 요청
  await paymentManager.requestPayment(10000, "payment-123");

  // 바코드 간편결제 요청
  await paymentManager.requestBarcodePayment(10000, "barcode-payment-456");

  // 현금 결제 요청
  await paymentManager.requestCashPayment(10000, "cash-payment-789");

  // 결제 취소
  await paymentManager.requestPaymentCancel("payment-123", "CARD", 10000, {
    timestamp: 1723628943812,
    approvalNumber: "000000000",
    installment: 0,
  });
}