Skip to content

API reference

External programs use this API to pull products, check stock, get quotes, place orders and query them. The store sharing feature is itself built on it.

If you only want to resell someone's products without writing code, use store sharing in the admin panel. This page is for people writing their own integration.

Before you start:

  1. Register on the target store and collect your merchant ID (app_id) and merchant key (app_key) from User centre → My profile
  2. Their products must have API access enabled, or you cannot see them
  3. The prices you get depend on your member tier on their store

Basics

  • Method: POST
  • Format: application/x-www-form-urlencoded recommended
  • Authentication: the common parameters app_id + sign
  • Success: code = 200
  • Failure: usually code = 0, with the reason in msg

Signing

php
/**
 * Generate the request signature
 * @param array $data
 * @param string $appKey
 * @return string
 */
public static function generateSignature(array $data, $appKey): string
{
    unset($data['sign']);
    ksort($data);
    foreach ($data as $key => $val) {
        if ($val === '') {
            unset($data[$key]);
        }
    }
    return md5(urldecode(http_build_query($data) . "&key=" . (string)$appKey));
}

Common request parameters

NameRequiredTypeDescription
app_idyesstring/intMerchant ID, from your profile in the user centre
signyesstringAll POST parameters of this request signed with the algorithm above

app_key is your merchant key. It is only used locally to generate the signature and should never be sent to the other server.

If the request contains array parameters such as sku, they must take part in the signature too, and the signed content must match exactly what you actually submit.

Common response format

FieldTypeDescription
codeintStatus code; 200 on success
msgstringMessage. Optional — only returned when the controller sets it explicitly
datamixedPayload

Success:

json
{
  "code": 200,
  "data": {}
}

Failure:

json
{
  "code": 0,
  "msg": "Invalid key"
}

Business fields

  • race — product variant, matching a key under [category] in the product configuration, e.g. Monthly, Yearly
  • sku — SKU combination; submit as an array, e.g. sku[Colour]=Black&sku[Capacity]=256GB
  • card_id — pre-selected card ID; only meaningful when the product detail reports draft_status=1
  • widget — custom widgets; if the product detail returns widget, submit each widget's name as a request parameter when ordering
  • request_no — idempotency key. Not strictly enforced by the code, but strongly recommended on every order to avoid duplicates

List all products

POST /shared/commodity/items

  • Body: no business parameters, just app_id and sign

data is an array of categories, each with a children array of products:

FieldTypeDescription
idintCategory or product ID
namestringCategory or product name
childrenarrayProducts available in this category
codestringProduct code, used by the detail and order endpoints
pricestring/floatGuest price
user_pricestring/floatMember / reseller price
stockintStock, for automatic-delivery products
delivery_wayintDelivery method
draft_statusintWhether buyer-selectable stock is supported

Product detail

POST /shared/commodity/item

NameRequiredTypeDescription
codeyesstringProduct code

Core fields of data:

FieldTypeDescription
idintProduct ID
namestringProduct name
descriptionstringProduct description
codestringProduct code
pricestring/floatGuest price
user_pricestring/floatMember / reseller price
stockint/stringCurrent stock
delivery_wayintDelivery method
contact_typeintContact type: 0=any, 1=phone, 2=email, 3=QQ
password_statusintQuery password enabled: 0=no, 1=yes
draft_statusintBuyer-selectable stock: 0=no, 1=yes
draft_premiumstring/floatSurcharge for pre-selection
minimumintMinimum quantity, 0 for no limit
maximumintMaximum quantity per order, 0 for no limit
configobjectParsed product configuration, typically containing category, sku, wholesale
widgetarray/nullCustom widget definitions; submit each widget's name when ordering
seckill_statusintWhether this is a flash-sale product
seckill_start_timestringFlash sale start
seckill_end_timestringFlash sale end
ownerobjectSupplier information
service_urlstringSupport link
service_qqstringSupport QQ
share_urlstringShareable product link

Check whether stock allows an order

POST /shared/commodity/inventoryState

NameRequiredTypeDescription
shared_codeyesstringProduct code
numyesintQuantity
card_idnointPre-selected card ID; 0 or omitted when not pre-selecting
racenostringProduct variant

A successful response means current stock (or the pre-selected card) satisfies the order:

json
{
  "code": 200,
  "msg": "success",
  "data": []
}

Insufficient stock, an unknown product, a discontinued product or an already-taken pre-selected card all return a failure instead.

Stock and basic configuration

POST /shared/commodity/inventory

NameRequiredTypeDescription
sharedCodeyesstringProduct code
racenostringProduct variant; the default variant is used when omitted
FieldTypeDescription
countintCurrent stock
delivery_wayintDelivery method
draft_statusintWhether pre-selection is supported
pricestring/floatBase price
user_pricestring/floatMember price
configstringProduct configuration, returned as raw INI text
factory_pricestring/floatYour cost price under the current integration identity
is_categoryboolWhether this is a variant product

Note: config here is configuration text, not the parsed object that item returns.

Live stock

POST /shared/commodity/stock

NameRequiredTypeDescription
codeyesstringProduct code
racenostringProduct variant
skunoarraySKU combination
json
{
  "code": 200,
  "data": {
    "stock": "15"
  }
}

Quote

POST /shared/commodity/valuation

NameRequiredTypeDescription
codeyesstringProduct code
numyesintQuantity
racenostringProduct variant
skunoarraySKU combination
card_idnointPre-selected card ID
json
{
  "code": 200,
  "data": {
    "price": "99.00"
  }
}

List pre-selectable cards

POST /shared/commodity/draftCard

NameRequiredTypeDescription
codeyesstringProduct code
pagerecommendedintPage number, starting at 1
limitnointPage size, default 10
racenostringProduct variant
skunoarraySKU combination
FieldTypeDescription
listarrayCards
totalintTotal count
list[].idintCard ID
list[].draftstringPreview text
list[].draft_premiumstring/floatSurcharge for this card

Only available when the product detail reports draft_status=1.

Single pre-selected card

POST /shared/commodity/draft

NameRequiredTypeDescription
codeyesstringProduct code
card_idyesintCard ID
FieldTypeDescription
draft_premiumstring/floatSurcharge for this card

Place an order

POST /shared/commodity/trade

This endpoint always pays from your balance.

NameRequiredTypeDescription
shared_codeyesstringProduct code
numyesintQuantity
request_nonostringIdempotency key; a unique value per order is strongly recommended
contactnostringContact; a placeholder value is fine
racenostringProduct variant
skunoarraySKU combination
card_idnointPre-selected card ID
passwordnostringQuery password
couponnostringCoupon code
devicenointDevice type; 0 when you do not distinguish

If the product detail returned widget, also submit each widget's name as an additional parameter.

FieldTypeDescription
tradeNostringOrder number
amountstring/floatAmount actually charged
secretstring/nullDelivery content; for manual delivery this may be a "pending" message
stockstring/intRemaining stock after the order
json
{
  "code": 200,
  "msg": "success",
  "data": {
    "url": null,
    "amount": "10.00",
    "tradeNo": "123260422101010888",
    "secret": "card key content",
    "stock": "14"
  }
}

Query an order

POST /shared/commodity/query

NameRequiredTypeDescription
tradeNoyesstringOrder number — note the field is tradeNo, not trade_no
FieldTypeDescription
secretstringDelivery content or card key
widgetobject/nullWidget values submitted with the order
statusintPayment status: 0=unpaid, 1=paid

Suggested integration flow

  1. Call items or item to pull product information
  2. If the product has category or sku, determine race and sku first
  3. If it supports pre-selection, call draftCard for the options and draft for the surcharge when needed
  4. Before ordering, confirm stock and price with stock, valuation or inventoryState
  5. Call trade to place the order
  6. Poll query if you need to track delivery

Notes

  • To test authentication only, call /shared/authentication/connect
  • The product detail endpoint returns config as a parsed object while inventory returns it as INI text. That is not a documentation error — it is how the program currently behaves
  • If you want full compatibility with the built-in sharing client, follow the field names and response shapes in this document; do not rename tradeNo to trade_no and so on

Released under the MIT License