Guide · Fulfillment

WH-DEV vs Sandbox: Test Warehouse Fulfillment Without Mixing Keys

Sandbox keys (hio_test_*) return fixtures, not your assigned warehouse. Test WH-DEV with hio_live_* plus the bound WH-DEV code, and know which errors are expected along the way.

HHioBuy Developer Team•7 min read•

WH-DEV vs Sandbox: three test configurations

You have a Growth or Enterprise plan. HioBuy has approved warehouse fulfillment for your app and issued a WH-DEV warehouse developer code. You start testing, and the results look wrong: the warehouse locations are not the ones you expected, the wallet balance is a round number you never topped up, and shipment ids look like sbs_… instead of the numeric ids in the docs.

In almost every case the cause is the same. The requests are signed with a Sandbox key (hio_test_*). Sandbox never reads your WH-DEV configuration. It returns fixtures.

This guide covers one decision: which key and which configuration to use when you test warehouse fulfillment. For the full fulfillment flow, see the Fulfillment overview. For Sandbox product search behavior, see our earlier guide on fixture data vs the live catalog.

The short answer

To test your assigned WH-DEV warehouse, use your Production API key (hio_live_*) on an app that has the WH-DEV code bound in the portal.

WH-DEV is still a test warehouse configuration. Using hio_live_* with WH-DEV does not mean your app is performing live warehouse fulfillment.

Do not use a Sandbox key to test an assigned WH-DEV warehouse.

Three configurations, three purposes

All three use the same base URL, https://api.hiobuy.com. The difference is the key and the warehouse binding on the app.

ConfigurationPurposeWhat /v1/fulfillment/* returns
hio_test_* (Sandbox)Mock / fixture API testingPredefined or simulated data, the same for every Sandbox user
hio_live_* + WH-DEV codeAssigned warehouse integration testingTest warehouse data from the WH-DEV warehouse configured for your app
hio_live_* + production warehouse authorizationLive warehouse fulfillmentReal parcels, real packing, real freight

Source: Sandbox environment & fixtures.

What Sandbox actually gives you

Sandbox is built to be repeatable: the same request returns the same response. That makes it useful for CI, error handling and UI states. It also means it knows nothing about your warehouse.

From the Sandbox reference, fulfillment fixtures include:

  • GET /v1/fulfillment/balance returns a mock available balance of 500000 CNY minor units (fen).
  • GET /v1/fulfillment/locations returns loc_wh_001, loc_sz_001 and loc_yw_001. Live warehouse mode uses the warehouse numeric id, for example "1".
  • POST /v1/fulfillment/shipments/create returns dynamic sbs_* ids. Live warehouse shipment ids are the numeric primary key as a string, for example "115".
  • Fixed ids such as sb_shp_unpaid, sb_pkg_received or sb_shp_pay_insufficient force specific states and errors.
  • Channel OAuth is treated as authorized, and quotas and rate limits are skipped for test keys.
  • Sandbox resources do not auto-emit webhooks. Use Send test in the portal.

If any of these values show up while you think you are testing WH-DEV, check the key first.

Sandbox is the right tool when you want to:

  • Exercise error paths (INSUFFICIENT_BALANCE, PARCEL_NOT_FOUND, SHIPMENT_NOT_INTERCEPTABLE) on demand.
  • Build UI for every shipment and package status without waiting for a warehouse.
  • Run deterministic regression tests.

It is the wrong tool for checking your warehouse locations, your shipping channels, your test wallet or package arrival at your assigned warehouse.

Before you test WH-DEV

From the WH-DEV fulfillment testing guide:

RequirementWhere
Developer subscription with warehouse fulfillment accessGrowth or Enterprise plan; see Warehouse authorization
WH-DEV warehouse developer codeProvided by HioBuy after approval
App configured for HioBuy warehouse fulfillmentPortal → Authorizations
Production API key (hio_live_*)Authentication
Test wallet balanceWallet balance; top up before paying a shipment
Test destination address and shipping channelsConfigured by HioBuy on your WH-DEV warehouse

Free plans include documentation and Sandbox access. Warehouse fulfillment requires a paid plan (Growth or Enterprise).

Bind the code once, then forget it

In the portal: Authorizations → Use HioBuy fulfillment → pick a procurement mode → enter the warehouse code. The binding is app-level, not per channel.

After that, your requests carry only the Bearer key. The Gateway attaches the warehouse code server-side.

curl https://api.hiobuy.com/v1/fulfillment/balance \
  -H "Authorization: Bearer hio_live_xxxxxxxx"

Never send these in Public API calls:

  • The warehouse developer code
  • Taobao, 1688 or Weidian access or refresh tokens
  • Portal session JWTs

The WH-DEV test path

Portal: bind WH-DEV code to the app (once)
        │
        ▼
 ┌──────────────────────────────┐      ┌──────────────────────────────────┐
 │ POST /v1/orders/create       │  or  │ POST /v1/fulfillment/inbounds/   │
 │ (procurement → warehouse)    │      │ create (parcel you control)      │
 └──────────────┬───────────────┘      └────────────────┬─────────────────┘
                └──────────────┬────────────────────────┘
                               ▼
        GET /v1/fulfillment/packages/{package_id}
        poll until status = RECEIVED      ← warehouse receiving (may be simulated)
                               │
                               ▼
        POST /v1/fulfillment/shipping/quotes
        pick quotes[].channel.code
                               │
                               ▼
        POST /v1/fulfillment/shipments/create
        tracking_numbers[], receiver, shipping_channel_code → status PENDING
                               │
                               ▼
        GET /v1/fulfillment/shipments/{id}
        poll while warehouse packs and measures   ← may be simulated
                               │  status = WAIT_PAYMENT
                               ▼
        POST /v1/fulfillment/shipments/{id}/pay
                               │
                               ▼
        GET /v1/fulfillment/shipments/{id}/tracking

Shipment status progression: PENDING → WAIT_PAYMENT → WAIT_SHIP → SHIPPED → SIGNED.

Money on fulfillment routes is in CNY fen. Responses include top-level monetary_unit: "CNY_minor", and every { amount, currency } field uses 1 yuan = 100 fen.

Common mistakes

1. Testing WH-DEV with hio_test_*

Symptom: locations, balance, channels or package states do not match what HioBuy configured for your app.

Fix: switch to hio_live_* on the app that has the WH-DEV code bound. Keep hio_test_* for fixture tests only.

A useful habit: log the key prefix (never the full key) with every fulfillment request in your test environment. If the log says hio_test_, you are on fixtures.

2. Expecting Sandbox fixtures to match WH-DEV

Symptom: a test suite written against sb_shp_* or sb_pkg_* ids fails when pointed at WH-DEV.

Fix: treat them as two suites. Sandbox ids are magic values that only exist for test keys. WH-DEV returns ids created by your own inbound notices, orders and shipments.

3. Calling fulfillment on a self-fulfillment app

Symptom:

HTTPerror.code
403FULFILLMENT_MODE_NOT_SUPPORTED

Cause: the app is still in self-fulfillment mode (the default). /v1/fulfillment/* is not available in that mode.

Fix: in the portal, switch the app to Use HioBuy fulfillment and bind the warehouse code. Check you are using the key for that same app. Each app has one key, and channel access follows that app's plan.

4. Paying a shipment right after creating it

Symptom:

HTTPerror.code
409SHIPMENT_NOT_READY_FOR_PAYMENT

This is expected. A new shipment starts in PENDING. The warehouse still has to retrieve, consolidate and pack the packages, then measure final weight and dimensions and calculate final freight.

Poll shipment detail and pay when these signals are present:

SignalReady for payment
statusWAIT_PAYMENT
payment_statusUNPAID with total.outstanding > 0
times.packed_atNot null
boxes[]Non-empty, with final weight and dimensions

Other pay errors to handle: 404 NOT_FOUND, 409 SHIPMENT_ALREADY_PAID, 402 INSUFFICIENT_BALANCE (top up the wallet).

In Sandbox you can reproduce these with fixtures such as sb_shp_pay_insufficient. In WH-DEV, the 409 usually just means packing is not finished.

5. Waiting for a "ready for payment" webhook

There is no such event today. Fulfillment webhooks include package.received, package.exception, consolidation.completed, shipment.created, shipment.dispatched, shipment.delivered, shipment.exception and balance.low.

Use webhooks to trigger a GET of shipment detail, and decide payability from the detail response:

Webhook (package.received / shipment.dispatched / …)
   → your system
   → GET /v1/fulfillment/shipments/{id}
   → business logic: pay / notify customer

6. Treating WH-DEV shipping channels as production specs

WH-DEV channels exist to test quote integration, channel selection, shipment creation, settlement and tracking. Channel names, prices, delivery times, customs and tax models in a test warehouse are not commercial commitments. Production channels may differ.

When to contact support

WH-DEV is not a continuously running warehouse. These events may need HioBuy to simulate them while you test:

  • Package received, inspected or stored
  • Shipment packing
  • Final weight and dimension measurement
  • Shipment dispatch
  • Tracking progression and delivery completion

If your test has been waiting on one of these, email support@hiobuy.com or open a support ticket. Use the format from the WH-DEV guide:

Subject: WH-DEV Fulfillment Test Assistance

Application:
WH-DEV Code:
Package ID:
Shipment ID:
Order SN:
Current Status:
Expected Next Test Step:
Request ID:

Every API response carries a request_id (and an x-request-id header). Include it.

Do not email support for Sandbox fixtures. Sandbox state is controlled entirely by the ids and triggers you send.

In production, these warehouse steps run through the normal workflow. You do not contact support for each shipment; your app monitors status, waits for payability, pays and reads tracking.

A simple environment setup

CI / unit tests        → HIOBUY_KEY=hio_test_…   (fixtures, deterministic)
WH-DEV integration     → HIOBUY_KEY=hio_live_…   (app with WH-DEV code bound)
Production             → HIOBUY_KEY=hio_live_…   (app with production warehouse authorization)

Keep keys server-side. Do not expose them in browser JavaScript, mobile apps or public repositories.

Checklist

  • Plan includes warehouse fulfillment (Growth or Enterprise)
  • App set to Use HioBuy fulfillment, WH-DEV code bound once
  • Requests use hio_live_* for that app, Bearer header only
  • Package polled to RECEIVED before quoting and creating a shipment
  • Shipment polled to WAIT_PAYMENT before calling pay
  • Amounts read as CNY fen (CNY_minor)
  • Sandbox used only for fixture and error-path tests

Next steps

The API Reference is the source of truth for fields and statuses. If anything here differs, follow the reference.


Next step

If you already understand the workflow, move to the API reference for exact request and response fields, or open the developer console to create your application.

Ready to build?

Open the API documentation or create your HioBuy developer application.

Related guides