샌드박스 환경 및 fixtures

대상: https://api.hiobuy.com(Workers gateway)에 배포하는 통합 — base URL은 프로덕션과 동일.

인증: 결정론적 fixtures는 hio_test_* 접두사 API 키(key_type: test)에 적용됩니다. hio_live_* 프로덕션 키는 이 페이지 규칙을 절대 사용하지 않으며, 항상 upstream marketplace에 정상 접근합니다.

관련 문서: Authentication · Response format · Errors · Rate limits · Products · Orders · Webhooks

Public API 커버리지(요약)

영역Sandbox
전역response_format: upstream 거부(standard만). currency body 필드는 prod와 같이 거부. sandbox_trigger는 test 키에 허용(플랫폼 fixtures). Channel OAuth는 hio_test_*인가된 것으로 처리. test 키에 할당량 및 rate limits 건너뜀.
/v1/products/*Search, detail, parse, upload-image, search-by-image, freight estimate, batch-check, 1688 analytics 엔드포인트 아래 문서대로 mock. 이 사이트 handoff 세트 밖 OpenAPI-only 확장은 mock 없음.
/v1/orders/*Preview, create, detail, pay, cancel, logistics trace, list, purchase query를 magic / dynamic id로 mock.
/v1/fulfillment/*게이트웨이에서 현재 mock 없음 — 샌드박스에서 사용 불가로 취급.
Webhooks샌드박스 주문은 webhooks를 발행하지 않음.

설계 목표

목표의미
반복 가능동일 요청 → 동일 응답(결과에 무작위 없음).
문서화각 시나리오에 이 페이지에서 grep할 수 있는 안정 id 또는 keyword.
계약 정렬JSON은 프로덕션 standard 스키마 필드와 일치; 값은 다름.
기본 happy path알 수 없는 id는 일반 성공 mock으로 fallback.
명시적 실패sb_* id 또는 sandbox_trigger로 오류 / 엣지 상태 강제.

명명: sb_{domain}_{scenario}

세그먼트규칙
접두사항상 sb_sb_prod_not_found
domain소문자 명사(prod, search, ord, plat, auth, …)
scenariosnake_casenot_found, pay_declined

문자: [a-z0-9_], 길이 ≤ ~48. fixture 의도가 없으면 실제 upstream id에 sb_붙이지 마세요.

두 가지 실패 계층

전송/API 오류HTTP 200 비즈니스 상태를 구분:

  • API 실패 → HTTP 4xx/5xx + error.code(예: NOT_FOUND, PAYMENT_DECLINED).
  • HTTP 200 + 상태 → 예: variants[].stock = 0, status: wait_payment.

상품 fixtures(개요)

POST /v1/products/detail

Product detail 참조. 샌드박스에서 upstream 형식 미지원.

product_id, 파싱된 url, mi_id, **tao_password**가 sb_* id로 해석되면 트리거.

Fixture id결과HTTP
(비 sb_ 임의 id)표준 mock 상품200
sb_prod_not_foundNOT_FOUND404
sb_prod_offlinePRODUCT_UNAVAILABLE422
sb_prod_no_stockDetail ok, stock: 0200
curl https://api.hiobuy.com/v1/products/detail \
  -H "Authorization: Bearer hio_test_..." \
  -H "Content-Type: application/json" \
  -d '{"channel":"1688","product_id":"sb_prod_not_found","language":"en"}'

POST /v1/products/search

channel, keyword, page, page_size, language 적용. 1688 filter / sort / 가격 필터는 수락되나 mock 행에서는 무시.

keyword(정확 일치)결과
일반 텍스트히트가 있는 mock 목록
sb_search_emptyitems: [], total: 0
sb_search_not_found빈 결과 별칭

Parse / upload-image / search-by-image / freight / analytics

EndpointSandbox 참고
Parse URLsb_* 포함 URL query/path는 detail 동작 반영.
Upload image검증 통과 후 항상 { "image_id": "img_sandbox_mock" }.
Image search선택 keyword: sb_search_empty는 빈 목록; 흐름 테스트는 upload-image와 병행.
Advanced — freight estimate기본 국내 운임 mock 800 minor units, preview와 정렬.
Advanced — batch-checkmock mpProducts 포함 upstream 스타일 envelope; 제외 목록에 mi_id/item_idsb_prod_not_found 사용.
Advanced — top keywords/list / daily-sales-trend문서화된 category_id / rank_idsb_search_empty로 빈 목록 또는 404 detail.

주문 및 결제 fixtures(magic id)

POST /v1/orders/detail

order_id일반적 status참고
sb_ord_unpaidwait_payment
sb_ord_paidwait_shipment
sb_ord_shippedwait_receive
sb_ord_completedcompleted
sb_ord_cancelledcancelled
sb_ord_refundingwait_shipment (refund_status in progress)
sb_ord_not_found404

POST /v1/orders/pay

order_id결과HTTP
sb_ord_unpaid결제 성공 → 논리적 paid 상태200
sb_ord_pay_declinedPAYMENT_DECLINED402
sb_ord_pay_insufficientPAYMENT_INSUFFICIENT_FUNDS402
sb_ord_paidORDER_ALREADY_PAID409
sb_ord_cancelledORDER_CANCELLED409
sb_ord_upstream_timeoutCHANNEL_UPSTREAM_ERROR502

Preview / create

Preview는 고정 illustrative 합계(샘플 라인 ~4500 + 운임 ~800 minor units) 반환. Createsbo_* 접두사 동적 order_id를 sandbox storage에 영속 — offer_id: sb_prod_offline / sb_prod_no_stock 참조 라인은 프로덕션 의미와 같이 422.

Cancel / logistics / list / purchase query

cancel, trace, detail list에 따라: 미결제 sb_ord_* 및 동적 미결제 sbo_* 취소 가능; paid/shipped 등 fixtures는 ORDER_NOT_CANCELLABLE. Logistics는 sb_ord_shipped / completed mock에 packages; unpaid/paid-await-shipment는 packages: []. 구매자 목록은 빈 mock에 product_name: sb_ord_list_empty 반영. **Purchase query**는 upstream envelope 반환; not-found pseudo id는 해당 없이 생략.

플랫폼 트리거: sandbox_trigger

hio_test_* 허용; 프로덕션 키는 필드를 조용히 무시.

sandbox_triggerHTTPerror.code
sb_plat_quota_exceeded429QUOTA_EXCEEDED
sb_plat_rate_limited429RATE_LIMIT_EXCEEDED
sb_plat_upstream_error502CHANNEL_UPSTREAM_ERROR

현실적인 body가 검증되도록 무해한 id와 조합:

{
  "channel": "1688",
  "product_id": "123456",
  "language": "en",
  "sandbox_trigger": "sb_plat_quota_exceeded"
}

트리거와 결합한 특수 auth fixture **sb_auth_channel_required**는 일반 «authorized by default» 규칙에도 UI 회귀용 CHANNEL_AUTH_REQUIRED(403) 생성 가능.

구현 상태 스냅샷

단계커버리지참고
Shipped위 Product + procurement API이 사이트에 게시된 Public API 부분집합 반영.
Not yet전체 /v1/fulfillment/*, webhooks, 미게시 OpenAPI-only 경로공지 전까지 sandbox CI에서 의존하지 마세요.

빠른 복사 치트시트

sb_prod_not_found          → 404 product missing
sb_prod_offline            → 422 unavailable
sb_prod_no_stock           → 200 detail with zero stock

sb_search_empty            → empty search/items
sb_ord_list_empty          → empty buyer order list filter
img_sandbox_mock           → stable upload-image id

sb_ord_unpaid              → detail wait_payment • pay succeeds • cancel ok
sb_ord_pay_declined        → pay 402 PAYMENT_DECLINED
sb_ord_paid                → pay 409 ALREADY_PAID • trace maybe empty until shipped fixtures
sb_ord_shipped             → detail wait_receive • trace populated
sb_ord_cancelled           → cancelled state • pay conflicts

sb_plat_quota_exceeded     → sandbox_trigger → 429 QUOTA_EXCEEDED

내부 fixtures 추가 시 회귀 테스트에 이 번호 체계를 반영 — mock 내부 standard JSON 형태는 절대 변경하지 마세요.