샌드박스 환경 및 fixtures
대상:
https://api.hiobuy.com(Workers gateway)에 배포하는 통합 — base URL은 프로덕션과 동일.
플랜: 무료 플랜에는 셀프서비스 문서와 Sandbox 액세스가 포함됩니다. 전담 연동 및 풀필먼트 지원은 유료 플랜에서 제공됩니다.
인증: 결정론적 fixtures는 hio_test_* 접두사 API 키(key_type: test)에 만 적용됩니다. hio_live_* 프로덕션 키는 이 페이지 규칙을 절대 사용하지 않으며, 항상 upstream marketplace / warehouse에 정상 접근합니다.
관련 문서: Authentication · Response format · Errors · Rate limits · Products · Orders · Fulfillment · Webhooks
중요: Warehouse Fulfillment 테스트
Sandbox API(hio_test_*)는 mock 및 fixture 기반 통합 테스트용입니다.
HIOBuy가 앱에 WH-DEV Warehouse Developer Code를 제공한 경우, 할당된 창고 구성을 테스트할 때 Sandbox API 키를사용하지 마세요.
다음을 사용하세요:
Production API Key (hio_live_*) + WH-DEV
WH-DEV는 여전히 테스트 창고 구성입니다. WH-DEV와 함께 Production API 키를 사용한다고 해서 실제 창고 이행을 수행하는 것은 아닙니다.
| 구성 | 목적 |
|---|---|
hio_test_* | Mock / fixture API 테스트 |
hio_live_* + WH-DEV | 테스트 창고 데이터로 할당된 창고 통합 테스트 |
hio_live_* + 프로덕션 창고 인가 | 실제 창고 이행 |
Sandbox Fulfillment 엔드포인트는 사전 정의되거나 시뮬레이션된 데이터를 반환합니다. 예: sandbox 창고 위치, 잔액, 패키지, 배송 경로, 패키지 상태는 앱에 할당된 WH-DEV 구성과 다를 수 있습니다.
WH-DEV 통합을 검증할 때는 항상 Production API 키를 사용하세요.
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/* | Balance, quotes, shipments, inbounds, packages, unclaimed, returns, locations, VAS, service-requests, finance를 magic / dynamic id로 mock(아래 참조). |
/v1/support/tickets | List/detail/reply를 tkt_* fixtures로 mock. |
| Webhooks | 샌드박스 리소스는 Webhook을 자동 발행하지 않습니다. 포털 테스트 전송(livemode: false)으로 수신과 서명을 검증하세요. |
설계 목표
| 목표 | 의미 |
|---|---|
| 반복 가능 | 동일 요청 → 동일 응답(결과에 무작위 없음). |
| 문서화 | 각 시나리오에 이 페이지에서 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, shp, pkg, plat, …) | — |
scenario | snake_case | not_found, pay_declined |
문자: [a-z0-9_], 길이 ≤ ~48. fixture 의도가 없으면 실제 upstream id에 sb_를 붙이지 마세요. 일부 fulfillment 리소스는 비 sb_ 안정 id(ret_*, ucp_*, svc_*, tkt_*, inv_*)도 사용합니다.
두 가지 실패 계층
전송/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 형식 미지원.
id, product_id, 파싱된 url, mi_id, **tao_password**가 sb_* id로 해석되면 트리거.
| Fixture id | 결과 | HTTP |
|---|---|---|
(비 sb_ 임의 id) | 표준 mock 상품 | 200 |
sb_prod_not_found | NOT_FOUND | 404 |
sb_prod_offline | PRODUCT_UNAVAILABLE | 422 |
sb_prod_no_stock | Detail ok, stock: 0 | 200 |
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":"ko"}'POST /v1/products/search
channel, keyword, page, page_size, language 적용. 1688 filter / sort / 가격 필터는 수락되나 mock 행에서는 무시.
keyword(정확 일치) | 결과 |
|---|---|
| 일반 텍스트 | 히트가 있는 mock 목록 |
sb_search_empty | items: [], total: 0 |
sb_search_not_found | 빈 결과 별칭 |
Parse / upload-image / search-by-image / freight / analytics
| Endpoint | Sandbox 참고 |
|---|---|
| Parse URL | sb_* 포함 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-check | mock mpProducts 포함 upstream 스타일 envelope; 제외 목록에 mi_id/item_id에 sb_prod_not_found 사용. |
| Advanced — top keywords/list / daily-sales-trend | 문서화된 category_id / rank_id에 sb_search_empty로 빈 목록 또는 404 detail. |
주문 및 결제 fixtures(magic id)
POST /v1/orders/detail
order_id | 일반적 status | 참고 |
|---|---|---|
sb_ord_unpaid | wait_payment | — |
sb_ord_paid | wait_shipment | — |
sb_ord_shipped | wait_receive | — |
sb_ord_completed | completed | — |
sb_ord_cancelled | cancelled | — |
sb_ord_refunding | wait_shipment (refund_status in progress) | — |
sb_ord_not_found | — | 404 |
POST /v1/orders/pay
order_id | 결과 | HTTP |
|---|---|---|
sb_ord_unpaid | 결제 성공 → 논리적 paid 상태 | 200 |
sb_ord_pay_declined | PAYMENT_DECLINED | 402 |
sb_ord_pay_insufficient | PAYMENT_INSUFFICIENT_FUNDS | 402 |
sb_ord_paid | ORDER_ALREADY_PAID | 409 |
sb_ord_cancelled | ORDER_CANCELLED | 409 |
sb_ord_upstream_timeout | CHANNEL_UPSTREAM_ERROR | 502 |
Preview / create
Preview는 고정 illustrative 합계(샘플 라인 ~4500 + 운임 ~800 minor units) 반환. Create는 sbo_* 접두사 동적 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는 해당 없이 생략.
Fulfillment fixtures
참고: 아래 fixtures는 Sandbox API 테스트 전용입니다. 앱의 WH-DEV 창고 구성을 나타내지 않습니다. WH-DEV 테스트에는 Production API 키(
hio_live_*)를 사용하세요.
아래 모든 엔드포인트에는 hio_test_* 키가 필요합니다. create에서 나온 동적 id(pkg_*, sbs_*, sbi_*, …)는 키 단위로 sandbox storage에 영속됩니다.
Balance · quotes · locations · VAS catalog
| Endpoint | Sandbox 참고 |
|---|---|
GET /v1/fulfillment/balance | Mock 가용 잔액 500000 CNY minor units. |
POST /v1/fulfillment/shipping/quotes | destination.country_code와 무게 또는 치수 필요; 레거시 …/shipments/freight/estimate도 동작. |
GET /v1/fulfillment/locations | loc_wh_001(웨이하이), loc_sz_001(선전, paused), loc_yw_001(이우). |
GET /v1/fulfillment/value-added-services | 안정 CODE 가격표; LEGACY_PHOTO_PRINT는 INACTIVE → 요청 시 사용 불가. |
Shipments
Live warehouse Public id is the numeric PK as a string (e.g. "115"); order_sn is the warehouse order number. Sandbox create returns sbs_*; fixtures below use sb_shp_*.
| Fixture / id | Behavior |
|---|---|
sb_shp_unpaid | List + detail PENDING; intercept → SHIPMENT_NOT_INTERCEPTABLE |
sb_shp_shipped | Shipped detail: split boxes, first/last-mile legs, packing files; plus international tracking events. Intercept → REQUESTED |
sb_shp_not_found | Detail 404 |
sb_shp_pay_insufficient | POST …/shipments/sb_shp_pay_insufficient/pay → INSUFFICIENT_BALANCE |
sb_shp_not_cancellable | Cancel → SHIPMENT_NOT_CANCELLABLE; intercept is allowed (WAIT_SHIP) |
sb_shp_signed | Signed; intercept → SHIPMENT_NOT_INTERCEPTABLE |
sb_shp_intercepted | Detail SHIPPED + interception.status: INTERCEPTED; intercept again → SHIPMENT_INTERCEPTION_ALREADY_REQUESTED |
Dynamic sbs_* | Create / pay / list / detail / cancel / intercept against sandbox storage |
sb_parcel_not_found | Create → 422 PARCEL_NOT_FOUND |
List path: GET /v1/fulfillment/shipments. Tracking path: GET /v1/fulfillment/shipments/{id}/tracking (language query).
Inbounds(create / cancel)
Create는 동적 package_id(pkg_*)를 반환합니다 — 별도의 inbound_id는 없습니다.
| Trigger value | Field | HTTP | error.code |
|---|---|---|---|
sb_inbound_shipped | tracking_number | 409 | INBOUND_TRACKING_ALREADY_SHIPPED |
sb_inbound_exists | tracking_number | 409 | INBOUND_TRACKING_ALREADY_EXISTS |
sb_inbound_bad_tracking | tracking_number | 422 | INVALID_TRACKING_NUMBER |
sb_inbound_external_exists | external_order_id | 409 | EXTERNAL_ORDER_ID_ALREADY_EXISTS |
sb_vas_missing | services[].service_code | 422 | VALUE_ADDED_SERVICE_NOT_FOUND |
sb_vas_unavailable | services[].service_code | 422 | VALUE_ADDED_SERVICE_UNAVAILABLE |
sb_vas_outbound | services[].service_code | 422 | VALUE_ADDED_SERVICE_INVALID_STAGE |
| Cancel id | HTTP | error.code |
|---|---|---|
Dynamic sbi_*(create 후) | 200 | 취소됨; 관련 package 폐기 |
동일 sbi_* 재실행 | 409 | INBOUND_NOT_EDITABLE |
sb_inb_not_found | 404 | INBOUND_NOT_FOUND |
sb_inb_received | 409 | INBOUND_ALREADY_RECEIVED |
sb_inb_shipped / sb_inb_consolidated / sb_inb_cancelled | 409 | INBOUND_NOT_EDITABLE |
Packages · tracking · list
package_id | Detail / tracking |
|---|---|
Dynamic pkg_* | PENDING; tracking은 INBOUND_CREATED부터 시작 |
sb_pkg_pending | PENDING |
sb_pkg_received | RECEIVED + PHOTO timeline |
sb_pkg_exception | RECEIVED + condition.EXCEPTION |
sb_pkg_shipped | SHIPPED 전체 outbound timeline |
sb_pkg_not_found | 404 PACKAGE_NOT_FOUND |
Unclaimed packages
| Id / trigger | 동작 |
|---|---|
ucp_01K2ABCDEF1234567890 | 클레임 가능; 실제 추적번호 SF123456789012(목록은 마스킹) |
ucp_01K2ABCDEF9876543210 | 클레임 가능; YT738800001148 |
sb_ucp_not_found | 404 UNCLAIMED_PACKAGE_NOT_FOUND |
sb_ucp_already_claimed | 409 PACKAGE_ALREADY_CLAIMED |
sb_ucp_not_claimable | 409 PACKAGE_NOT_CLAIMABLE |
| 동일 ucp에서 잘못된 추적번호 ×5 | 429 CLAIM_ATTEMPTS_EXCEEDED |
Returns
| Id | 동작 |
|---|---|
ret_pending_001 | PENDING; fee=18; confirm 성공 |
ret_pending_002 | PENDING; fee=20; 18로 confirm → RETURN_FEE_CHANGED |
ret_returned_001 | RETURNED + tracking |
ret_cancelled_001 | CANCELLED |
sb_ret_not_found | 404 RETURN_NOT_FOUND |
sb_ret_fee_not_ready | Confirm → RETURN_FEE_NOT_READY |
sb_ret_insufficient | Confirm → INSUFFICIENT_BALANCE |
sb_pkg_shipped에서 Create | 409 PACKAGE_NOT_RETURNABLE |
Service requests
| Id | 동작 |
|---|---|
svc_photo_completed | PHOTO COMPLETED + images |
svc_inspection_failed | BASIC_INSPECTION FAILED |
svc_video_processing | VIDEO PROCESSING |
svc_reinforce_pending | PACKAGE_REINFORCEMENT PENDING |
svc_wooden_awaiting | WOODEN_FRAME 확인 대기 |
sb_svc_not_found | 404 |
sb_svc_fee_not_ready / sb_svc_insufficient | Confirm 엣지 케이스 |
Finance(transactions / invoices)
| Fixture | 참고 |
|---|---|
txn_01K2ABC001…006 | TOP_UP / VAS / RETURN / SHIPPING / REFUND / STORAGE |
inv_01K2ABC001 | ISSUED(다운로드 가능) |
inv_01K2ABC002 | PENDING |
inv_01K2ABC003 | REJECTED |
지원 티켓 fixtures
| Fixture id | 시나리오 |
|---|---|
tkt_01K2ABCDEF1234567890 | PACKAGE · NORMAL · WAITING_FOR_HIOBUY |
tkt_01K2ABCDEF9876543210 | RETURN · URGENT · WAITING_FOR_CUSTOMER |
tkt_01K2ABCDEFAPIRESOLVED | API · NORMAL · RESOLVED |
tkt_01K2ABCDEFSHIPCLOSED | SHIPMENT · NORMAL · CLOSED(답변 없음) |
tkt_not_found | 404 TICKET_NOT_FOUND |
Support tickets 참조.
플랫폼 트리거: sandbox_trigger
hio_test_*에 만 허용; 프로덕션 키는 필드를 조용히 무시.
sandbox_trigger | HTTP | error.code |
|---|---|---|
sb_plat_quota_exceeded | 429 | QUOTA_EXCEEDED |
sb_plat_rate_limited | 429 | RATE_LIMIT_EXCEEDED |
sb_plat_upstream_error | 502 | CHANNEL_UPSTREAM_ERROR |
현실적인 body가 검증되도록 무해한 id와 조합:
{
"channel": "1688",
"product_id": "123456",
"language": "ko",
"sandbox_trigger": "sb_plat_quota_exceeded"
}트리거와 결합한 특수 auth fixture **sb_auth_channel_required**는 일반 «authorized by default» 규칙에도 UI 회귀용 CHANNEL_AUTH_REQUIRED(403) 생성 가능.
구현 상태 스냅샷
| 단계 | 커버리지 | 참고 |
|---|---|---|
| Shipped | Products, 조달 주문, fulfillment(balance/quotes/shipments/inbounds/packages/unclaimed/returns/locations/VAS/service-requests/finance), 지원 티켓 | 이 사이트에 게시된 Public API 부분집합 반영. |
| Not yet | 자동 발행 샌드박스 webhooks; 미게시 OpenAPI-only 카탈로그 확장 | Webhook 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_shp_unpaid / sb_shp_shipped / sb_shp_signed / sb_shp_intercepted → shipment list / detail / intercept
sb_pkg_received / sb_pkg_shipped → package detail / fulfillment timeline
sb_inbound_exists → inbound create 409 tracking exists
ret_pending_001 → return confirm happy path
ucp_01K2ABCDEF1234567890 → unclaimed claimable
svc_photo_completed → VAS request completed
tkt_01K2ABCDEF1234567890 → support ticket open
sb_plat_quota_exceeded → sandbox_trigger → 429 QUOTA_EXCEEDED내부 fixtures 추가 시 회귀 테스트에 이 번호 체계를 반영 — mock 내부 standard JSON 형태는 절대 변경하지 마세요.
Get Support
Need integration help? Contact Developer Support at support@hiobuy.com · Response within 1–2 business days