v1 장바구니 API는 회원의 장바구니 관리와 주문 전 가격 견적을 제공해요. 엔드포인트별 필드와 오류는 장바구니 API 원문을 확인해요.
모든 URL은 https://api.bootapi.com 기준이며 서버 Basic 인증을 사용해요. 회원 장바구니에는 Bootpay-User-JWT 또는 쇼핑몰 서버가 secretKey로 인증하고 지정한 user_id가 필요해요. 두 값을 함께 보내면 같은 회원이어야 해요. client_key만으로 인증한 호출에서는 user_id를 사용할 수 없어요.
장바구니 HTTP 계약
| 메서드·URL | 본문 | 성공 본문 |
|---|---|---|
GET /v1/cart |
없음 | 장바구니 객체 |
POST /v1/cart |
product_id, product_option_id?, quantity |
null — 추가 후 다시 조회 |
PUT /v1/cart/:id 또는 PATCH |
quantity |
변경된 항목 |
DELETE /v1/cart/:id |
없음 | null |
DELETE /v1/cart/destroy_items |
item_ids: string[] |
success와 제거/남은 개수 |
DELETE /v1/cart/clear |
선택 group_key |
success와 제거/남은 개수 |
POST /v1/cart/merge |
cart_items: object[] |
비회원 장바구니 병합 결과 |
POST /v1/cart/batch |
items: object[] |
일괄 추가 결과 |
POST /v1/cart/checkout |
item_ids: string[], 선택 group_key |
{ "order_pre_id": "...", "url": "..." } |
PATCH /v1/cart/:id/update_period |
subscription_period_id |
기간 변경 결과 |
:id는 상품 ID가 아니라 장바구니 항목 ID예요. 추가는 단건 본문이고 일괄 추가는 items 배열이에요. 수량 변경 액션은 옵션 변경을 처리하지 않아요. 옵션을 바꾸려면 항목 삭제/추가 흐름을 사용해요.
추가 API는 is_subscription, period, corporate_type, user_group_id도 읽어요. 회원/기업 권한과 상품 소속을 서버에서 검증한 값만 전달해요.
await commerce.post('cart', {
product_id: productId,
product_option_id: optionId,
quantity: 2
}, { headers: { 'Bootpay-User-JWT': customerJwt } })
const cart = await commerce.get('cart', {
headers: { 'Bootpay-User-JWT': customerJwt }
})javascript조회 객체에는 cart_id, user_id, cart_items, delivery_groups, summary, checkout_groups, item_count, total_summary, created_at, updated_at가 있어요. checkout_groups[].group_key는 일반/구독 및 구매 유형별 결제 그룹을 구분해요. POST /v1/cart/checkout에서는 item_ids를 배열로 보내고, 한 주문에는 한 그룹만 담아요. item_ids와 group_key를 모두 생략하면 REQUIRED_PARAMETER_IS_MISSING이에요. group_key를 함께 보내면 해당 그룹의 항목만 주문해요. 성공 응답의 url로 결제 화면을 열고, 결제가 끝난 뒤 장바구니 항목이 빠져요.
컨트롤러에 preview/benefits 메서드가 남아 있어도 /v1/cart/preview, /v1/cart/benefits 라우트는 없어요. 아래 order-preview를 사용해요.
비회원 상품 검증·배송비·미리보기
| 메서드·URL | 요청 | 응답 |
|---|---|---|
POST /v1/cart/validate |
cart_items |
{ cart_items: [...] } |
POST /v1/cart/delivery-fee |
cart_items |
{ delivery_groups: [...] } |
POST /v1/cart/order-preview |
cart_items, 선택 shipping_address.zipcode |
checkout_ready, amounts, quote_token, expires_at 등 |
const preview = await commerce.cart.orderPreview({
cart_items: [{ product_id: productId, product_option_id: optionId, quantity: 2 }]
})javascriptvalidate는 구매 불가 항목도 빼지 않고 is_available: false와 reason을 돌려줘요. 견적은 상품 금액·배송비를 주문 준비와 같은 규칙으로 계산해요. shipping_address.zipcode를 넣으면 제주·도서산간 추가 배송비까지 확정해요. 쿠폰·적립금은 반영하지 않고 구독 상품은 이 견적으로 결제할 수 없어요.
{
"checkout_ready": true,
"amounts": {
"product_price": 20000,
"delivery_price": 3000,
"total_price": 23000
},
"quote_token": "q1.eyJ2Ijo...",
"expires_at": "2026-09-29T03:00:00Z"
}jsoncart_items는 최대 50개이며 수량은 각 항목과 같은 상품·옵션의 합계 모두 1~999여야 해요. 구매 불가 항목이 하나라도 있으면 checkout_ready: false, amounts: null이며 토큰이 없어요. 견적 토큰은 10분 동안 유효해요. 회원 장바구니에서 결제한다면 항목마다 cart_item_id를 보내세요. 결제 완료 후 해당 줄에서 결제한 수량만 차감해요.
회원 견적은 JWT 또는 secretKey 인증의 user_id를 사용해요. 비회원 견적에 Bootpay-Device-UUID를 보냈다면 준비 요청에도 같은 값을 보내야 해요. 견적과 준비의 구매자가 달라지면 ORDER_QUOTE_SESSION_MISMATCH로 거절돼요. 미리보기가 성공해도 주문서나 재고 예약은 생성되지 않아요.
찜
| 메서드·URL | 본문 | 성공 본문 |
|---|---|---|
GET /v1/wishlist |
없음 | { "wishlist_items": [], "total_items": 0 } |
POST /v1/wishlist |
product_id, 선택 product_option_id |
null |
DELETE /v1/wishlist/:id |
없음 | null |
POST /v1/wishlist/:id/to_cart |
없음 | null; 장바구니에 수량 1 추가 후 찜 삭제 |
:id는 wishlist_items[].wishlist_id예요. 항목에는 product_id, product_option_id, product_name, product_option_name, image, price, available, unavailable_label이 있어요. to_cart가 성공하면 찜과 장바구니를 다시 조회해요.
찜 API도 회원 전용이에요. Bootpay-User-JWT 또는 secretKey 인증의 user_id로 회원을 지정해요. POST /v1/wishlist는 다른 상점의 상품 ID를 PRODUCT_NOT_FOUND로 거절해요. 다른 회원의 wishlist_id로 삭제·이동하면 404예요. 필드와 오류는 찜 API 원문을 확인해요.
to_cart 재시도
POST /v1/wishlist/:id/to_cart에 Idempotency-Key 헤더를 보내면, 같은 회원이 같은 항목으로 재전송해도 장바구니 수량이 다시 오르지 않고 최초 결과를 돌려줘요. 같은 키로 다른 항목을 보내면 409 IDEMPOTENCY_REQUEST_MISMATCH예요. 헤더가 없으면 이전 동작 그대로예요.
담기까지 성공한 뒤 찜 삭제가 실패해 요청 자체가 실패로 끝난 경우에는, 같은 키의 재시도가 다시 실행돼요(주문 준비의 멱등 계약과 같아요). 응답을 받은 뒤의 재전송·다중 클릭은 막혀요.