상품 상세
손님이 쇼핑몰에서 보는 그대로 상품 하나의 이미지 · 옵션 · 배송 · 가격을 읽습니다.
업데이트됨 10.13 — 관리자 상품 응답에서 detail_content 를 뺐습니다무엇인가요
손님이 쇼핑몰 상품 화면에서 보는 것과 같은 값으로 상품 하나를 읽습니다. 상품 번호(product_no)는 상품 목록에서 얻습니다.
| 누가 보나 | 보내는 것 | 가격 · 노출 |
|---|---|---|
| 회원 토큰 로그인한 회원 | Authorization: Bearer 회원 토큰(me:read) | 그 회원 등급의 할인가 · 회원 전용 상품 · 회원 전용 카테고리가 열립니다 |
| 비회원 | X-Client-Id: ms_… (쇼핑몰이 등록한 앱) | 비회원 등급 가격. 회원 전용은 잠김 |
회원 토큰은 회원 로그인 또는 회원 동의로 받습니다. 둘 다 없으면 401 입니다.
캐시는 응답 헤더를 따르세요
비회원 응답은
Cache-Control: public, max-age=60, stale-while-revalidate=300 입니다 — 모든 비회원에게 같으니 서버 · CDN 에 담아도 됩니다(Next.js 면 ISR · 60초). 회원 응답은 private, no-store 입니다 — 등급마다 가격이 달라 담지 말고 그때그때 부르세요. API 가 이미 캐시에서 읽고 등급가만 얹어 빠릅니다. 오류 응답에는 캐시 헤더가 없습니다.상품 상세
GET
https://api.mallstory.kr/v1/store/products/{product_no}인증 회원 토큰(me:read) 또는 X-Client-Id
bash요청
curl 'https://api.mallstory.kr/v1/store/products/4' \
-H 'X-Client-Id: ms_xxxxxxxxxxxx'json200 OK (비회원)
{
"product_no": 4,
"category_ids": [],
"display_order": -999999,
"discount_rate": 0,
"sales_count": 0,
"review_count": 0,
"review_score": 0,
"created_at": "2026-09-04T06:27:41.500Z",
"name": "펩시",
"promotion_text": "ㅋㅋ",
"status_type": "OUTOFSTOCK",
"sold_out": true,
"list_price": null,
"sale_price": 5000,
"base_price": 5000,
"image_url": "https://cdn.story.store/storages/2026/09/04/9eb598eb-c575-4bbf-b28d-36a0f6e110f8.jpg",
"badges": [],
"view_permission": "GUEST",
"view_level": 0,
"images": [
"https://cdn.story.store/storages/2026/09/04/9eb598eb-c575-4bbf-b28d-36a0f6e110f8.jpg"
],
"video_url": "",
"detail_content": "",
"brand": "",
"seo": {
"title": "펩시",
"description": "ㅋㅋ",
"keywords": "",
"title_is_manual": false
},
"option_names": [],
"option_pick_types": [],
"options": [],
"notice": null,
"custom_options": [],
"custom_scope": "ONCE",
"extra_options": [],
"order_limit": {
"enabled": false,
"basis": "EACH",
"min": 0,
"max": 0
},
"order_permission": "GUEST",
"order_level": 0,
"shippable": false,
"bundle_shipping": "POSSIBLE",
"collect_clearance_code": false,
"delivery": [],
"final_price": 5000,
"strike_price": null,
"level_discount": 0
}상품 목록의 카드 필드가 모두 오고, 아래 상세 필드가 더 옵니다.
응답 필드
| 필드 | 형식 | 설명 |
|---|---|---|
images | string[] | 이미지 전부(차례대로). 첫 장이 image_url |
video_url | string | 동영상 주소. 없으면 빈 글자. 있으면 대표 이미지보다 위에 세웁니다 |
detail_content | string | 상세 설명 HTML — 상품 본문 앞뒤에 공통정보 템플릿(상단 · 하단)을 붙인 것. 템플릿을 고치면 바로 바뀝니다 |
brand | string | 브랜드. 없으면 빈 글자 |
display_order | number | 기본 전시순 값(작을수록 앞) |
seo | object | title · description · keywords · title_is_manual(true 면 제목 뒤에 쇼핑몰명을 붙이지 않음). 비어 있으면 쇼핑몰 기본값 |
option_names | string[] | 옵션명(색상 · 사이즈 …). 비면 옵션 없는 상품 |
option_pick_types | string[] | 옵션 단계마다 고르는 방식 |
options | array | 옵션 행. key(행 식별자) · values(단계별 값) · price(가산액, 음수 가능) · stock_quantity · image_url · color_hex |
custom_options | array | 추가 입력옵션 — name · input_type · required · values · guide |
custom_scope | string | 주문 요청사항을 주문에 한 번 받는가, 고른 옵션마다 받는가 코드값 |
extra_options | array | 추가 상품(name · required · use_stock · values[value · price · 재고]) |
order_limit | object | 주문 수량 제한 — enabled · basis(EACH 옵션별 · TOTAL 합계) · min · max · max_check |
order_permission | string | 주문할 수 있는 사람. 못 사는 열람자에게는 담기 대신 안내를 세웁니다 코드값 |
order_level | number | MEMBER 일 때 주문할 수 있는 최소 등급 레벨 |
shippable | boolean | 배송하는 상품인가 |
bundle_shipping | string | 다른 상품과 한 상자로 묶어 보낼 수 있는가 코드값 |
collect_clearance_code | boolean | 주문 때 통관고유부호를 받는가(해외 직구 상품) |
delivery | array | 배송 방법별 method 와 배송비 템플릿(template) |
notice | object | null | 상품정보제공고시 — mode(서식 · 이미지) · form_name · fields[name · value] · image_url |
카드 필드(목록과 같음)
| 필드 | 형식 | 설명 |
|---|---|---|
product_no | number | 상품 번호. 상세는 /v1/store/products/{product_no} |
name | string | 상품명 |
promotion_text | string | 간략소개(상품명 위 작은 글자). 없으면 빈 글자 |
image_url | string | null | 대표 이미지 1장. 이미지를 넣지 않은 상품은 null. 나머지 이미지는 상세의 images |
badges | array | 상품명 앞 배지. 한 개에 name · design · shape · text_color · background_color · border_color · image_url |
icon | object | null | 상품 이미지 우측 상단에 얹는 아이콘. name(그림의 대체 글자) · url. 없으면 null |
status_type | string | 판매 상태. 쇼핑몰 화면에는 판매중 · 품절인 상품만 나옵니다 코드값 |
sold_out | boolean | 품절인가(상품 품절 · 재고 0) |
list_price | number | null | 정가. 없으면 null |
sale_price | number | 할인 전 판매가 |
base_price | number | 상품 할인(즉시 · 기간)까지 적용한 값. 등급 할인 전 |
final_price | number | 열람자가 내는 값(등급 할인까지). 화면에 크게 쓰는 값 |
strike_price | number | null | 취소선으로 쓰는 값. 깎인 게 없으면 null |
level_discount | number | 등급으로 더 깎인 금액. 0 이면 등급 혜택이 없음 |
discount_rate | number | 할인율(%). 할인율순 정렬에 쓰는 값 |
sales_count | number | 판매량. 판매량순 정렬에 쓰는 값 |
review_count | number | 리뷰 수. 리뷰 많은순 정렬에 쓰는 값 |
review_score | number | 평점(0~5). 평점 높은순 정렬에 쓰는 값 |
created_at | ISO | 등록 시각. 최신 등록순 정렬에 쓰는 값 |
category_ids | string[] | 걸린 카테고리 키(대표 · 추가 진열) |
view_permission | string | 누가 볼 수 있나 코드값 |
view_level | number | MEMBER 일 때 볼 수 있는 최소 등급 레벨 |
locked | boolean | 이 열람자가 볼 수 없는 상품. 자리만 두고 눌리지 않게 그립니다(상세는 403) |
오류
| 상태 | code | 언제 |
|---|---|---|
| 400 | InvalidParameterValue | 상품 번호가 숫자가 아님 |
| 403 | Forbidden | 회원 전용 상품을 볼 수 없는 열람자(목록의 locked) |
| 404 | ProductNotExist | 판매중지 · 전시중지 · 지운 상품 · 없는 번호 |
| 401 | MissingClient | X-Client-Id 도 회원 토큰도 없음 |
| 401 | InvalidClient | 등록되지 않은 앱 |