스냅툴 구독킷
연동 가이드

API 연동

구독킷 RESTful API 연동 가이드

개요

구독킷 API는 구독 결제 시스템을 쉽게 연동할 수 있도록 설계된 RESTful API입니다.

인증

모든 API 요청에는 X-Subscription-Key 헤더가 필요합니다.

X-Subscription-Key: your-subscription-key

기본 URL

https://your-domain.com

API 엔드포인트

1. 사전 주문 계산

구독 상품의 최종 결제 금액을 계산합니다.

POST /api/pre-order

요청 본문

필드타입필수설명
productIdstring (UUID)O구독 상품 ID
discountCodesarray of stringX적용할 할인 코드 목록
quantitynumberO구매 수량 (기본값: 1)

응답

필드타입설명
successboolean요청 성공 여부
data.product.idstring상품 ID
data.product.namestring상품명
data.product.descriptionstring상품 설명
data.product.unitAmountnumber단위 가격
data.product.currencystring통화 (KRW, USD)
data.pricing.originalPricenumber할인 전 원래 가격
data.pricing.finalPricenumber최종 결제 금액
data.pricing.quantitynumber구매 수량
data.pricing.discounts[].codestring할인 코드
data.pricing.discounts[].typestring할인 유형 (PERCENTAGE: 비율, FIXED_AMOUNT: 정액)
data.pricing.discounts[].valuenumber할인값 (비율 또는 금액)
data.pricing.discounts[].descriptionstring할인 설명
data.pricing.discounts[].appliedAmountnumber실제 적용된 할인 금액
data.pricing.discounts[].originalAmountnumber할인 적용 전 금액
data.pricing.invalidDiscounts[].codestring유효하지 않은 할인 코드
data.pricing.invalidDiscounts[].reasonstring유효하지 않은 이유
data.pricing.breakdown.subtotalnumber소계
data.pricing.breakdown.discountAmountnumber총 할인 금액
data.pricing.breakdown.totalnumber최종 결제 금액

요청 예시

POST /api/pre-order
Content-Type: application/json
X-Subscription-Key: your-subscription-key
 
{
  "productId": "123e4567-e89b-12d3-a456-426614174000",
  "discountCodes": ["WELCOME2024", "SPRING10"],
  "quantity": 2
}

응답 예시

{
  "success": true,
  "data": {
    "product": {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "name": "프리미엄 플랜",
      "description": "모든 기능 사용 가능, 무제한 사용자",
      "unitAmount": 99000,
      "currency": "KRW"
    },
    "pricing": {
      "originalPrice": 198000,
      "finalPrice": 158400,
      "quantity": 2,
      "discounts": [
        {
          "code": "WELCOME2024",
          "type": "PERCENTAGE",
          "value": 15,
          "description": "신규 가입 할인",
          "appliedAmount": 29700,
          "originalAmount": 198000
        },
        {
          "code": "SPRING10",
          "type": "FIXED_AMOUNT",
          "value": 5000,
          "description": "봄맞이 프로모션",
          "appliedAmount": 9900,
          "originalAmount": 168300
        }
      ],
      "invalidDiscounts": [
        {
          "code": "EXPIRED2023",
          "reason": "만료된 할인 코드입니다."
        }
      ],
      "breakdown": {
        "subtotal": 198000,
        "discountAmount": 39600,
        "total": 158400
      }
    }
  }
}

2. 카드 등록

신규 구독을 위한 카드 등록을 처리합니다.

POST /api/card-registration

요청 본문

필드타입필수설명
customerKeystringO고객 식별자
productIdstring (UUID)O구독 상품 ID
cardNumberstringO카드번호 (XXXX XXXX XXXX XXXX 형식)
expirationYearstringO유효기간 연도 (YY 형식)
expirationMonthstringO유효기간 월 (MM 형식)
cardPasswordstringO카드 비밀번호 앞 2자리
isCorporatebooleanO법인카드 여부
personalIdstring생년월일 6자리 (개인카드 시 필수)
corporateIdstring사업자등록번호 10자리 (법인카드 시 필수)
quantitynumberX구매 수량 (기본값: 1)
withTrialbooleanX무료체험 시작 여부 (기본값: false)
withPaymentbooleanX즉시 결제 여부 (기본값: false)
discountCodesarray of stringX적용할 할인 코드 목록

응답

필드타입설명
successboolean요청 성공 여부
data.cardEndNumberstring카드 끝 4자리

요청 예시

POST /api/card-registration
Content-Type: application/json
X-Subscription-Key: your-subscription-key
 
{
  "customerKey": "USER_123",
  "productId": "123e4567-e89b-12d3-a456-426614174000",
  "cardNumber": "1234 5678 9012 3456",
  "expirationYear": "28",
  "expirationMonth": "12",
  "cardPassword": "12",
  "isCorporate": false,
  "personalId": "901231",
  "quantity": 1,
  "withTrial": true,
  "withPayment": false
}

응답 예시

{
  "success": true,
  "data": {
    "cardEndNumber": "3456"
  }
}

3. 카드 정보 업데이트

기존 구독의 카드 정보를 업데이트합니다.

POST /api/card-update/{subscriptionId}

Path 파라미터

파라미터타입설명
subscriptionIdstring (UUID)구독 ID

요청 본문

필드타입필수설명
cardNumberstringO카드번호 (XXXX XXXX XXXX XXXX 형식)
expirationYearstringO유효기간 연도 (YY 형식)
expirationMonthstringO유효기간 월 (MM 형식)
cardPasswordstringO카드 비밀번호 앞 2자리
isCorporatebooleanO법인카드 여부
personalIdstring생년월일 6자리 (개인카드 시 필수)
corporateIdstring사업자등록번호 10자리 (법인카드 시 필수)

응답

필드타입설명
successboolean요청 성공 여부
data.cardEndNumberstring카드 끝 4자리

요청 예시

POST /api/card-update/123e4567-e89b-12d3-a456-426614174000
Content-Type: application/json
X-Subscription-Key: your-subscription-key
 
{
  "cardNumber": "9876 5432 1098 7654",
  "expirationYear": "29",
  "expirationMonth": "06",
  "cardPassword": "12",
  "isCorporate": true,
  "corporateId": "1234567890"
}

응답 예시

{
  "success": true,
  "data": {
    "cardEndNumber": "7654"
  }
}

4. 구독 정보 조회

구독 상세 정보를 조회합니다.

GET /api/subscriptions/{customerKey}?productId={productId}

Path 파라미터

파라미터타입설명
customerKeystring고객 식별자

Query 파라미터

파라미터타입필수설명
productIdstring (UUID)O구독 상품 ID

응답

필드타입설명
successboolean요청 성공 여부
data.subscription.idstring구독 ID
data.subscription.statusstring구독 상태
data.subscription.currentPeriodStartstring현재 구독 기간 시작일
data.subscription.currentPeriodEndstring현재 구독 기간 종료일
data.subscription.cardEndNumberstring카드 끝 4자리
data.paymentTransactions[].idstring결제 트랜잭션 ID
data.paymentTransactions[].amountnumber결제 금액
data.paymentTransactions[].currencystring통화
data.paymentTransactions[].statusstring결제 상태
data.paymentTransactions[].createdAtstring결제 일시
data.product.idstring상품 ID
data.product.namestring상품명
data.product.descriptionstring상품 설명
data.product.unitAmountnumber단위 가격
data.product.currencystring통화

요청 예시

GET /api/subscriptions/USER_123?productId=123e4567-e89b-12d3-a456-426614174000
X-Subscription-Key: your-subscription-key

응답 예시

{
  "success": true,
  "data": {
    "subscription": {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "status": "ACTIVE",
      "currentPeriodStart": "2024-03-01T00:00:00Z",
      "currentPeriodEnd": "2024-04-01T00:00:00Z",
      "cardEndNumber": "3456"
    },
    "paymentTransactions": [
      {
        "id": "tr_123456789",
        "amount": 99000,
        "currency": "KRW",
        "status": "SUCCESS",
        "createdAt": "2024-03-01T00:00:00Z"
      }
    ],
    "product": {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "name": "프리미엄 플랜",
      "description": "모든 기능 사용 가능, 무제한 사용자",
      "unitAmount": 99000,
      "currency": "KRW"
    }
  }
}

5. 구독 취소

구독을 취소합니다.

POST /api/subscriptions/{subscriptionId}/cancel

Path 파라미터

파라미터타입설명
subscriptionIdstring (UUID)구독 ID

응답

필드타입설명
successboolean요청 성공 여부
data.subscription.idstring구독 ID
data.subscription.statusstring구독 상태 (CANCELED)
data.subscription.canceledAtstring취소 일시

요청 예시

POST /api/subscriptions/123e4567-e89b-12d3-a456-426614174000/cancel
X-Subscription-Key: your-subscription-key

응답 예시

{
  "success": true,
  "data": {
    "subscription": {
      "id": "123e4567-e89b-12d3-a456-426614174000",
      "status": "CANCELED",
      "canceledAt": "2024-03-15T09:30:00Z"
    }
  }
}

6. 구독 수량 업데이트

구독의 수량을 변경합니다.

PATCH /api/subscription/{subscriptionId}/quantity

Path 파라미터

파라미터타입설명
subscriptionIdstring (UUID)구독 ID

요청 본문

필드타입필수설명
quantitynumberO변경할 수량 (1 이상)
effectiveDatestringO적용 시점 ('immediate': 즉시, 'next_billing': 다음 결제일)

응답

필드타입설명
successboolean요청 성공 여부
data.quantitynumber변경된 수량
data.effectiveDatestring적용 시점

요청 예시

PATCH /api/subscription/123e4567-e89b-12d3-a456-426614174000/quantity
Content-Type: application/json
X-Subscription-Key: your-subscription-key
 
{
  "quantity": 5,
  "effectiveDate": "immediate"
}

응답 예시

{
  "success": true,
  "data": {
    "quantity": 5,
    "effectiveDate": "immediate"
  }
}

비즈니스 로직

  • 즉시 적용('immediate')을 선택한 경우:
    • 수량이 증가하면 남은 기간에 대한 추가 금액이 즉시 청구됨
    • 수량이 감소하면 다음 결제부터 새로운 금액이 적용됨
  • 다음 결제일 적용('next_billing')을 선택한 경우:
    • 현재 구독 기간은 기존 수량 유지
    • 다음 결제일부터 새로운 수량과 금액이 적용됨

7. 카드 정보 업데이트

기존 구독의 카드 정보를 포함한 모든 결제 정보를 업데이트합니다.

PUT /api/subscription/{subscriptionId}/payment-method

Path 파라미터

파라미터타입설명
subscriptionIdstring (UUID)구독 ID

요청 본문

필드타입필수설명
cardNumberstringO카드번호 (XXXX XXXX XXXX XXXX 형식)
expirationYearstringO유효기간 연도 (YY 형식)
expirationMonthstringO유효기간 월 (MM 형식)
cardPasswordstringO카드 비밀번호 앞 2자리
isCorporatebooleanO법인카드 여부
personalIdstring생년월일 6자리 (개인카드 시 필수)
corporateIdstring사업자등록번호 10자리 (법인카드 시 필수)
updateBillingbooleanX청구 정보 업데이트 여부 (기본값: false)

응답

필드타입설명
successboolean요청 성공 여부
dataobject업데이트된 결제 수단 정보
data.cardEndNumberstring카드 끝 4자리
data.cardIssuerstring카드 발급사
data.updatedAtstring업데이트 일시

요청 예시

PUT /api/subscription/123e4567-e89b-12d3-a456-426614174000/payment-method
Content-Type: application/json
X-Subscription-Key: your-subscription-key
 
{
  "cardNumber": "9876 5432 1098 7654",
  "expirationYear": "29",
  "expirationMonth": "06",
  "cardPassword": "12",
  "isCorporate": true,
  "corporateId": "1234567890",
  "updateBilling": true
}

응답 예시

{
  "success": true,
  "data": {
    "cardEndNumber": "7654",
    "cardIssuer": "신한카드",
    "updatedAt": "2024-03-15T09:30:00Z"
  }
}

비즈니스 로직

  • 기존 카드는 자동으로 만료 처리됨
  • updateBilling이 true인 경우:
    • 다음 결제부터 새로운 카드로 청구됨
    • 현재 미납된 청구서가 있다면 즉시 새로운 카드로 재시도
  • 카드 정보 변경 시 고객에게 이메일 알림 발송

오류 처리

성공 응답

{
  "success": true,
  "data": { ... }
}

실패 응답

{
  "success": false,
  "error": "오류 메시지",
  "redirect": "오류 페이지 URL (옵션)"
}

HTTP 상태 코드

코드설명
200성공
400잘못된 요청 (요청 본문 검증 실패)
401인증 실패 (API 키 오류)
403권한 없음
404리소스를 찾을 수 없음
500서버 오류

구독 상태 (RecurringStatus)

상태설명
TRIALING체험 중 (무료 체험 기간)
ACTIVE활성 (정상 이용 중)
PAST_DUE연체 (결제 실패 후 재시도 중)
UNPAID미납 (결제 재시도 모두 실패)
CANCELED취소됨 (해지)
INCOMPLETE진행중 (결제 정보 등록 중)
INCOMPLETE_EXPIRED진행중 만료 (결제 정보 등록 시간 초과)