체크아웃

체크아웃 붙이기

상품 등록 → 체크아웃 → 서버 재조회 검증 → 웹훅 보정, 네 단계예요.

이 문서는 커머스 체크아웃을 가장 짧게 붙이는 매뉴얼이에요. 전체 파라미터, 할인, 배송비, 프로모션은 주문서 요청에서 더 자세히 다뤄요.

상품을 등록해 product_id 를 확보하고, 프론트엔드가 그 ID와 수량으로 체크아웃을 열고, 결제가 끝나면 서버가 order_number 로 주문을 다시 조회해 검증하고, 마지막으로 웹훅이 상태를 한 번 더 보정해요. 아래 네 STEP 이 그 순서예요.

내가 하는 것

  • 상품 등록 또는 기존 상품 ID 매핑
  • 장바구니 금액·수량 검증
  • 서버에서 order_number 기준 주문 조회
  • 웹훅 중복 처리와 주문 상태 저장

Bootpay가 알아서 하는 것

  • 주문서 UI와 결제 진입
  • 결제 처리와 주문 객체 생성
  • 주문·취소·구독 이벤트 웹훅 발송

STEP 1. 상품을 준비해요

Bootpay 관리자 → 상품 관리에서 상품을 등록하고 product_id를 받아요.

API로 등록하려면 상품 등록을 사용해요. 기존 상품 DB가 있으면 내부 상품 ID와 Bootpay product_id를 함께 저장해 두면 이후 주문 검증이 쉬워져요.

STEP 2. 체크아웃을 열어요

아래 코드는 최소 흐름만 보여줘요. 실제 서비스에서는 서버에서 장바구니 금액과 재고를 먼저 검증하고, 검증된 상품 ID와 수량만 체크아웃에 넘겨요.

패키지 이름을 확인해요

커머스 클라이언트 SDK는 @bootpay/bp-commerce-sdk 예요. 결제 SDK(@bootpay/client-js)와 다른 패키지고, default export 라 중괄호 없이 가져와요.

// npm install @bootpay/bp-commerce-sdk
import BootpayCommerce from '@bootpay/bp-commerce-sdk'

const CLIENT_KEY = 'your-client-key'

await BootpayCommerce.requestCheckout({
  client_key: CLIENT_KEY,
  request_id: 'your-order-draft-id',       // 가맹점 주문 초안 ID (웹훅 매칭에 그대로 실려 와요)
  name: '프로 플랜',
  price: 29900,                             // 서버에서 계산한 금액
  redirect_url: `${window.location.origin}/checkout/result`,
  user: {
    membership_type: 'guest',               // 'member' 면 user_id 는 부트페이에 등록된 고객의 user_id 여야 해요
    user_id: 'user_1234',                   // guest 면 가맹점 쪽 회원 식별자
    name: '홍길동',
    phone: '01012345678',
    email: 'user@example.com',
  },
  products: [
    { product_id: 'your-product-id', quantity: 1 },
  ],
  extra: {
    open_type: 'redirect',                  // 'popup' | 'iframe' | 'redirect' — 필수예요
  },
})javascript
결제가 끝나면 `redirect_url` 로 돌아와요

성공하면 쿼리스트링에 order_number(주문 고유번호)와 event(done, 분리 승인이면 confirm)가 실려요. 실패·취소면 event 없이 error_code·message 가 실려요. 전체 파라미터와 팝업·iframe 모드는 주문서 요청에서 다뤄요.

클라이언트 결과만 믿으면 안 돼요

event=done 은 사용자의 브라우저에서 받은 신호예요. 서버가 주문 조회 API와 웹훅으로 같은 결과를 확인한 뒤 주문 상태를 바꿔야 해요.

STEP 3. 서버에서 주문을 검증해요

서버는 커머스 키로 주문을 조회하고, 내부 주문 기준과 비교해요.

조회 키는 `order_number` 예요

GET /v1/orders/{order_number} 는 주문 고유번호​(예: 25071182085082524116)로만 찾아요. order_id(24자리 ObjectId)를 넣으면 ORDER_NOT_FOUND 가 돌아와요.

const auth = Buffer.from(
  `${process.env.BOOTPAY_COMMERCE_CLIENT_KEY}:${process.env.BOOTPAY_COMMERCE_SECRET_KEY}`
).toString('base64')

const response = await fetch(`https://api.bootapi.com/v1/orders/${orderNumber}`, {
  headers: {
    Authorization: `Basic ${auth}`,
    'Content-Type': 'application/json',
  },
})

const order = await response.json()

if (order.price !== expectedPrice) {
  throw new Error('주문 금액이 일치하지 않아요')
}

// 결제 완료 상태는 'payment_completed' 예요
if (order.status !== 'payment_completed') {
  throw new Error('결제 완료 주문이 아니에요')
}

await markOrderPaid(order.order_number)javascript
상태 문자열은 Enum 표에 있어요

order_pending · payment_pending · payment_completed · cancellation_completed 등 전체 값은 커머스 Enum — 주문 상태에서 확인해요.

STEP 4. 웹훅으로 한 번 더 맞춰요

주문 상태가 바뀌면 웹훅으로 알림을 받아요.

이벤트 시점 서버가 할 일
order.done 결제 완료 주문 완료 처리 또는 서비스 활성화
order.cancelled 주문 취소 환불·서비스 비활성화 처리
order.confirm_error 결제 승인 실패 주문 실패 처리
subscription.approved 구독 시작 구독 권한 활성화
subscription.hold_on 회차 결제 실패로 자동 중단 서비스 제한 + 복구 결제 안내
subscription.terminated 구독 종료 구독 권한 해제

웹훅 설정은 주문 웹훅 설정, 이벤트별 처리 기준은 웹훅 처리 가이드를 이어서 확인해요. 실제 결제 없이 수신 경로를 확인하려면 웹훅 테스트 API의 POST /v1/webhook/test를 사용해요.

다음 단계