# 05. Shopping
# About platform logistics order process, please refer to the Documentation
# 1 Order
# 1.1 Create Order V2(POST)
- Create order
payType=1or omitted: page payment (default), andcjPayUrlwill be returned (deprecated, see the notice below)payType=2: balance payment, and the order will continue through add-to-cart, order confirmation, and balance deductionpayType=3: create the order only without initiating payment, add-to-cart, or order confirmation- Add param platformToken to header, The way to obtain platformToken is the same as the way to obtain CJ Access Token. If not required, the value can be empty. (2025-01-08 update)
cjPayUrl is deprecated
The cjPayUrl payment page redirect address returned with payType=1 (page payment) is deprecated and is no longer maintained. Do not use it in new integrations. Please pay in one of the following ways instead:
payType=2: pay with balance directly while creating the order;payType=3: create the order only, then call "2.3 Pay Balance V2(POST)" yourself to complete the payment.
The field is still returned for backward compatibility with existing integrations, but it is no longer maintained and may stop working or be removed in the future.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/createOrderV2
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/createOrderV2' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'platformToken: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"orderNumber": "1234",
"shippingZip": "123",
"shippingCountry": "123",
"shippingCountryCode": "US",
"shippingProvince": "123",
"shippingCity": "132",
"shippingCounty": "",
"shippingPhone": "111",
"shippingCustomerName": "123213",
"shippingAddress": "123213",
"shippingAddress2": "123213",
"taxId": "123",
"remark": "note",
"email": "",
"consigneeID": "",
"payType": "",
"shopAmount": "",
"logisticName": "PostNL",
"fromCountryCode": "CN",
"houseNumber": "123",
"platform": "shopify",
"iossType": "",
"iossNumber": "",
"orderFlow": 1,
"products": [
{
"vid": "92511400-C758-4474-93CA-66D442F5F787",
"quantity": 1,
"storeLineItemId": "test-lineItemId-1111"
}
]
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| orderNumber | Order number | string | Y | 50 | |
| shippingZip | Zip of destination | string | N | 20 | |
| shippingCountryCode | Destination country code | string | Y | 20 | Use a two-letter country code |
| shippingCountry | Destination country | string | Y | 50 | |
| shippingProvince | Destination province/state | string | Y | 50 | |
| shippingCity | Destination city | string | Y | 50 | |
| shippingCounty | Destination county | string | N | 50 | |
| shippingPhone | Recipient phone number | string | N | 20 | |
| shippingCustomerName | Recipient name | string | Y | 50 | |
| shippingAddress | Recipient address line 1 | string | Y | 500 | |
| shippingAddress2 | Recipient address line 2 | string | N | 500 | |
| houseNumber | House number | string | N | 20 | |
| string | N | 50 | |||
| taxId | Tax ID | string | N | 20 | |
| remark | Order remark | string | N | 500 | |
| consigneeID | Consignee ID | string | N | 20 | |
| payType | Payment type | int | N | 10 | 1=page payment (default, returns cjPayUrl, deprecated), 2=balance payment, 3=create order only |
| isSandbox | Sandbox order flag | integer | N | 1 | 0=normal order, 1=sandbox order |
| shopAmount | Order amount | BigDecimal | N | 20 | |
| logisticName | Logistics name | string | Y | 50 | |
| fromCountryCode | Shipping country | string | Y | 20 | Use a two-letter country code |
| platform | Platform type, default Api | string | N | 20 | Refer to Platforms |
| shopLogisticsType | Shipping mode, default value: 2 | int | N | 20 | 1=platform logistics, 2=merchant logistics, 3=platform logistics with CJ-assigned warehouse. Defaults to 2 (merchant logistics) when not provided |
| storageId | CJ warehouse ID | string | N | 40 | Used when shopLogisticsType=1 |
| iossType | IOSS type | int | N | 20 | 1=no IOSS, 2=use your IOSS, 3=use CJ IOSS |
| iossNumber | IOSS number | string | N | 10 | |
| storeName | Store name | String | N | 50 | If provided, the system will validate that the store name matches an API store in CJ system. If not provided, the order will be assigned to the default API store |
| storeOrderTime | Store order time | Long | N | 20 | Timestamp in seconds. Represents the actual order creation time in the customer's store. If the time is later than the current system time, an error will be returned |
| orderFlow | Order flow type, default value: 1 | int | N | 10 | Order flow type. Options: 1=CJ Product Order Flow (create order using CJ variants, default), 2=Store Product Order Flow (supports creating orders using store SKUs, requires Store Product linked to CJ products in My CJ). Launched on 2025-05-19 |
| products | List | Y | 20 | ||
| - vid | CJ variant id | string | N | 50 | vid and sku cannot both be null. When vid is missing, sku will be used to query the CJ variant. If both are provided, they must refer to the same variant and will be validated accordingly. If the customer account has been granted permission to submit non-CJ SKUs, then the vid field is required |
| - sku | CJ variant sku | string | N | 50 | vid and sku cannot both be null. When vid is missing, sku will be used to query the CJ variant. If both are provided, they must refer to the same variant and will be validated accordingly. |
| - storeProductId | Store product id | String | N | 64 | used as the store product's platform product id, saved to the store product record; Launched on 2026-06-02 |
| - storeProductImg | Store product image | String | N | 500 | used as the store product's platform product image, saved to the store product record; Launched on 2026-06-02 |
| - storeProductName | Store product name | String | N | 200 | Used under Store Product Order Flow (orderFlow=2) as this product's title |
| - storeSku | Store SKU | String | N | 60 | Non-CJ SKU, used to identify this product's SKU (distinct from the sku field above, which is used to look up the CJ variant). Recommended under Store Product Order Flow (orderFlow=2), otherwise this product's SKU will be empty |
| - variantOptions | Variant options | String | N | 100 | Textual description of the variant. If there are multiple options, join them yourself with "-" before passing (e.g. "Red-XL") |
| - quantity | quantity | int | Y | 50 | |
| - unitPrice | item pricing | BigDecimal | N | 20 | |
| - storeLineItemId | lineItemId of your store order | string | N | 125 | |
| - podProperties | POD customization information | String | N | 500 | podProperties is a string,1:Pod2.0 Example: [{"areaName":"LogoArea","links":["https://cc-west-usa.oss-us-west-1.aliyuncs.com/9f0b99e6-17ec-4dcd-8916-fc5d644be993_LOGO_NavyBlue.png"],"type":"1"}] 2:Pod3.0 Example:[{"links": ["Production image URL (multiple allowed)"],"effectImgs": ["Rendering image URL (exactly one required)"]}] |
# Return
success
{
"code": 200,
"result": true,
"message": "Success",
"data": {
"orderNumber": "",
"orderId": "123434",
"shipmentOrderId": "",
"iossAmount": "",
"iossTaxHandlingFee": "",
"postageAmount": "",
"productAmount": "",
"productOriginalAmount": "",
"productDiscountAmount": "",
"postageDiscountAmount": "",
"postageOriginalAmount": "",
"totalDiscountAmount": "",
"actualPayment": "",
"orderOriginalAmount": "",
"cjPayUrl": "",
"orderAmount": "",
"logisticsMiss": "",
"productInfoList": [
{
"storeLineItemId": "test-lineItemId-1111",
"lineItemId": "",
"variantId": "",
"isGroup": true,
"quantity":10,
"subOrderProducts": [
{
"lineItemId": "",
"variantId": "",
"quantity": 1
}
]
}
],
"orderStatus": "",
"interceptOrderReasons": [
{
"code": 1001,
"message": ""
}
]
},
"requestId": "9eddf3f5-bd3d-4fae-a4f2-028cbb90db97",
"success": true
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
data information
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| orderId | CJ order id | string | 200 | If the provided product VID is not a CJ SKU, the order id will change, and thus the CJ order id will not be returned. You can monitor the webhook to obtain the latest CJ order id |
| orderNumber | orderNumber | string | 200 | |
| shipmentOrderId | shipment order id | string | 200 | |
| iossAmount | ioss amount | BigDecimal | (18,2) | Unit: $ (USD) |
| iossTaxHandlingFee | ioss tax | BigDecimal | (18,2) | Unit: $ (USD) |
| postageAmount | postage amount | BigDecimal | (18,2) | Unit: $ (USD) |
| productAmount | product amount | BigDecimal | (18,2) | Unit: $ (USD) |
| productOriginalAmount | total amount of products (before discount) | BigDecimal | (18,2) | Unit: $ (USD) |
| productDiscountAmount | product discount amount | BigDecimal | (18,2) | Unit: $ (USD) |
| postageDiscountAmount | postage discount amount | BigDecimal | (18,2) | Unit: $ (USD) |
| postageOriginalAmount | postage amount (before discount) | BigDecimal | (18,2) | Unit: $ (USD) |
| totalDiscountAmount | the total amount of the order after discount | BigDecimal | (18,2) | Unit: $ (USD) |
| actualPayment | the amount actually paid | BigDecimal | (18,2) | Unit: $ (USD) |
| orderOriginalAmount | original order amount | BigDecimal | (18,2) | Unit: $ (USD) |
| cjPayUrl | CJ pay url (deprecated, see the notice at the beginning of this section) | string | 200 | |
| orderAmount | order amount | BigDecimal | 200 | |
| logisticsMiss | logistics missing mark | Boolean | 10 | |
| orderStatus | Order status | string | 10 | Referer Order Status |
| productInfoList | product information | list | ||
| interceptOrderReasons | order interception information | list |
product information
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| storeLineItemId | lineItemId of your store order | string | 125 | |
| lineItemId | lineItemId of CJ order | string | 50 | |
| variantId | variant id | string | 50 | |
| quantity | quantity | int | 20 | |
| isGroup | Main product label | boolean | 10 | |
| isPackaging | Whether this line is a packaging item | boolean | 10 | true means this line was not submitted by you. CJ appended it automatically according to the packaging you linked in My CJ > Connect Packaging.⚠ One exception: when the creation itself fails and CJ finds an existing order under the same orderNumber and echoes it back, this field is always false, and a false here does not mean the line is not a packaging line (that echo path has no product-type information). Use the order-detail endpoint to check packaging in that case.📌 Note this is not the duplicate-submission case — a genuine duplicate orderNumber is rejected outright (ORDER_CODE_EXIST) and never reaches the echo path |
| price | Unit price of this line (after discount) | BigDecimal | (18,2) | In $ (USD). This is the unit price, not the subtotal: line amount = price × quantity. For a packaging line this value is the packaging fee.⚠ Whether the order-level productAmount already includes the packaging fee depends on your account configuration, so do not derive it as "order amount − product amount". Sum price × quantity over the lines where isPackaging is true instead |
| belongToLineItemIds | Line items this packaging belongs to | array | — | Values are the lineItemId of other product lines in this same response, i.e. which product(s) this packaging was added for. One packaging may be shared by several products (or map to all sub-SKUs of a combo), hence an array.⚠ Only populated when isPackaging is true; empty for normal product lines |
| subOrderProducts | combination product | list | 10 | |
| - lineItemId | Unique ID of the order item in CJ | string | 50 | |
| - variantId | variant id | string | 50 | |
| - quantity | quantity | int | 20 |
Order interception information
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | code | int | 50 | |
| message | message | string | 200 |
error
{
"code": 1600100,
"result": false,
"message": "Param error",
"data": null,
"requestId": "323fda9d-3c94-41dc-a944-5cc1b8baf5b1"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
# 1.2 Create Order V3(POST)
- Create order
- Add param platformToken to header, The way to obtain platformToken is the same as the way to obtain CJ Access Token. If not required, the value can be empty. (2025-01-08 update)
cjPayUrl is deprecated
The cjPayUrl payment page redirect address returned with payType=1 (page payment) is deprecated and is no longer maintained. Do not use it in new integrations. Please pay in one of the following ways instead:
payType=2: pay with balance directly while creating the order;payType=3: create the order only, then call "2.3 Pay Balance V2(POST)" yourself to complete the payment.
The field is still returned for backward compatibility with existing integrations, but it is no longer maintained and may stop working or be removed in the future.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/createOrderV3
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/createOrderV3' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'platformToken: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"orderNumber": "1234",
"shippingZip": "123",
"shippingCountry": "123",
"shippingCountryCode": "US",
"shippingProvince": "123",
"shippingCity": "132",
"shippingCounty": "",
"shippingPhone": "111",
"shippingCustomerName": "123213",
"shippingAddress": "123213",
"shippingAddress2": "123213",
"taxId": "123",
"remark": "note",
"email": "",
"consigneeID": "",
"shopAmount": "",
"logisticName": "PostNL",
"fromCountryCode": "CN",
"houseNumber": "123",
"iossType": "",
"platform": "shopify",
"iossNumber": ""
"shopLogisticsType": 1,
"storageId": "201e67f6ba4644c0a36d63bf4989dd70",
"orderFlow": 1,
"products": [
{
"vid": "92511400-C758-4474-93CA-66D442F5F787",
"quantity": 1,
"storeLineItemId": "test-lineItemId-1111"
}
]
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| orderNumber | A unique identifier for the order from CJ partner. | string | Y | 50 | |
| shippingZip | Zip of destination | string | N | 20 | |
| shippingCountryCode | Country code of destination | string | Y | 20 | Referer:Country Code, Please use The two-letter code |
| shippingCountry | Country of destination | string | Y | 50 | |
| shippingProvince | Province of destination | string | Y | 50 | |
| shippingCity | City of destination | string | Y | 50 | |
| shippingCounty | County of destination | String | N | 50 | |
| shippingPhone | Phone number of destination | string | N | 20 | |
| shippingCustomerName | Customer name | string | Y | 50 | |
| shippingAddress | Shipping address of destination | string | Y | 500 | |
| shippingAddress2 | Shipping address 2 of destination | string | N | 500 | |
| houseNumber | House Number | String | N | 20 | |
| String | N | 50 | |||
| taxId | Tax Id | string | N | 20 | |
| remark | Order remark | string | N | 500 | |
| consigneeID | consignee id | string | N | 20 | |
| shopAmount | Order Amount | BigDecimal | N | 20 | |
| logisticName | logistic name | string | Y | 50 | Referer Freight Calculation |
| fromCountryCode | Country code of the shipment from | string | Y | 20 | Referer:Country Code, Please use The two-letter code |
| platform | Platform, Default: Api | String | N | 20 | If this parameter is not passed, the default platform Api will be used. Referer Platforms |
| iossType | IOSS Type | int | N | 20 | IOSS Type, Options: 1=No IOSS(The recipient will be required to pay VAT and other related fees when the order is declared without IOSS.), 2=Declare with my own IOSS(Please ensure that the IOSS provided is valid and is linked to the destination country in the EU. The declaration will proceed without IOSS if the destination country is not linked to a correct IOSS.), 3=Declare with CJ’s IOSS(Declaration with your store order amount is recommended. You will be responsible for the relevant risks if you choose to declare with CJ order amount. CJ’s IOSS is not applicable for orders valued above €150, and the recipient will be required to pay VAT.), Config Page (opens new window) |
| iossNumber | IOSS Number | String | N | 10 | If iossType=3, the value is fixed to CJ-IOSS |
| shopLogisticsType | Shipping mode, default value: 2 | int | N | 20 | Shipping type, Options: 1=Platform Logistics (storageId specified by you, required. When choosing platform logistics mode, the warehouse will start operation after uploading the shipping label. Please upload the shipping label in a timely manner, Upload Shipping and Shipping Label), 2=Seller Logistics (storageId will not be used), 3=Platform Logistics (storageId specified by CJ). Defaults to 2 (merchant logistics) when not provided. If no requirement, please use 2=merchant logistics. Launched on 2025-11-18 |
| storageId | CJ warehouse ID | String | N | 40 | This value is valid when shopLogisticsType=1, Added on 2025-11-18 |
| storeName | Store name | String | N | 50 | If provided, the system will validate that the store name matches an API store in CJ system. If not provided, the order will be assigned to the default API store |
| storeOrderTime | Store order time | Long | N | 20 | Timestamp in seconds. Represents the actual order creation time in the customer's store. If the time is later than the current system time, an error will be returned |
| orderFlow | Order flow type, default value: 1 | int | N | 10 | Order flow type. Options: 1=CJ Product Order Flow (create order using CJ variants, default), 2=Store Product Order Flow (supports creating orders using store SKUs, requires Store Product linked to CJ products in My CJ). Launched on 2025-05-19 |
| isSandbox | Is sandbox order | integer | N | 1 | Default 0. 0-normal order; 1-sandbox order. Regardless of payType value, sandbox orders will automatically use fake/simulated payment and will not generate real charges, real logistics, or fulfillment |
| products | List | Y | 20 | ||
| - vid | CJ variant ID | string | N | 50 | vid and sku cannot both be null. When vid is missing, sku will be used to query the CJ variant. If both are provided, they must refer to the same variant and will be validated accordingly. If the customer account has been granted permission to submit non-CJ SKUs, then the vid field is required |
| - sku | CJ variant sku | string | N | 50 | vid and sku cannot both be null. When vid is missing, sku will be used to query the CJ variant. If both are provided, they must refer to the same variant and will be validated accordingly. |
| - storeProductId | Store product id | String | N | 64 | used as the store product's platform product id, saved to the store product record; Launched on 2026-06-02 |
| - storeProductImg | Store product image | String | N | 500 | used as the store product's platform product image, saved to the store product record; Launched on 2026-06-02 |
| - storeProductName | Store product name (Title) | String | N | 500 | Used under Store Product Order Flow (orderFlow=2) as this product's title |
| - storeSku | Store SKU | String | N | 60 | Non-CJ SKU, used to identify this product's SKU (distinct from the sku field above, which is used to look up the CJ variant). Recommended under Store Product Order Flow (orderFlow=2), otherwise this product's SKU will be empty |
| - variantOptions | Variant options (Variant) | String | N | 200 | Textual description of the variant. If there are multiple options, join them yourself with "-" before passing (e.g. "Red-XL") |
| - quantity | quantity | int | Y | 50 | |
| - unitPrice | item pricing | BigDecimal | N | 20 | |
| - storeLineItemId | lineItemId of your store order | string | N | 125 | |
| - podProperties | POD customization information | String | N | 500 | podProperties is a string,1:Pod2.0 Example: [{"areaName":"LogoArea","links":["https://cc-west-usa.oss-us-west-1.aliyuncs.com/9f0b99e6-17ec-4dcd-8916-fc5d644be993_LOGO_NavyBlue.png"],"type":"1"}] 2:Pod3.0 Example:[{"links": ["Production image URL (multiple allowed)"],"effectImgs": ["Rendering image URL (exactly one required)"]}] |
# Return
success
{
"code": 200,
"result": true,
"message": "Success",
"data": {
"orderNumber": "",
"orderId": "123434',
"shipmentOrderId": "",
"iossAmount": ,
"iossTaxHandlingFee": ,
"iossAmount": ,
"postageAmount": ,
"productAmount": "",
"productOriginalAmount": "",
"productDiscountAmount": "",
"postageDiscountAmount": "",
"postageOriginalAmount": "",
"totalDiscountAmount": "",
"actualPayment": "",
"orderOriginalAmount": "",
"cjPayUrl": "",
"orderAmount": "",
"logisticsMiss": "",
"productInfoList": [
{
"storeLineItemId": "test-lineItemId-1111",
"lineItemId": "",
"variantId": "",
"isGroup": true,
"quantity":10,
"subOrderProducts": [
{
"lineItemId": "",
"variantId": "",
"quantity": ""
}
]
}
],
"orderStatus": "",
"interceptOrderReasons": [
{
"code": 1001,
"message": ""
}
]
},
"requestId": "9eddf3f5-bd3d-4fae-a4f2-028cbb90db97"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
data information
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| orderId | CJ order id | string | 200 | If the provided product VID is not a CJ SKU, the order id will change, and thus the CJ order id will not be returned. You can monitor the webhook to obtain the latest CJ order id |
| orderNumber | customer order number | string | 200 | |
| shipmentOrderId | shipment order id | string | 200 | |
| iossAmount | ioss amount | BigDecimal | (18,2) | Unit: $ (USD) |
| iossTaxHandlingFee | ioss tax | BigDecimal | (18,2) | Unit: $ (USD) |
| postageAmount | postage amount | BigDecimal | (18,2) | Unit: $ (USD) |
| productAmount | product amount | BigDecimal | (18,2) | Unit: $ (USD) |
| productOriginalAmount | total amount of products (before discount) | BigDecimal | (18,2) | Unit: $ (USD) |
| productDiscountAmount | product discount amount | BigDecimal | (18,2) | Unit: $ (USD) |
| postageDiscountAmount | postage discount amount | BigDecimal | (18,2) | Unit: $ (USD) |
| postageOriginalAmount | postage amount (before discount) | BigDecimal | (18,2) | Unit: $ (USD) |
| totalDiscountAmount | the total amount of the order after discount | BigDecimal | (18,2) | Unit: $ (USD) |
| actualPayment | the amount actually paid | BigDecimal | (18,2) | Unit: $ (USD) |
| orderOriginalAmount | original order amount | BigDecimal | (18,2) | Unit: $ (USD) |
| cjPayUrl | CJ pay url (deprecated, see the notice at the beginning of this section) | string | 200 | |
| orderAmount | order amount | BigDecimal | 200 | |
| logisticsMiss | logistics missing mark | Boolean | 10 | |
| orderStatus | order status | string | 10 | Referer Order Status |
| productInfoList | product information | list | ||
| interceptOrderReasons | order interception information | list |
product information
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| storeLineItemId | lineItemId of your store order | String | 125 | |
| lineItemId | Unique ID of the order item in CJ | string | 50 | |
| variantId | variant id | string | 50 | |
| quantity | quantity | int | 20 | |
| isGroup | Main product label | boolean | 10 | |
| isPackaging | Whether this line is a packaging item | boolean | 10 | true means this line was not submitted by you. CJ appended it automatically according to the packaging you linked in My CJ > Connect Packaging.⚠ One exception: when the creation itself fails and CJ finds an existing order under the same orderNumber and echoes it back, this field is always false, and a false here does not mean the line is not a packaging line (that echo path has no product-type information). Use the order-detail endpoint to check packaging in that case.📌 Note this is not the duplicate-submission case — a genuine duplicate orderNumber is rejected outright (ORDER_CODE_EXIST) and never reaches the echo path |
| price | Unit price of this line (after discount) | BigDecimal | (18,2) | In $ (USD). This is the unit price, not the subtotal: line amount = price × quantity. For a packaging line this value is the packaging fee.⚠ Whether the order-level productAmount already includes the packaging fee depends on your account configuration, so do not derive it as "order amount − product amount". Sum price × quantity over the lines where isPackaging is true instead |
| belongToLineItemIds | Line items this packaging belongs to | array | — | Values are the lineItemId of other product lines in this same response, i.e. which product(s) this packaging was added for. One packaging may be shared by several products (or map to all sub-SKUs of a combo), hence an array.⚠ Only populated when isPackaging is true; empty for normal product lines |
| subOrderProducts | combination product | list | 10 | |
| - lineItemId | Unique ID of the order item in CJ | string | 50 | |
| - variantId | CJ variant id | string | 50 | |
| - quantity | quantity | int | 20 |
Order interception information
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | code | int | 50 | |
| message | message | string | 200 |
error
{
"code": 1600100,
"result": false,
"message": "Param error",
"data": null,
"requestId": "323fda9d-3c94-41dc-a944-5cc1b8baf5b1"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
# 1.3 Add Cart
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/addCart
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/addCart' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"cjOrderIdList": ["SD25080109282603297001"]
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| cjOrderIdList | CJ order id | List | Y | 200 | Query |
# Return
success
{
"success": true,
"code": 200,
"message": "Congratulation! Well done!",
"data": {
"successCount": 1,
"addSuccessOrders": [
"SD25080109282603297001"
],
"unInterceptAddressCount": 0,
"interceptOrders": []
}
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
error
{
"code": 1603001,
"result": false,
"message": "order confirm fail",
"data": null,
"requestId": "7dc61955-c0e8-4731-bb9b-393b4fffeaaf"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
# 1.4 Add Cart Confirm (POST)
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/addCartConfirm
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/addCartConfirm' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"cjOrderIdList": ["SD25080109282603297001"]
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| cjOrderIdList | CJ order id | List | Y | 200 | Query |
# Return
success
{
"success": true,
"code": 200,
"message": "Congratulation! Well done!",
"data": {
"successCount": 1,
"submitSuccess": true,
"shipmentsId": "",
"result": 0,
"interceptOrders": []
}
}
success (some orders blocked — no shipmentsId yet)
{
"success": true,
"code": 200,
"message": "Congratulation! Well done!",
"data": {
"successCount": 22,
"submitSuccess": false,
"shipmentsId": null,
"result": 1,
"unMatchOrderCodes": ["SD26091511445596293001"],
"unMatchProductCodes": ["2611020016220645600"],
"interceptOrders": [
{
"orderCode": "SD26091511445596293001",
"interceptReason": [
{ "interceptReasonCode": 1, "simpleTip": "Product removed.", "completeTip": "Please contact your agent for more details." },
{ "interceptReasonCode": 42, "simpleTip": "The selected warehouse is unavailable.", "completeTip": "Please choose another warehouse and place the order again." }
],
"products": [{ "productCode": "2609151144579622402", "productType": "5", "productTip": "Product removed.", "quantity": 2, "sku": "CJYH288349401AZ" }]
},
{
"orderCode": "DP2611020016220642000",
"interceptReason": [
{ "interceptReasonCode": 201, "simpleTip": "Packaging out of stock.", "completeTip": "See 1.20 Proceed From Cart." }
],
"products": [{ "productCode": "2611020016220645600", "productType": "3", "productTip": "Insufficient inventory.", "quantity": 1, "sku": "CJBZ000000001AZ" }]
}
]
}
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| - successCount | Success Count | int | ||
| - submitSuccess | Is the submission successful | boolean | ||
| - shipmentsId | Shipment Order Id | string | Returned only when every order passed; use it as shipmentOrderId for 1.5 | |
| - result | Confirmation result | int | 0 all orders passed; 1 some orders blocked; 2 all orders blocked; 3 all orders were already submitted. If any order is blocked, no shipmentsId is created for the whole batch | |
| - interceptOrders | Blocked orders | List | One item per blocked order; empty when nothing is blocked | |
| -- orderCode | CJ order id | string | ||
| -- interceptReason | Why the order is blocked | List | An order can have more than one reason — check every item | |
| --- interceptReasonCode | Reason code | int | e.g. 201 packaging out of stock, 130 some items fulfilled elsewhere, 121–190 store exceptions, 2 insufficient inventory, 42 warehouse unavailable | |
| --- simpleTip | Short explanation | string | English | |
| --- completeTip | What to do | string | English | |
| -- products | Products of the order | List | Each item: productCode (product line), productType (3 = packaging), productTip, quantity, sku | |
| - unMatchOrderCodes | Orders blocked for reasons other than out-of-stock packaging | List | Pass back to 1.20 Proceed From Cart | |
| - unMatchProductCodes | Out-of-stock packaging lines | List | Pass back to 1.20 Proceed From Cart | |
| requestId | requestId | string | 48 | Flag request for logging errors |
error
{
"code": 1603001,
"result": false,
"message": "order confirm fail",
"data": null,
"requestId": "7dc61955-c0e8-4731-bb9b-393b4fffeaaf"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
# 1.5 Save Generate Parent Order(POST)
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/saveGenerateParentOrder
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/saveGenerateParentOrder' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"shipmentOrderId": "SD25080109282603297001"
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| shipmentOrderId | Shipment Order Id | string | Y | 200 | Query |
Note: CJ coupons are not applied when a parent order is generated through the Open API (no coupon in the account is deducted), so
paymentInformation.couponAmountis always 0.
# Return
success
{
"success": true,
"message": "",
"data": {
"orderMoney": 99.99,
"payExpireTime": "2024-12-31 23:59:59",
"payId": "PAY123456789",
"result": 0,
"submitSuccess": true,
"unMatchOrderCodes": ["ORDER001", "ORDER002"],
"successOrders": ["ORDER003", "ORDER004"],
"unMatchProductCodes": ["PROD001", "PROD002"],
"paymentInformation": {
"actualPayment": 89.99,
"balanceDeduction": 10.00,
"billAmount": 12.50,
"canDeduct": true,
"commodityDiscount": 5.00,
"commodityTotalAmount": 94.99,
"couponAmount": 0.00,
"freight": 5.00,
"iossAmount": 2.50,
"iossNumber": "IOSS123456",
"iossTaxHandlingFee": 0.50,
"iossTaxes": 2.00,
"iossType": 3,
"orderOriginalAmount": 104.99,
"orderProductAmount": 94.99,
"payableAmount": 89.99,
"postageDiscount": 0.00,
"serviceFee": 1.00
},
"interceptOrders": [
]
}
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| - payId | Payment ID | string | Returned when the payment is generated; use it to pay | |
| - unMatchOrderCodes | Orders blocked for reasons other than out-of-stock packaging | List | Pass back to 1.20 Proceed From Cart with this shipmentOrderId | |
| - unMatchProductCodes | Out-of-stock packaging lines | List | Pass back to 1.20 Proceed From Cart with this shipmentOrderId | |
| - interceptOrders | Blocked orders | List | Each item: orderCode and interceptReason[] (interceptReasonCode, simpleTip, completeTip), as in 1.4; an order can have more than one reason | |
| requestId | requestId | string | 48 | Flag request for logging errors |
error
{
"code": 1603001,
"result": false,
"message": "order confirm fail",
"data": null,
"requestId": "7dc61955-c0e8-4731-bb9b-393b4fffeaaf"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
# 1.6 List Order(GET)
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/list?pageNum=1&pageSize=10
# CURL
curl --location --request GET 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/list?pageNum=1&pageSize=10' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| pageNum | Page number | int | N | 20 | Default 1 |
| pageSize | Quantity of results on each page | int | N | 20 | Default 20 |
| orderIds | order id | string[] | N | 100 | |
| shipmentOrderId | Shipment Order Id | string | N | 100 | |
| status | order status | string | N | 200 | default: CANCELLED, values: CREATED,IN_CART,UNPAID,PENDING,PROCESSING,UNSHIPPED,SHIPPED,DELIVERED,CANCELLED,OTHER. PENDING and PROCESSING are sub-statuses of UNSHIPPED |
| paymentDateFrom | Payment time from (inclusive) | string | N | 19 | Format yyyy-MM-dd HH:mm:ss, UTC, same basis as the returned paymentDate. Must be sent together with paymentDateTo |
| paymentDateTo | Payment time to (inclusive) | string | N | 19 | Same as above. The range must not exceed 90 days |
| createDateFrom | Order creation time from (inclusive) | long | N | 13 | UTC epoch milliseconds. Must be sent together with createDateTo; the range must not exceed 90 days |
| createDateTo | Order creation time to (inclusive) | long | N | 13 | Same as above; must not be earlier than createDateFrom |
| storageIds | Sub-warehouse (shipping warehouse) IDs | string[] | N | 20 values, 64 each | Passed like orderIds: storageIds=a&storageIds=b or comma-separated storageIds=a,b. Each value is a storageId returned by this API, passed as is; exact match; orders from any of them are returned. Blank values are ignored, leading/trailing spaces are trimmed and duplicates count once; at most 20 values after cleaning (more returns a parameter error); all blank means no filter. Sending createDateFrom / createDateTo and paymentDateFrom / paymentDateTo as well is recommended. The storageIds filter supports orders paid on or after 2026-11-08 (UTC); not supported with status=CANCELLED |
| areaId | Regional warehouse ID | int | N | 20 | Use the areaId returned by Global Warehouse List /product/globalWarehouseList (e.g. 1=China, 2=US); a positive integer, a single value only; can be combined with storageIds. Sending createDateFrom / createDateTo as well is recommended. Only orders created on or after 2024-09-01 00:00:00 UTC are covered; not supported with status=CANCELLED |
Notes on filtering by sub-warehouse / regional warehouse
- Where the value comes from: each
storageIdsvalue is astorageIdreturned by this API (or by the order detail), passed as is; exact match, up to 20 sub-warehouses per request. ForareaId, use theareaIdreturned by the Global Warehouse List/product/globalWarehouseList; one region per request. - Data coverage: the
storageIdsfilter supports orders paid on or after 2026-11-08 (UTC); also sendpaymentDateFrom/paymentDateTo. TheareaIdfilter only covers orders created on or after 2024-09-01 00:00:00 UTC. Orders outside these ranges may not appear in filtered results (this does not mean there are none). Thedata.noticein the response is authoritative. - Response
notice: when the request containsstorageIds(non-empty after cleaning) orareaId,datacarries an extra English fieldnoticestating the coverage start of the filters used (and, without a creation time range, that only the last year is searched). Without these two parameters the field is not returned and the response is unchanged. - Send an order creation time range as well: when filtering by
storageIds/areaId, also sendcreateDateFrom/createDateTo; without a creation time range (and withoutorderIds/shipmentOrderId), only orders from the last year are covered. - Not supported with
status=CANCELLED(history store); sending both returns a parameter error rather than silently ignoring the filter. AnareaIdthat is not a positive integer also returns a parameter error. - Large result sets: when 10,000 or more orders match the sub-warehouse / regional warehouse filter, or when paging beyond the first 10,000 results (
pageNum × pageSizegreater than 10,000), a parameter error is returned; narrow the time range and query in segments.
Notes on filtering by payment date (important)
- Time zone: the same basis as the returned
paymentDate(UTC), so returned values can be fed straight back for incremental pulls. - Must be sent as a pair: sending only one side returns a parameter error (otherwise the 90-day cap could be bypassed).
- Maximum range 90 days: exceeding it returns a parameter error; pull in segments.
- Unpaid orders are excluded once a payment date filter is supplied.
- Not supported with
status=CANCELLED(history store); sending both returns a parameter error rather than silently ignoring the filter. - Sort order unchanged (creation time descending).
# Return
success
{
"code": 200,
"result": true,
"message": "Success",
"data": {
"pageNum": 1,
"pageSize": 10,
"total": 6859,
"list": [
{
"orderId": "1377085655003308032",
"orderNum": "50166125936666",
"cjOrderId": null,
"shippingCountryCode": "SG",
"shippingProvince": "Singapore",
"shippingCity": "Singapore",
"shippingPhone": "6587997352",
"shippingAddress": "Singapore,07 Anson Tanjong Pagar,79 ANSON ROAD,79 Anson Road #01-01, Phoenix Tower",
"shippingCustomerName": "KUDO KANJI ",
"remark": "",
"orderWeight": 0,
"orderStatus": "CREATED",
"subStatus": null,
"orderAmount": null,
"productAmount": 0,
"postageAmount": null,
"iossTaxes": null,
"iossTaxHandlingFee": null,
"tariff": null,
"logisticsClearanceOperationFee": null,
"currency": "USD",
"logisticName": null,
"trackNumber": null,
"trackingProvider": null,
"createDate": "2021-03-31 00:46:39",
"paymentDate": null,
"productList": null,
"storageId": "201e67f6ba4644c0a36d63bf4989dd70",
"storageName": "Cranbury Warehouse",
"shopId": "1619935922558865408",
"shopName": "My Shopify Store"
}...
]
}
}
When the request contains storageIds or areaId, data also contains notice at the same level as list, for example:
"data": {
"pageNum": 1,
"pageSize": 10,
"total": 2,
"list": [ ... ],
"notice": "storageIds filter supports orders paid on or after 2026-11-08 (UTC); areaId filter only covers orders created on or after 2024-09-01 00:00:00 UTC. Without createDateFrom/createDateTo (and without orderIds/shipmentOrderId), only orders created within the last year are searched."
}
| data field | Definition | Type | Length | Note |
|---|---|---|---|---|
| pageNum | page number | int | 20 | |
| pageSize | page size | int | 20 | |
| total | total count | int | 20 | |
| list | orders | list | see the table below | |
| notice | data coverage notice (English) | string | 500 | Returned only when the request contains storageIds or areaId, mentioning only the filters actually used; absent otherwise |
The four optional fee fields below use USD and two decimal places with HALF_UP rounding. Null or omitted means unavailable; explicit zero means a recorded zero. Duty and clearance handling are already part of freight: do not add them again to postage or the order total. These query fields do not recalculate prices or replace a payment-ID quotation. For applicable IOSS orders, tax plus its handling fee gives the IOSS total; where the rate is 3%, line-level rounding can differ from rounding the order-level VAT total multiplied by 3%. A rounded tax amount cannot determine the declaration base exactly. For CANCELLED history results, these fee fields and currency are null or omitted.
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| orderId | order id | string | 200 | |
| orderNum | order name | string | 200 | |
| cjOrderId | CJ order id | string | 200 | |
| shippingCountryCode | country code | string | 200 | |
| shippingProvince | province | string | 200 | |
| shippingCity | city | string | 200 | |
| shippingAddress | shipping address | string | 200 | |
| shippingCustomerName | shipping name | string | Y | 200 |
| shippingPhone | phone number | string | 200 | |
| remark | order remark | string | 500 | |
| logisticName | logistic name | string | 200 | |
| trackNumber | track number | string | 200 | |
| trackingProvider | tracking provider (logistics service provider) | string | 200 | |
| trackingUrl | tracking URL | string | N | 200 |
| orderWeight | order weight | int | 20 | |
| orderAmount | order amount | BigDecimal | (18,2) | Unit: $ (USD) |
| iossTaxes | Recorded tax excluding handling fee; original VAT for applicable IOSS orders. Non-IOSS orders may contain other recorded taxes. | BigDecimal | (18,2) | USD; nullable |
| iossTaxHandlingFee | Recorded tax handling fee; not recalculated from the order-level tax total. | BigDecimal | (18,2) | USD; nullable |
| tariff | Customs duty recorded in the logistics snapshot. | BigDecimal | (18,2) | USD; nullable |
| logisticsClearanceOperationFee | Customs clearance handling fee, separate from the tax handling fee. | BigDecimal | (18,2) | USD; nullable |
| currency | Currency of these four amounts: USD; not the shop or account display currency. | string | 3 | USD |
| orderStatus | order status | string | 200 | Referer Order Status |
| subStatus | order sub-status | string | 200 | PENDING or PROCESSING when order is UNSHIPPED, null otherwise |
| createDate | create time | string | 200 | |
| paymentDate | pay time | string | 200 | |
| storeCreateDate | Store order creation time | DateTime | 1 | UTC Time, eg: 2025-03-14 13:21:07 |
| isSandbox | Is sandbox order | integer | 1 | 0-no, 1-yes |
| privateOutboundOrder | Whether a private inventory outbound order | boolean | true=private inventory outbound order, false=regular order. Consistent with the webhook order message | |
| productAmount | product amount | BigDecimal | (18,2) | Unit: $ (USD) |
| postageAmount | postage amount | BigDecimal | (18,2) | Unit: $ (USD) |
| storageId | storage id | string | 200 | Added on 2025-11-18; can be put into the request parameter storageIds to filter by sub-warehouse |
| storageName | storage name | string | 200 | Added on 2025-11-18 |
| shopId | shop id | string | 200 | The id of the shop the order belongs to; identical to the shop id returned by getShops, so you can associate the order with a shop. May be null for non-shop orders |
| shopName | shop name | string | 200 | The name of the shop the order belongs to (snapshot at order time), corresponding to name in getShops. May be an old name or empty after the shop is renamed; use shopId to look up the authoritative name via getShops |
error
{
"code": 1600100,
"result": false,
"message": "Param error",
"data": null,
"requestId": "323fda9d-3c94-41dc-a944-5cc1b8baf5b1"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
# 1.7 Query Order(GET)
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/getOrderDetail?orderId=210711100018043276
# CURL
curl --location --request GET 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/getOrderDetail?orderId=210711100018043276&features=f1&features=f2' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
# Request Parameters
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| orderId | order id | string | Y | 200 | support: Custom order id, CJ order id |
| features | features | List<String> | false | 20 | If a feature is passed in, the relevant function will be enabled. If multiple features are required, pass multiple feature parameters |
# Feature enumeration
| Enumeration | Description |
|---|---|
| LOGISTICS_TIMELINESS | Enable querying logistics timeliness. After passing in this feature enumeration, logisticTimelines will be returned in the results |
# Response
success
{
"code": 200,
"result": true,
"message": "Success",
"data": {
"orderId": "210823100016290555",
"orderNum": "api_52f268d40b8d460e82c0683955e63cc9",
"platformOrderId": "6387689586969",
"cjOrderId": null,
"shippingCountryCode": "US",
"shippingProvince": "Connecticut",
"shippingCity": "ftdsr",
"shippingPhone": "43514123",
"shippingAddress": "rfdxf rfdesr",
"shippingCustomerName": "Xu Old",
"remark": null,
"orderWeight": 20,
"orderStatus": "CREATED",
"subStatus": null,
"orderAmount": 4.25,
"productAmount": 0.57,
"postageAmount": 3.68,
"iossTaxes": null,
"iossTaxHandlingFee": null,
"tariff": null,
"logisticsClearanceOperationFee": null,
"currency": "USD",
"logisticName": "CJPacket Ordinary",
"trackNumber": null,
"trackingProvider": "Yun_Standard",
"createDate": "2021-08-23 11:31:45",
"paymentDate": null,
"isComplete":1,
"fromCountryCode":"CN",
"storageId": "201e67f6ba4644c0a36d63bf4989dd70",
"storageName": "Cranbury Warehouse",
"shopId": "1619935922558865408",
"shopName": "My Shopify Store",
"disputeId": null,
"disputeOpenedId": null,
"productList": [
{
"vid": "1392053744945991680",
"quantity": 1,
"sellPrice": 0.57,
"podPropertiesInfo": null,
"lineItemId": "2505170958390976500",
"storeLineItemId": "16045188153625",
"orderNumber": "#1416",
"productionOrderStatus": 1,
"abnormalType": [
6,
9
]
}
]
},
"requestId": "3adccdcb-d41b-4808-996b-c7c5c833d77d"
}
POD order return information
{
"code": 200,
"result": true,
"message": "Success",
"data": {
"orderId": "210823100016290555",
"orderNum": "api_52f268d40b8d460e82c0683955e63cc9",
"cjOrderId": null,
"platformOrderId": "6387689586969",
"shippingCountryCode": "US",
"shippingProvince": "Connecticut",
"shippingCity": "ftdsr",
"shippingPhone": "43514123",
"shippingAddress": "rfdxf rfdesr",
"shippingCustomerName": "Xu Old",
"remark": null,
"orderWeight": 20,
"orderStatus": "CREATED",
"subStatus": null,
"orderAmount": 4.25,
"productAmount": 0.57,
"postageAmount": 3.68,
"iossTaxes": null,
"iossTaxHandlingFee": null,
"tariff": null,
"logisticsClearanceOperationFee": null,
"currency": "USD",
"logisticName": "CJPacket Ordinary",
"trackNumber": null,
"trackingProvider": "Yun_Standard",
"createDate": "2021-08-23 11:31:45",
"paymentDate": null,
"isComplete": 1,
"fromCountryCode": "CN",
"storageId": "201e67f6ba4644c0a36d63bf4989dd70",
"storageName": "Cranbury Warehouse",
"shopId": "1619935922558865408",
"shopName": "My Shopify Store",
"productList": [
{
"vid": "1392053744945991680",
"quantity": 1,
"sellPrice": 0.57,
"lineItemId": "2505170958390976500",
"storeLineItemId": "16045188153625",
"productionOrderStatus": 1,
"abnormalType": [
6,
9
]
"podPropertiesInfo": {
"image": "https://pod-picture.oss-cn.aliyuncs.com/LX/PO-211-12729261699191806-1.jpg",
"isFixedCustom": false,
"podVersion": 3,
"failedList": [],
"effectImgList": [
"https://pod-picture.oss-cn.aliyuncs.com/LX/PO-211-1.jpg?podThumbnailUrl=https%3A%2F%2Fpod-picture.oss-cn.aliyuncs.com%2Fpod%2F250428%2Fpod-picture_oss-cn-211-12729261699191806-1_jpg.1440x1440.webp&podOriginSize=638820&podOriginPxUrl=https%3A%2F%2Fpod-picture.oss-cn-hangzhou.aliyuncs.com%2Fpod_infinity%2F250428%2Fpod-picture_oss-cn-hangzhou_aliyuncs_com_LX_PO-211-12729261699191806-1_jpg.InfinityxInfinity.webp&podOriginPx=1936_1854&podOriginOss=https%3A%2F%2Fpod-picture.oss-cn-hangzhou.aliyuncs.com%2Fpod_origin%2F250428%2Fpod-picture_oss-cn-hangzhou_aliyuncs_com_LX_PO-211-1_jpg.InfinityxInfinity.jpg"
],
"finish": 1,
"customResources": [],
"type": 5,
"customMessgae": {
"podType": 1,
"color": {},
"zone": {
"back": {},
"front": {}
}
},
"productionImgList": [
"https://pod-picture.oss-cn.aliyuncs.com/LX/PO-211-1.jpg?podThumbnailUrl=https%3A%2F%2Fpod-picture.oss.aliyuncs.com%2Fpod%2F250428%2Fpod-picture_oss-cn-hangzhou_aliyuncs_com_LX_PO-211-12729261699191806-1_jpg.1440x1440.webp&podOriginSize=638820&podOriginPxUrl=https%3A%2F%2Fpod-picture.oss-cn-hangzhou.aliyuncs.com%2Fpod_infinity%2F250428%2Fpod-picture_oss-cn-hangzhou_aliyuncs_com_LX_PO-211-12729261699191806-1_jpg.InfinityxInfinity.webp&podOriginPx=1936_1854&podOriginOss=https%3A%2F%2Fpod-picture.oss-cn-hangzhou.aliyuncs.com%2Fpod_origin%2F250428%2Fpod-picture_oss-cn-hangzhou_aliyuncs_com_LX_PO-211-12729261699191806-1_jpg.InfinityxInfinity.jpg"
],
"customDesign": [
{
"img": "https://oss-cf.cjdropshipping.com/product/2025/04/22/01/180af06e-7b7-4662-b975-070203989480.jpg",
"areaNameEn": "",
"printWidth": "50",
"typeName": "",
"type": "1",
"scaleX": "1",
"backImgList": [
{
"color": "1pcs",
"imgSrc": "https://oss-cf.cjdropshipping.com/product/2025/04/22/01/00e2483-b3b2-4873-80ac-e71f4d760e1f.jpg"
},
{
"color": "4pcs",
"imgSrc": "https://oss-cf.cjdropshipping.com/product/2025/04/22/01/0c42181-d63f-49f9-b6d5-d55574027fcb.jpg"
},
{
"color": "10pcs",
"imgSrc": "https://oss-cf.cjdropshipping.com/product/2025/04/22/01/1ae2f95-5484-4d30-a93f-64bc740832d2.jpg"
},
{
"color": "16pcs",
"imgSrc": "https://oss-cf.cjdropshipping.com/product/2025/04/22/01/53ce421-33db-4249-8862-f36ad20083b5.jpg"
},
{
"color": "18pcs",
"imgSrc": "https://oss-cf.cjdropshipping.com/product/2025/04/22/01/245e348-a87b-4196-a3a4-056f6b391301.jpg"
}
],
"printHeight": "50",
"scaleY": "1",
"podType": "4",
"top": "297.99999928474426",
"areaName": "DIY",
"left": "253.99999994039536",
"areaType": "1",
"imgicon": "",
"angle": "0",
"fontSize": 12,
"fontSpace": 0,
"sku": ""
}
]
}
}
]
},
"requestId": "3adccdcb-d41b-4808-996b-c7c5c833d77d"
}
The four optional fee fields below use USD and two decimal places with HALF_UP rounding. Null or omitted means unavailable; explicit zero means a recorded zero. Duty and clearance handling are already part of freight: do not add them again to postage or the order total. These query fields do not recalculate prices or replace a payment-ID quotation. For applicable IOSS orders, tax plus its handling fee gives the IOSS total; where the rate is 3%, line-level rounding can differ from rounding the order-level VAT total multiplied by 3%. A rounded tax amount cannot determine the declaration base exactly.
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| orderId | order id | string | 200 | |
| orderNum | order name | string | 200 | |
| platformOrderId | Shop order ID | string | 200 | |
| cjOrderId | CJ order id | string | 200 | |
| cjOrderCode | CJ order code | string | 200 | |
| fromCountryCode | shipment country code | string | 200 | |
| shippingCountryCode | Recipient country code | string | 200 | |
| shippingProvince | Recipient province | string | 200 | |
| shippingCity | Recipient city | string | 200 | |
| shippingAddress | Recipient address | string | 200 | |
| shippingCustomerName | Recipient name | string | 200 | |
| shippingPhone | Recipient phone number | string | 200 | |
| remark | order remark | string | 500 | |
| logisticName | logistic name | string | 200 | |
| trackNumber | track number | string | 200 | |
| trackingProvider | tracking provider | string | 200 | |
| trackingUrl | tracking URL | string | 200 | |
| disputeId | CJ dispute ID | string | 50 | |
| disputeOpenedId | CJ dispute ID | string | 50 | Same value as disputeId. Since 2026-08-19 this endpoint also returns the field (previously only "1.16 Batch Query Order" did); additive and backward compatible |
| orderWeight | order weight | int | 20 | |
| orderAmount | Order amount | BigDecimal | (18,2) | Unit: $ (USD) |
| iossTaxes | Recorded tax excluding handling fee; original VAT for applicable IOSS orders. Non-IOSS orders may contain other recorded taxes. | BigDecimal | (18,2) | USD; nullable |
| iossTaxHandlingFee | Recorded tax handling fee; not recalculated from the order-level tax total. | BigDecimal | (18,2) | USD; nullable |
| tariff | Customs duty recorded in the logistics snapshot. | BigDecimal | (18,2) | USD; nullable |
| logisticsClearanceOperationFee | Customs clearance handling fee, separate from the tax handling fee. | BigDecimal | (18,2) | USD; nullable |
| currency | Currency of these four amounts: USD; not the shop or account display currency. | string | 3 | USD |
| orderStatus | Order status | string | 200 | Referer Order Status |
| subStatus | Order sub-status | string | 200 | PENDING or PROCESSING when order is UNSHIPPED, null otherwise |
| createDate | Create time | string | 200 | UTC Time |
| paymentDate | Pay time | string | 200 | UTC Time |
| outWarehouseTime | Delivery time | DateTime | 1 | UTC Time, eg: 2025-03-14 13:21:07 |
| storeCreateDate | Store order creation time | DateTime | 1 | UTC Time, eg: 2025-03-14 13:21:07 |
| productAmount | product amount | BigDecimal | (18,2) | Unit: $ (USD) |
| isComplete | Is the order complete? 1: Complete 0: Incomplete | Number | 1 | |
| isSandbox | Is sandbox order | integer | 1 | 0-no, 1-yes |
| storageId | storage id | string | 200 | Added on 2025-11-18 |
| storageName | storage name | string | 200 | Added on 2025-11-18 |
| privateOutboundOrder | Whether a private inventory outbound order | boolean | true=private inventory outbound order, false=regular order. Consistent with the webhook order message | |
| shopId | shop id | string | 200 | The id of the shop the order belongs to; identical to the shop id returned by getShops, so you can associate the order with a shop. May be null for non-shop orders |
| shopName | shop name | string | 200 | The name of the shop the order belongs to (snapshot at order time), corresponding to name in getShops. May be an old name or empty after the shop is renamed; use shopId to look up the authoritative name via getShops |
| productList | Product List | list | 200 | |
| - vid | Variant Id | string | 200 | |
| - quantity | quantity | int | 20 | |
| - sellPrice | Sell Price | BigDecimal | (18,2) | unit:$(USA) |
| - storeLineItemId | The lineItemId of your store order | string | 125 | |
| - lineItemId | Unique ID of the order item in CJ | string | 50 | |
| - orderNumber | Store order number | string | 200 | The store order number this product line belongs to. When one CJ order merges several store orders, the value differs line by line, so you can tell which store order each line of goods comes from; null when not filled in |
| - productionOrderStatus | Production Status | Number | 1 | 1=Pending Order, 2=Pending Production, 3=In Production, 4=Production Completed, 5=Production Abnormality |
| - abnormalType | Abnormal Reason | int[] | 6= Image link error, 9= Production drawings don't match the renderings, 10= Missing hanging ring, 11= Mismatch between die-cutting diagram and printing diagram, 12= uneven edges, 13= letters not connected, 14= Missing order images | |
| - podPropertiesInfo | pod product order return information | Object | ||
| -- effectImgList | Product renderings | List | 200 | |
| -- customResources | Finished product information | List | 200 | |
| -- productionImgList | Production diagram | List | 200 | |
| logisticsTimeliness | Logistics Timeliness | Object | ||
| - logisticsModes | Logistics List | List | ||
| -- logisticsName | Logistics Name | string | DHL Official | |
| -- arrivalTime | Arrival Time (Day) | string | 3-7 Days |
Order Status
| Order Status | Status | remark |
|---|---|---|
| CREATED | order create | create order, wait confirm |
| IN_CART | in cart | wait confirm, api merge this state |
| UNPAID | unpaid | confirm order, CJ order number create |
| PENDING | pending | sub-status of UNSHIPPED: paid, waiting for processing (status code 300-399) |
| PROCESSING | processing | sub-status of UNSHIPPED: order is being processed for shipment (status code 400-499) |
| UNSHIPPED | unshipped | paid, wait for sending (includes both PENDING and PROCESSING) |
| SHIPPED | shipped | in transit, get tracking number |
| DELIVERED | delivered | clients receving |
| CANCELLED | cancelled |
error
{
"code": 1600100,
"result": false,
"message": "Param error",
"data": null,
"requestId": "323fda9d-3c94-41dc-a944-5cc1b8baf5b1"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
# Error code and Message
| Error Code | Message |
|---|---|
| 1600300 | order not found |
| 1600300 | orderId must be not empty |
| 1600300 | The maximum number of features is 20 |
# 1.8 Order Delete(DEL)
Only orders whose status is CREATED (created, not yet added to cart) or IN_CART (in cart) can be deleted. Once an order has been confirmed or moved to a later state (UNPAID, UNSHIPPED, SHIPPED, DELIVERED, CANCELLED, etc.), it cannot be deleted via this endpoint.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/deleteOrder?orderId=210711100018655344
# CURL
curl --location --request DELETE 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/deleteOrder?orderId=210711100018655344' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| orderId | order id | string | Y | 200 | Query |
# Return
success
{
"code": 200,
"result": true,
"message": "Success",
"data": "210711100018655344",
"requestId": "721341bf-abf8-4d8c-b400-1fbdaef79039"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
error
{
"code": 1600100,
"result": false,
"message": "Param error",
"data": null,
"requestId": "323fda9d-3c94-41dc-a944-5cc1b8baf5b1"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
# 1.9 Confirm Order(PATCH)
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/confirmOrder
# CURL
curl --location --request PATCH 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/confirmOrder' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"orderId": "210711100018655344"
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| orderId | order id | string | Y | 200 | Query |
# Return
success
{
"code": 200,
"result": true,
"message": "Success",
"data": "210711100018655344",
"requestId": "721341bf-abf8-4d8c-b400-1fbdaef79039"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
error
{
"code": 1603001,
"result": false,
"message": "order confirm fail",
"data": null,
"requestId": "7dc61955-c0e8-4731-bb9b-393b4fffeaaf"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
# 1.10 Change Order Warehouse
- The warehouse of the orders of the platform logistics can be modified through this interface.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/changeWarehouse
# CURL
curl --location 'http://localhost:8081/api2.0/v1/shopping/order/changeWarehouse' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data '{
"orderCode": "123",
"storageId": "1234"
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| orderCode | order code | string | Y | 200 | Query |
| storageId | storage id | string | Y | 200 | Query |
# Return
success
{
"code": 200,
"result": true,
"message": "Congratulation! Well done!",
"data": true,
"requestId": "c627424a858444ef861484ba8d1bee48",
"success": true
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
error
{
"code": 1603001,
"result": false,
"message": "order query fail",
"data": false,
"requestId": "7dc61955-c0e8-4731-bb9b-393b4fffeaaf"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
# 1.11 Sandbox Simulate Pay(POST)
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/sandbox/simulatePay
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/sandbox/simulatePay' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"orderId": "SD2608161721220010101"
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| orderId | CJ order id | string | N | 200 | CJ order id of the sandbox order, either this or shipmentOrderId |
| shipmentOrderId | Parent order id | string | N | 200 | Batch simulate pay for all sandbox sub-orders, either this or orderId |
Parameter Note: At least one of
orderIdorshipmentOrderIdis required. PassorderIdto simulate pay for a single sub-order; passshipmentOrderIdto batch simulate pay for all sandbox sub-orders under the parent order.Note: When a parent order contains multiple sub-orders, you cannot use
orderIdto simulate pay for a single sub-order. Please useshipmentOrderIdto batch simulate pay for all sub-orders.Scope: Only supports sandbox orders created with
isSandbox=1. This API only simulates payment success and will not generate real charges, real logistics, or fulfillment.
# Return
success
{
"code": 200,
"result": true,
"message": "Success",
"data": true,
"requestId": "9eddf3f5-bd3d-4fae-a4f2-028cbb90db97"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | simulate pay result | boolean | true-success | |
| requestId | requestId | string | 48 | Flag request for logging errors |
# 1.12 Sandbox Update Status(POST)
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/sandbox/updateStatus
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/sandbox/updateStatus' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"orderId": "SD2608161721220010101",
"targetStatus": 400
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| orderId | CJ order id | string | Y | 200 | The CJ order id of the sandbox order |
| targetStatus | Target status code | integer | Y | 20 | Optional: 400(unshipped), 500(shipped), 600(completed), 700(closed) |
Scope: Only supports sandbox orders created with
isSandbox=1. Status update only simulates sandbox order status flow and will not trigger real logistics or fulfillment.
Status Flow Rule: Status can only flow in order: 300→400→500→600→700. Cannot skip or revert.
# Return
success
{
"code": 200,
"result": true,
"message": "Success",
"data": true,
"requestId": "9eddf3f5-bd3d-4fae-a4f2-028cbb90db97"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | update status result | boolean | true-success | |
| requestId | requestId | string | 48 | Flag request for logging errors |
# 1.13 Get Order Optional Logistics(GET)
- Query the optional logistics (shipping methods) currently available for a platform logistics order; the returned
idis passed back to the Modify Order Logistics API. - Only orders still editable (order status ≤ add-to-cart) and already trial-calculated return a non-empty list; paid/shipped orders can no longer change logistics.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/getOrderLogisticsInfo
# CURL
curl --location --request GET 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/getOrderLogisticsInfo?orderCode=DP2605200604000336000' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| orderCode | CJ order code | string | Y | 200 | The cjOrderId returned by the order list API (starts with DP/SD), NOT orderId/orderNum |
# Return
success (the example below is one real logistics item returned during integration testing; the list may contain multiple items)
{
"code": 200,
"result": true,
"message": "Success",
"data": [
{
"id": 2605200604010337400,
"orderCode": "DP2605200604000336000",
"logisticsName": "CJPacket Sensitive M",
"logisticsNameAlias": "",
"postage": 2.93,
"postageDiscountPrice": 2.93,
"basePostage": 2.93,
"remoteAmount": 0,
"packPrice": 0.0,
"serviceAmount": null,
"startCountry": "China",
"arrivalTime": "1-6",
"channelId": 10,
"isChecked": null,
"checkIossSuccess": null,
"taxesFlag": 1,
"taxesType": 3,
"availableTrackingInfo": true,
"remark": "logistics remark",
"hasStock": true
}
],
"requestId": "ba429209d4c74fba8168f5592f1d3932"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | 200 means success, others see Reference error code |
| result | whether the return is normal | boolean | 1 | true=success |
| message | return message | string | 200 | error description on failure, e.g. "The CJ order does not exist." |
| data | optional logistics list | array | array of logistics methods, element structure below | |
| data[].id | logistics base id | long | 20 | passed back as id when modifying logistics; differs per logistics method of the same order |
| data[].orderCode | CJ order code | string | 200 | same as request |
| data[].logisticsName | logistics name | string | 200 | passed back as logisticsName when modifying logistics |
| data[].logisticsNameAlias | logistics alias | string | 200 | for display, may be empty |
| data[].postage | postage (final freight) | decimal | unit: USD | |
| data[].postageDiscountPrice | postage (before discount) | decimal | unit: USD | |
| data[].basePostage | base freight | decimal | unit: USD | |
| data[].remoteAmount | remote area fee | decimal | unit: USD, 0 means none | |
| data[].packPrice | packaging freight | decimal | unit: USD | |
| data[].serviceAmount | service fee | decimal | unit: USD, may be null | |
| data[].startCountry | dispatch origin | string | 50 | e.g. China |
| data[].arrivalTime | estimated arrival time | string | 50 | business-day range, e.g. "1-6" |
| data[].channelId | logistics channel id | long | 20 | |
| data[].isChecked | currently selected | boolean | 1 | may be null (incomplete orders do not return selected state) |
| data[].checkIossSuccess | whether CJ tax agency is supported | boolean | 1 | may be null |
| data[].taxesFlag | tax agency flag | int | 1 | 0-no 1-yes |
| data[].taxesType | tax type | int | 1 | 0-none 1-EU ioss 2-Brazil duty |
| data[].availableTrackingInfo | whether tracking query is supported | boolean | 1 | |
| data[].remark | customer notice | string | 500 | may be empty |
| data[].hasStock | stock availability | boolean | 1 | true-sufficient false-insufficient null-unchecked |
| requestId | requestId | string | 48 | Flag request for logging errors |
# 1.14 Modify Order Logistics(POST)
- Change the logistics (shipping method) of a platform logistics order to the specified one; call Get Order Optional Logistics first to obtain the target
idandlogisticsName. - Only editable-stage orders (order status ≤ add-to-cart) can be modified; paid/shipped orders return
8002 Orders status changed.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/updateLogistics
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/updateLogistics' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data '{
"id": 2605200327040339800,
"orderCode": "SD2605200327030339800",
"logisticsName": "CJPacket Sensitive M",
"from": 1
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| id | logistics base id | long | Y | 20 | the target data[].id from Get Order Optional Logistics |
| orderCode | CJ order code | string | Y | 200 | same as the get API request (cjOrderId) |
| logisticsName | target logistics name | string | N | 200 | the data[].logisticsName from Get Order Optional Logistics; must match id |
| from | operation source | int | N | 1 | default 1, Optional. 0-incomplete order 1-complete order 2-cart; pass 1 (complete order) for orders returned by Query Order List |
# Return
success (real integration-test response; orderCompletedOutputVo is the recalculated complete order, with many fields, omitted here)
{
"code": 200,
"result": true,
"message": "Success",
"data": {
"orderCompletedOutputVo": { "areaEnName": "China Warehouse", "orderQuantity": 2, "...": "recalculated complete order" },
"shoppingCartOrderVo": null,
"abnormalReason": { "logisticsCanUser": false },
"interceptAbnormalReasons": [],
"unInterceptAbnormalReasons": []
},
"requestId": "f82bbfea70c142dd920dc958722d62e6"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | 200 success; 8002 means order status changed and cannot be modified; others see Reference error code |
| result | whether the return is normal | boolean | 1 | true=success |
| message | return message | string | 200 | error description on failure |
| data | modify logistics result | object | result object after successful modification, structure below | |
| data.orderCompletedOutputVo | recalculated complete order | object | contains amount, quantity, area, logistics and other recalculated info (many fields) | |
| data.shoppingCartOrderVo | recalculated cart order | object | returned for from=2 cart scenario, otherwise null | |
| data.abnormalReason | logistics abnormal reason | object | may be empty; e.g. logisticsCanUser=false means the logistics is unavailable | |
| data.interceptAbnormalReasons | hard-intercept abnormal reasons | array | non-empty means hard-intercepted and the change will not take effect | |
| data.unInterceptAbnormalReasons | non-intercept abnormal reasons | array | hint only, does not block the change | |
| requestId | requestId | string | 48 | Flag request for logging errors |
# 1.15 Sandbox Update Track Number(POST)
- Sets or overwrites the tracking number of a sandbox order, so that you can test downstream logic (tracking number retrieval, shipment tracking, fulfillment callback) in the sandbox environment.
- Only supports sandbox orders created with
isSandbox=1. No real label, logistics or fulfillment is generated. - After a successful update, the new value can be read from the
trackNumberfield of 1.7 Query Order(GET) or 1.6 Order List(GET).
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/sandbox/updateTrackNumber
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/sandbox/updateTrackNumber' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"orderId": "SD2606221308140324100",
"trackNumber": "SBXTN2607290902"
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| orderId | CJ order id | string | Y | 200 | The CJ order id of the sandbox order, taken from the create-order response or the order list orderId |
| trackNumber | Tracking number | string | Y | 64 | Any custom string (the sandbox does not validate authenticity or uniqueness), max 64 characters, longer values are rejected by parameter validation |
Scope: Only supports sandbox orders created with
isSandbox=1. The tracking number is written to sandbox order data only. No real label is generated and no real logistics or fulfillment is triggered.Order status requirement: The order must be paid and not closed (i.e. in
UNSHIPPED(300-499),SHIPPED(500) orDELIVERED(600-601) stage). Unpaid (UNPAID) or closed (CLOSED) orders return 819.Repeatable: The API can be called multiple times for the same order, the value of the last call takes effect.
Note: If the order has a forwarder re-label tracking number, the order query API shows that one first. This normally does not happen for sandbox orders.
# Return
success
{
"code": 200,
"result": true,
"message": "Success",
"data": true,
"requestId": "9eddf3f5-bd3d-4fae-a4f2-028cbb90db97"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | 200 success; error codes below; others see Reference error code |
| result | whether the return is normal | boolean | 1 | true=success |
| message | return message | string | 200 | error description on failure |
| data | update track number result | boolean | true-success | |
| requestId | requestId | string | 48 | Flag request for logging errors |
# Common Error Codes
| Code | Message | Description |
|---|---|---|
| 803 | Order not found. | The order id does not exist |
| 811 | Not a sandbox order, operation is not allowed. | Not a sandbox order, updating the tracking number is forbidden (do not call it for production orders) |
| 818 | This sandbox order does not belong to your account. | The sandbox order does not belong to the current API account |
| 819 | Current order status is %s, tracking number can only be updated after payment and before the order is closed. | The order is unpaid or already closed |
| 820 | Order logistics information not found, cannot update tracking number. | The order has no logistics information yet (e.g. logistics has not been calculated) |
| 821 | Tracking number update failed. | Failed to persist the tracking number, please retry |
# Order Status
| Order Status | remark |
|---|---|
| CREATED | Order Created |
| IN_CART | Order in cart |
| UNPAID | Order unpaid |
| PENDING | Sub-status of UNSHIPPED: paid, waiting for processing (status code 300-399) |
| PROCESSING | Sub-status of UNSHIPPED: order is being processed for shipment (status code 400-499) |
| UNSHIPPED | Order has been paid and is currently pending shipment (includes both PENDING and PROCESSING) |
| SHIPPED | Order Shipped and in transit |
| DELIVERED | Package delivered |
| CANCELLED | Order cancelled |
# 1.16 Query Orders In Batch(POST)
Query the details of multiple orders in a single request. Up to 100 order ids per request (raised from 20).
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/getOrderDetailBatch
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/getOrderDetailBatch' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{"orderIds": ["2608010328430327800", "SD2608010328110333600"]}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| orderIds | Order id list | string[] | Y | 100 | Up to 100 per request; accepts CJ order number / store order number / order id; a batch of 20-50 is recommended to keep per-request latency low |
Notes: the response may contain fewer items than requested — ids that cannot be found or do not belong to your account are silently skipped, so match by cjOrderCode; the response is identical to "1.7 Query Order" (since 2026-08-19 the two endpoints return the same response object and the orderStatus basis is unified as well, so you can reuse one deserialization model); the only value difference is that features is not supported, so logisticsTimeliness is always null (use the single-order endpoint for logistics timeliness); platform order ids as a query condition and archived orders are not supported (use the single-order endpoint; note the platformOrderId field is still returned in the response — "not supported" refers to using it as a lookup key); an internal retrieval failure returns code=1600000 (never 200 with an empty array — retry later); rate limit 2 requests/second/account.
Change on 2026-08-19 (two parts — part 1 is backward compatible, part 2 is a value change):
- 8 previously omitted fields are now returned:
trackingUrl,trackingProvider,isSandbox,platformOrderIdat order level andlineItemId,storeLineItemId,productionOrderStatus,abnormalTypeat product level (even though the text above already claimed the structure matched). The value semantics oftrackingUrland the carrier-name mapping are aligned with the single-order endpoint too (previously this endpoint'strackingUrlwas alwaysnull). This part is additive only — no existing field name or meaning changed, so no action is needed for current integrations.- The
orderStatusbasis now matches "1.7": this endpoint previously returned codes 300–399 directly asPENDINGand 400–499 asPROCESSING; it now always returns the aggregateUNSHIPPED, refined bysubStatus=PENDING/PROCESSING(same as "1.7"). If you previously detected unshipped orders on this endpoint viaorderStatus=PENDING/PROCESSING, switch toorderStatus=UNSHIPPED+subStatus. "1.7 Query Order" itself is unchanged.
# Response
success
data is an array; each element has exactly the same fields as the object returned by 1.7 Query Order.
The example below contains two orders: the first one has shipped (so it has a tracking number and a tracking URL),
the second has not shipped yet (so trackNumber / trackingProvider / trackingUrl are empty).
{
"code": 200,
"result": true,
"message": "Success",
"data": [
{
"orderId": "2608010711160329400",
"orderNum": "SJSC2026080104",
"platformOrderId": "6387689586969",
"cjOrderId": "CJ26080146254089558136",
"cjOrderCode": "SD2608010711150328200",
"fromCountryCode": "CN",
"shippingCountryCode": "US",
"shippingProvince": "NJ",
"shippingCity": "Avalon",
"shippingAddress": "384 41st St",
"shippingCustomerName": "jaecob gonzalez",
"shippingPhone": "17872208692",
"remark": null,
"logisticName": "SUNYOU",
"trackNumber": "SY123456789CN",
"trackingProvider": "Yun_Standard",
"trackingUrl": "https://www.sypost.net/search?orderNo=SY123456789CN",
"disputeId": null,
"disputeOpenedId": null,
"orderWeight": 620,
"orderAmount": 77.45,
"productAmount": 60.60,
"postageAmount": 16.85,
"iossTaxes": null,
"iossTaxHandlingFee": null,
"tariff": null,
"logisticsClearanceOperationFee": null,
"currency": "USD",
"orderStatus": "UNSHIPPED",
"subStatus": "PENDING",
"createDate": "2026-08-01 07:11:17",
"paymentDate": "2026-08-01 07:15:00",
"storeCreateDate": null,
"outWarehouseTime": null,
"isComplete": 1,
"isSandbox": 0,
"storageId": "758ad2ef89d12c0eb77695fad97c0aa9",
"storageName": "Jinfeng POD Warehouse",
"privateOutboundOrder": false,
"shopId": "1619935922558865408",
"shopName": "My Shopify Store",
"logisticsTimeliness": null,
"productList": [
{
"vid": "2601140230570658000",
"quantity": 1,
"sellPrice": 12.12,
"storeLineItemId": "16045188153625",
"lineItemId": "2608010711160321900",
"orderNumber": "SJSC2026080104",
"productionOrderStatus": 5,
"abnormalType": [14],
"podPropertiesInfo": null
}
]
},
{
"orderId": "2608010710340327100",
"orderNum": "SJSC2026080103",
"platformOrderId": null,
"cjOrderId": "CJ26080146254089558100",
"cjOrderCode": "SD2608010710330327100",
"fromCountryCode": "CN",
"shippingCountryCode": "FR",
"shippingProvince": null,
"shippingCity": "Paris",
"shippingAddress": "12 Rue de Rivoli",
"shippingCustomerName": "Marie Dupont",
"shippingPhone": null,
"remark": null,
"logisticName": "PostNL",
"trackNumber": "",
"trackingProvider": null,
"trackingUrl": null,
"disputeId": null,
"disputeOpenedId": null,
"orderWeight": 120,
"orderAmount": 3.21,
"productAmount": 0.00,
"postageAmount": 0.74,
"iossTaxes": null,
"iossTaxHandlingFee": null,
"tariff": null,
"logisticsClearanceOperationFee": null,
"currency": "USD",
"orderStatus": "UNSHIPPED",
"subStatus": "PENDING",
"createDate": "2026-08-01 07:10:34",
"paymentDate": "2026-08-01 07:14:58",
"storeCreateDate": null,
"outWarehouseTime": null,
"isComplete": 1,
"isSandbox": 0,
"storageId": null,
"storageName": null,
"privateOutboundOrder": false,
"shopId": "1619935922558865408",
"shopName": "My Shopify Store",
"logisticsTimeliness": null,
"productList": [
{
"vid": "2607230725220652000",
"quantity": 4,
"sellPrice": 0.00,
"storeLineItemId": null,
"lineItemId": "2608010711160321901",
"orderNumber": "SJSC2026080103",
"productionOrderStatus": null,
"abnormalType": null,
"podPropertiesInfo": null
}
]
}
],
"requestId": "3adccdcb-d41b-4808-996b-c7c5c833d77d"
}
The four optional fee fields below use USD and two decimal places with HALF_UP rounding. Null or omitted means unavailable; explicit zero means a recorded zero. Duty and clearance handling are already part of freight: do not add them again to postage or the order total. These query fields do not recalculate prices or replace a payment-ID quotation. For applicable IOSS orders, tax plus its handling fee gives the IOSS total; where the rate is 3%, line-level rounding can differ from rounding the order-level VAT total multiplied by 3%. A rounded tax amount cannot determine the declaration base exactly.
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | Order list | list | Array; may contain fewer items than requested (see Notes above) | |
| requestId | requestId | string | 48 | Flag request for logging errors |
Fields of each element in data:
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| orderId | order id | string | 200 | |
| orderNum | order name | string | 200 | |
| platformOrderId | Shop order ID | string | 200 | Returned normally. "Platform order ids are not supported" refers only to using it as a query condition |
| cjOrderId | CJ order id | string | 200 | |
| cjOrderCode | CJ order code | string | 200 | Match the response back to your request by this field |
| fromCountryCode | shipment country code | string | 200 | |
| shippingCountryCode | Recipient country code | string | 200 | |
| shippingProvince | Recipient province | string | 200 | |
| shippingCity | Recipient city | string | 200 | |
| shippingAddress | Recipient address | string | 200 | |
| shippingCustomerName | Recipient name | string | 200 | |
| shippingPhone | Recipient phone number | string | 200 | |
| remark | order remark | string | 500 | |
| logisticName | logistic name | string | 200 | |
| trackNumber | track number | string | 200 | |
| trackingProvider | tracking provider | string | 200 | null when not filled in by the order |
| trackingUrl | tracking URL | string | 500 | Carrier tracking page + tracking number; falls back to the 17track generic page when the carrier is not configured; null when there is no tracking number |
| disputeId | CJ dispute ID | string | 50 | |
| disputeOpenedId | CJ dispute ID | string | 50 | Same value as disputeId |
| orderWeight | order weight | int | 20 | |
| orderAmount | Order amount | BigDecimal | (18,2) | Unit: $ (USD) |
| iossTaxes | Recorded tax excluding handling fee; original VAT for applicable IOSS orders. Non-IOSS orders may contain other recorded taxes. | BigDecimal | (18,2) | USD; nullable |
| iossTaxHandlingFee | Recorded tax handling fee; not recalculated from the order-level tax total. | BigDecimal | (18,2) | USD; nullable |
| tariff | Customs duty recorded in the logistics snapshot. | BigDecimal | (18,2) | USD; nullable |
| logisticsClearanceOperationFee | Customs clearance handling fee, separate from the tax handling fee. | BigDecimal | (18,2) | USD; nullable |
| currency | Currency of these four amounts: USD; not the shop or account display currency. | string | 3 | USD |
| productAmount | product amount | BigDecimal | (18,2) | Unit: $ (USD) |
| postageAmount | postage amount | BigDecimal | (18,2) | Unit: $ (USD) |
| orderStatus | Order status | string | 200 | Referer Order Status. Unshipped orders return the aggregate UNSHIPPED, refined by subStatus |
| subStatus | Order sub-status | string | 200 | PENDING or PROCESSING when order is UNSHIPPED, null otherwise |
| createDate | Create time | string | 200 | UTC Time |
| paymentDate | Pay time | string | 200 | UTC Time |
| outWarehouseTime | Delivery time | DateTime | 1 | UTC Time, eg: 2025-03-14 13:21:07 |
| storeCreateDate | Store order creation time | DateTime | 1 | UTC Time, eg: 2025-03-14 13:21:07 |
| isComplete | Is the order complete? 1: Complete 0: Incomplete | Number | 1 | |
| isSandbox | Is sandbox order | integer | 1 | 0-no, 1-yes |
| storageId | storage id | string | 200 | |
| storageName | storage name | string | 200 | |
| privateOutboundOrder | Whether a private inventory outbound order | boolean | true=private inventory outbound order, false=regular order | |
| shopId | shop id | string | 200 | The id of the shop the order belongs to; identical to the shop id returned by getShops |
| shopName | shop name | string | 200 | Shop name snapshot at order time; use shopId to look up the authoritative name via getShops |
| logisticsTimeliness | Logistics Timeliness | Object | Always null for this endpoint (features is not supported). Use 1.7 Query Order if you need it | |
| productList | Product List | list | 200 | |
| - vid | Variant Id | string | 200 | |
| - quantity | quantity | int | 20 | |
| - sellPrice | Sell Price | BigDecimal | (18,2) | unit:$(USA) |
| - storeLineItemId | The lineItemId of your store order | string | 125 | |
| - lineItemId | Unique ID of the order item in CJ | string | 50 | |
| - orderNumber | Store order number | string | 200 | The store order number this product line belongs to. When one CJ order merges several store orders, the value differs line by line; null when not filled in |
| - productionOrderStatus | Production Status | Number | 1 | 1=Pending Order, 2=Pending Production, 3=In Production, 4=Production Completed, 5=Production Abnormality; null for non-POD products |
| - abnormalType | Abnormal Reason | int[] | 6= Image link error, 9= Production drawings don't match the renderings, 10= Missing hanging ring, 11= Mismatch between die-cutting diagram and printing diagram, 12= uneven edges, 13= letters not connected, 14= Missing order images | |
| - podPropertiesInfo | pod product order return information | Object | null for non-POD products | |
| -- effectImgList | Product renderings | List | 200 | |
| -- customResources | Finished product information | List | 200 | |
| -- productionImgList | Production diagram | List | 200 |
error
{
"code": 1600100,
"result": false,
"message": "orderIds only within 100 size",
"data": null,
"requestId": "323fda9d-3c94-41dc-a944-5cc1b8baf5b1"
}
| Code | HTTP | message | Cause |
|---|---|---|---|
| 1600300 | 400 | Param error | orderIds is empty or exceeds 100 |
| 1600200 | 200 | Too Many Requests | Rate limit exceeded (2 requests/second/account) |
| 1600000 | 200 | System busy | Internal retrieval failed. This does not mean "no data" — retry later; do not treat it as "these orders are not mine" |
# 1.17 Query Proof Of Delivery(POST)
Retrieve proof-of-delivery (POD) file links for multiple orders. Up to 100 order ids per request (raised from 20).
POD here means Proof of Delivery, unrelated to the print-on-demand artwork endpoint.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/getProofOfDelivery
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/getProofOfDelivery' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{"orderIds": ["SD2604060227360336400"]}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| orderIds | Order id list | string[] | Y | 100 | Up to 100 per request; a batch of 20-50 is recommended to keep per-request latency low |
| Return field | Definition | Type | Note |
|---|---|---|---|
| orderId | CJ order number | string | |
| proofOfDeliveryList | Proof of delivery file URLs | string[] | Empty array (not null) when no proof is available yet |
Notes: file URLs are returned — download and archive them on your side, CJ does not package them server-side; an order id absent from the response means it is not yours or does not exist, while an id present with an empty array means no proof yet (not delivered / carrier has not returned it / channel does not provide one); query after the order reaches DELIVERED; an internal retrieval failure returns code=1600000 (never 200 with an empty array — treat it as "retry later" when archiving automatically); rate limit 2 requests/second/account.
See 1.10 Query Proof Of Delivery in the new docs for the full response example.
# 1.18 Query Order By Code (POST)
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/queryOrderInfo
# CURL
curl --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/queryOrderInfo' \
--header 'CJ-Access-Token: YOUR_ACCESS_TOKEN' \
--header 'Content-Type: application/json' \
--data-raw '{"orderCode":"SD2607130258040329700"}'
# Request Parameters
| Field | Type | Meaning |
|---|---|---|
| orderCode | string | Order code to query; maximum 100 characters. |
# Response
The response structure depends on the order type. For ordinary child orders and child-order results under a CJ parent order, the following fields belong to each returned order object. Special service/dispute order result types are outside this field contract.
The four optional fee fields below use USD and two decimal places with HALF_UP rounding. Null or omitted means unavailable; explicit zero means a recorded zero. Duty and clearance handling are already part of freight: do not add them again to postage or the order total. These query fields do not recalculate prices or replace a payment-ID quotation. For applicable IOSS orders, tax plus its handling fee gives the IOSS total; where the rate is 3%, line-level rounding can differ from rounding the order-level VAT total multiplied by 3%. A rounded tax amount cannot determine the declaration base exactly.
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| iossTaxes | Recorded tax excluding handling fee; original VAT for applicable IOSS orders. Non-IOSS orders may contain other recorded taxes. | BigDecimal | (18,2) | USD; nullable |
| iossTaxHandlingFee | Recorded tax handling fee; not recalculated from the order-level tax total. | BigDecimal | (18,2) | USD; nullable |
| tariff | Customs duty recorded in the logistics snapshot. | BigDecimal | (18,2) | USD; nullable |
| logisticsClearanceOperationFee | Customs clearance handling fee, separate from the tax handling fee. | BigDecimal | (18,2) | USD; nullable |
| currency | Currency of these four amounts: USD; not the shop or account display currency. | string | 3 | USD |
Order-object fragment (other response fields omitted):
{
"iossTaxes": 5.92,
"iossTaxHandlingFee": 0.18,
"tariff": 22.22,
"logisticsClearanceOperationFee": 36.00,
"currency": "USD"
}
# 1.19 Query Order Logs (POST)
Returns the log of one order — the same records you see under Order Logs in My CJ. Free (no points). Rate limit: the per-user QPS of your account level applies (1–6 requests/second, see Access Frequency Restrictions); exceeding it returns HTTP 429 with code 1600200.
Two modes:
- Default (
fullTimelineomitted orfalse): only the Dispatched record(s). This is the original behaviour of this endpoint and is unchanged. - Full timeline (
fullTimeline=true): all log records of the order returned by the log service, newest first, each with the stage it belongs to (nodeName).
Only your own orders can be queried: an order that does not exist and an order that belongs to another account both return 1603100, in both modes.
Change for existing callers (2026-10): before this change the default mode returned the Dispatched record without checking that the order is yours. Orders of other accounts now return
1603100; the output for your own orders is unchanged. If ownership cannot be verified because the order service is unavailable, the call returns1600000(retry later). An order archived long ago is restored automatically on first query; in the rare case the restore fails it returns1603100.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/queryOrderLog
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/queryOrderLog' \
--header 'Content-Type: application/json' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--data-raw '{
"orderCode": "SD2610010000001",
"fullTimeline": true
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| orderCode | CJ order number | string | Y | 100 | e.g. cjOrderCode from 1.7 Query Order. Supported prefixes: SD, DP, DR, HB, J, GX, SH…D, ZF, YJ, SY. Other prefixes (including BF payment numbers) return data: null |
| fullTimeline | Return the full timeline | boolean | N | Default false (Dispatched records only) |
# Return
success (fullTimeline=true)
{
"code": 200,
"result": true,
"message": "Success",
"data": [
{
"id": "1791008470000",
"logContent": "Dispatched. Tracking number: CJPKL7160102171YQ",
"operator": "System",
"node": 5,
"subNode": 1,
"exceptionNode": 0,
"sortKey": "1791008470000_1791008470000",
"createDate": "2026-10-03 06:21:10",
"nodeName": "Dispatch in preparation"
},
{
"id": "1790842805000",
"logContent": "Order paid.",
"operator": "Platform Support (No.23121)",
"node": 2,
"subNode": 1,
"exceptionNode": 0,
"sortKey": "1790842805000_1790842805000",
"createDate": "2026-10-01 08:20:05",
"nodeName": "Payment"
}
],
"requestId": "0b1c2d3e-4f5a-6b7c-8d9e-0f1a2b3c4d5e"
}
| Field | Definition | Type | Note |
|---|---|---|---|
| id | Log record ID | string | |
| logContent | Log text (EN) | string | Same text as in My CJ |
| operator | Who did it | string | Same text as in My CJ: your account name (Name (Sub-account) for a sub-account), Platform Support (No.<staff number digits>) (e.g. Platform Support (No.23121)) or Platform Support for CJ staff, System or System (Auto Payment) for automatic steps; null for some old records |
| node / subNode | Stage / step code | int | For sorting and grouping only |
| exceptionNode | Reserved | int | Currently always 0 |
| sortKey | Sort key | string | <time in ms>_<id>; records are already returned newest first |
| createDate | Time | string | UTC yyyy-MM-dd HH:mm:ss |
| nodeName | Stage name | string | Full timeline only; null in the default mode and for ZF / YJ / SY orders |
The default mode returns the same fields without nodeName.
error
{
"code": 1603100,
"result": false,
"message": "Order not found, please check the CJ order id",
"data": null,
"requestId": "0b1c2d3e-4f5a-6b7c-8d9e-0f1a2b3c4d5e"
}
| Code | Meaning | What to do |
|---|---|---|
| 1603100 | Order not found, or not yours | Check the order number |
| 1600000 | Ownership could not be verified, or (full timeline only) the log service failed. In the default mode a log-service failure still returns an empty list, as before | Retry later; contact your agent with the requestId if it persists |
# 1.20 Proceed From Cart (POST)
The API version of Proceed in My CJ. When 1.4 Add Cart Confirm or 1.5 Save Generate Parent Order blocks some orders, call this endpoint once with the unMatchOrderCodes and unMatchProductCodes of that response: the out-of-stock packaging is removed, the failed orders are left out, and the rest continue together — exactly as clicking Proceed in My CJ. Free (no points). Rate limit: 2 requests/second; exceeding it returns HTTP 429 with code 1600200.
| Where it was blocked | Pass | What this endpoint does | Next step |
|---|---|---|---|
| Add Cart Confirm | cjOrderIdList (the orders you confirmed together) + unMatchOrderCodes + unMatchProductCodes | Removes the out-of-stock packaging (unMatchProductCodes); leaves the failed orders (unMatchOrderCodes) out — they stay in the cart; confirms all remaining orders again together, so they get one shipmentsId | stillBlocked: false → generate the payment with shipmentsId. stillBlocked: true with nextAction = this endpoint → call it again with cjOrderIdList = remainingOrderCodes and the values in confirmResult (they may be empty). stillBlocked: true with nextAction: null → none of the remaining orders can continue now: handle them by their intercept reasons |
| Save Generate Parent Order | shipmentOrderId + unMatchOrderCodes + unMatchProductCodes | Moves the failed orders out of the payment (back to the cart) and removes the out-of-stock packaging, in one call. The previous payment is cancelled; the shipmentOrderId stays the same | Call Save Generate Parent Order again with the same shipmentOrderId to get a new payment |
- Handle one batch at a time per account: while a call is still running, another call from the same account at the same step returns
1600000"The order is being processed. Please retry later." — wait a few seconds and retry. - Pass the two lists exactly as returned by the latest call above.
unMatchProductCodescan only contain out-of-stock packaging of your orders reported there. - Orders left out stay in the cart: handle them by their intercept reason (for store exceptions, see 1.21) and confirm them later.
- At Add Cart Confirm, if only warnings blocked the orders (both lists empty), calling this endpoint with empty lists confirms them anyway, the same as Proceed in My CJ.
- After a payment was generated, the call waits until CJ finishes (normally a few seconds, at most about 30 seconds). If it returns "still being processed", wait a moment and call it again with the same values: what was already done counts as done, and it tells you to generate the payment again.
# Handling it in your program
Every response tells your program what to do next — no need to read message:
r = addCartConfirm(orders)
if r.data.shipmentsId: go to PAYMENT
if r.data.unMatchOrderCodes contains every order: handle each order by its interceptReason; stop
batch = orders; o = r.data.unMatchOrderCodes; p = r.data.unMatchProductCodes
loop:
x = proceedFromCart(cjOrderIdList = batch, unMatchOrderCodes = o, unMatchProductCodes = p)
if x.code == 1600000: wait a few seconds, send the same call again
if x.code != 200: stop and follow x.message
handle x.data.excludedOrderCodes later by their interceptReason
if x.data.stillBlocked == false: shipmentsId = x.data.shipmentsId; go to PAYMENT
if x.data.nextAction == null: handle x.data.remainingOrderCodes by their interceptReason; stop
batch = x.data.remainingOrderCodes; o = x.data.confirmResult.unMatchOrderCodes; p = x.data.confirmResult.unMatchProductCodes
PAYMENT:
s = saveGenerateParentOrder(shipmentsId)
while s.data.interceptOrders is not empty:
if s.data.unMatchOrderCodes and s.data.unMatchProductCodes are both empty: follow completeTip; stop
x = proceedFromCart(shipmentOrderId = shipmentsId, unMatchOrderCodes = s.data.unMatchOrderCodes, unMatchProductCodes = s.data.unMatchProductCodes)
(1600000: wait a few seconds, send the same call again; other errors: stop and follow x.message)
s = saveGenerateParentOrder(shipmentsId)
pay with s.data.payId
- Set your HTTP timeout to at least 60 seconds. If a call times out, send the same call again: what was already done counts as done (if the orders were already confirmed together, you get their
shipmentsId). - For a large batch, the call may stop after removing the packaging and return
stillBlocked: truewith empty lists inconfirmResult, to stay within the time limit. The loop above handles it: the next call confirms the orders.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/proceedFromCart
# CURL
# Blocked at Add Cart Confirm
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/proceedFromCart' \
--header 'Content-Type: application/json' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--data-raw '{
"cjOrderIdList": ["DP2609231209550327300", "DP2609231209590338200", "DP2609231210040339400"],
"unMatchOrderCodes": ["DP2609231209550327300"],
"unMatchProductCodes": []
}'
# Blocked at Save Generate Parent Order
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/proceedFromCart' \
--header 'Content-Type: application/json' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--data-raw '{
"shipmentOrderId": "CJ26110546239662110016",
"unMatchOrderCodes": ["DP2609231210180334500"],
"unMatchProductCodes": ["2609231210170332301", "2609231210150325501", "2609231210170332300", "2609231210150325500"]
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| cjOrderIdList | Orders you confirmed together | list<string> | Y (Add Cart Confirm) | 200 items | Same as cjOrderIdList of Add Cart Confirm. Pass either this or shipmentOrderId |
| shipmentOrderId | Payment (parent order) ID | string | Y (Save Generate Parent Order) | 200 | Same as shipmentOrderId of Save Generate Parent Order |
| unMatchOrderCodes | Failed orders | list<string> | N | 200 items | From the latest response; left out of the batch / moved out of the payment |
| unMatchProductCodes | Out-of-stock packaging lines | list<string> | N | 1000 items | From the latest response; removed |
# Return
success (blocked at Add Cart Confirm)
{
"code": 200,
"result": true,
"message": "Success",
"data": {
"removedProductCodes": [],
"affectedOrders": [],
"excludedOrderCodes": ["DP2609231209550327300"],
"remainingOrderCodes": ["DP2609231210040339400", "DP2609231209590338200"],
"confirmResult": { "result": 0, "shipmentsId": "CJ26110546239661523362", "unMatchOrderCodes": [], "unMatchProductCodes": [], "interceptOrders": [] },
"shipmentsId": "CJ26110546239661523362",
"stillBlocked": false,
"nextAction": "POST /shopping/order/saveGenerateParentOrder",
"message": "The orders in remainingOrderCodes were confirmed together (shipmentsId). Generate the payment with POST /shopping/order/saveGenerateParentOrder. The orders in excludedOrderCodes were left out and stay in the cart; handle them by their intercept reasons."
},
"requestId": "0b1c2d3e-4f5a-6b7c-8d9e-0f1a2b3c4d5e"
}
| Field | Definition | Type | Note |
|---|---|---|---|
| removedProductCodes | Packaging lines removed | list<string> | |
| affectedOrders | Orders whose packaging was removed | list | Each item has orderId, removedProductCodes, remainingProductCodes |
| excludedOrderCodes | Failed orders | list<string> | Add Cart Confirm: left out, still in the cart. Save Generate Parent Order: moved out of the payment, back to the cart |
| remainingOrderCodes | Orders that continue | list<string> | Add Cart Confirm: confirmed again together. Save Generate Parent Order: still in the payment |
| confirmResult | Result of confirming the remaining orders again | object | Add Cart Confirm only; same structure as data of Add Cart Confirm |
| shipmentsId | Payment (parent order) ID | string | Use it as shipmentOrderId for Save Generate Parent Order. Add Cart Confirm: only when all remaining orders passed |
| stillBlocked | Not finished yet | boolean | Always returned. false: done, follow nextAction. true: some orders are still blocked, or (large batch) the remaining orders will be confirmed by the next call |
| nextAction | The endpoint to call next | string | POST /shopping/order/proceedFromCart or POST /shopping/order/saveGenerateParentOrder; null with stillBlocked: true means calling again won't help — handle the remaining orders by their intercept reasons |
| message | What happened and what to do next | string | English |
error
{
"code": 1600300,
"result": false,
"message": "unMatchProductCodes must be the out-of-stock packaging returned in unMatchProductCodes by the latest addCartConfirm for these orders.",
"data": null,
"requestId": "0b1c2d3e-4f5a-6b7c-8d9e-0f1a2b3c4d5e"
}
| Code | Meaning | What to do |
|---|---|---|
| 1600300 | The values don't match the latest response (not your out-of-stock packaging, failed orders not in the batch / payment, all orders left out), an order is not in the expected state, or the payment is already paid | Follow message; call Add Cart Confirm / Save Generate Parent Order again and pass its values, or handle it in My CJ |
| 1603001 | CJ reported success but the change didn't take effect | Handle it in My CJ, then generate the payment again |
| 1600000 | The order is being processed, the removal is still running, or the automatic confirmation failed | Retry later as message says |
| 1603100 | Order or payment not found, or not yours | Check the order numbers / shipmentOrderId |
# 1.21 Query Store Exception (POST)
The API version of the Recover dialog in My CJ, read-only: shows what changed in your store order and what each available action will do. Free (no points). Rate limit: 5 requests/second.
Use it for orders blocked by a store exception — intercept codes 121, 122, 123, 130, 140, 150, 160, 170, 180, 190 returned by 1.3 Add Cart or 1.4 Add Cart Confirm. Only orders not yet submitted (CREATED) or in the cart without a generated payment (IN_CART) can be handled through the API; after a payment was generated, handle the store exception in My CJ.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/storeAbnormal/detail
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/storeAbnormal/detail' \
--header 'Content-Type: application/json' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--data-raw '{
"orderId": "DP26110202343006518001"
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| orderId | CJ order number | string | Y | 100 | cjOrderCode |
# Return
success
{
"code": 200,
"result": true,
"message": "Success",
"data": {
"orderId": "DP26110202343006518001",
"orderStatus": "IN_CART",
"abnormalSubType": "202",
"abnormalDescription": "Some items in your store order can no longer be fulfilled (fulfillable quantity is 0), for example they were already fulfilled elsewhere.",
"actions": [
{
"action": "PROCEED",
"result": "ITEMS_REMOVED",
"irreversible": false,
"description": "The order is refreshed from your store and the items with 0 fulfillable quantity are removed; the other items stay and can be fulfilled. Changes you made in CJ (such as the shipping method) may be overwritten, so check them before paying."
}
],
"nextAction": "POST /shopping/order/storeAbnormal/resolve",
"message": "Choose one of the actions and call POST /shopping/order/storeAbnormal/resolve with this orderId, the action and abnormalSubType 202. Read each action's description first: it tells you what happens to the order."
},
"requestId": "0b1c2d3e-4f5a-6b7c-8d9e-0f1a2b3c4d5e"
}
| Field | Definition | Type | Note |
|---|---|---|---|
| orderId | CJ order number | string | |
| orderStatus | Order status | string | CREATED / IN_CART |
| abnormalSubType | Store exception subtype | string | Pass it back unchanged to Resolve Store Exception |
| abnormalDescription | What changed in your store order | string | English |
| actions | Available actions | list | Empty means it can't be handled through the API; message explains, handle it in My CJ |
| actions[].action | Action | string | PROCEED / DELETE (the Proceed / Delete buttons in My CJ) |
| actions[].result | What the action does | string | ITEMS_REMOVED: items with 0 fulfillable quantity are removed; ORDER_UPDATED_FROM_STORE: the order is refreshed from your store; FLAG_CLEARED: only the exception mark is removed, products unchanged; MOVED_TO_TRASH: the order is moved to Trash |
| actions[].irreversible | Can't be undone | boolean | true: the order can't be restored from Trash |
| actions[].description | What happens to the order | string | English |
| nextAction | The endpoint to call next | string | null when it must be handled in My CJ |
| message | What to do next | string | English |
| Code | Meaning | What to do |
|---|---|---|
| 1600300 | The order has no store exception, is not a store order, or its state isn't supported (for example, a payment was generated) | Handle it in My CJ if needed |
| 1600000 | The order or its store exception couldn't be read | Retry later |
| 1603100 | Order not found, or not yours | Check the order number |
# 1.22 Resolve Store Exception (POST)
Runs the action you chose from 1.21 Query Store Exception — the same as clicking Proceed or Delete in the My CJ Recover dialog. Free (no points). Rate limit: 2 requests/second.
- Always read the actions from Query Store Exception first: some actions move the order to Trash, and some of those can't be undone.
- Pass back the
abnormalSubTypeyou saw. If the store order changed again in the meantime, nothing is done and you're asked to check again. - The result is confirmed by reading the order again; when it can't be confirmed you get
1600000and should check with Query Store Exception before doing anything else.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/storeAbnormal/resolve
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/storeAbnormal/resolve' \
--header 'Content-Type: application/json' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--data-raw '{
"orderId": "DP26110202343006518001",
"action": "PROCEED",
"abnormalSubType": "202"
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| orderId | CJ order number | string | Y | 100 | |
| action | Chosen action | string | Y | PROCEED or DELETE; must be in actions of Query Store Exception | |
| abnormalSubType | Subtype from Query Store Exception | string | Y | 20 | Pass back unchanged |
# Return
success
{
"code": 200,
"result": true,
"message": "Success",
"data": {
"orderId": "DP26110202343006518001",
"orderStatus": "IN_CART",
"result": "ITEMS_REMOVED",
"removedProductCodes": ["2611020234300651800"],
"remainingProductCodes": ["2611020234300651801"],
"stillBlocked": false,
"nextAction": "POST /shopping/order/addCartConfirm",
"message": "Store exception resolved. The order is refreshed from your store and the items with 0 fulfillable quantity are removed; the other items stay and can be fulfilled. Changes you made in CJ (such as the shipping method) may be overwritten, so check them before paying."
},
"requestId": "0b1c2d3e-4f5a-6b7c-8d9e-0f1a2b3c4d5e"
}
| Field | Definition | Type | Note |
|---|---|---|---|
| orderId | CJ order number | string | |
| orderStatus | Order status after processing | string | TRASH when moved to Trash |
| result | What was done | string | Same values as actions[].result |
| removedProductCodes | Lines removed from the order | list<string> | Not returned when moved to Trash |
| remainingProductCodes | Lines left in the order | list<string> | Not returned when moved to Trash |
| stillBlocked | The order has another store exception | boolean | true: call Query Store Exception again |
| nextAction | The endpoint to call next | string | e.g. POST /shopping/order/addCartConfirm / addCart; null when nothing is needed or it must be handled in My CJ |
| message | What happened and what to do next | string | English |
| Code | Meaning | What to do |
|---|---|---|
| 1600300 | The store exception changed since you checked it, the action isn't available, the exception can't be handled through the API, or the order state changed | Call Query Store Exception again, or handle it in My CJ |
| 1603001 | The action didn't take effect, or CJ moved the order to Trash instead (for example, a duplicated store order) | Handle it in My CJ as message says |
| 1600000 | The result couldn't be confirmed, the order is being processed, or CJ couldn't release the reserved inventory | Check with Query Store Exception before retrying |
| 1603100 | Order not found, or not yours | Check the order number |
# 2 Payment
# 2.1 Get Balance(GET)
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/pay/getBalance
# CURL
curl --location --request GET 'https://developers.cjdropshipping.com/api2.0/v1/shopping/pay/getBalance' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
# Return
success
{
"code": 200,
"result": true,
"message": "Success",
"data": {
"amount": 87247.32,
"noWithdrawalAmount": null,
"freezeAmount": null
},
"requestId": "36fc030a-a110-4318-bc83-f39f9d3e5484"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| noWithdrawalAmount | Bonus amount | BigDecimal | (18,2) | Unit: $ (USD) |
| freezeAmount | Frozen amount | BigDecimal | (18,2) | Unit: $ (USD) |
| amount | Amount | BigDecimal | (18,2) | Unit: $ (USD) |
error
{
"code": 1600100,
"result": false,
"message": "Param error",
"data": null,
"requestId": "323fda9d-3c94-41dc-a944-5cc1b8baf5b1"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
# 2.2 Pay Balance(POST)
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/pay/payBalance
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/pay/payBalance' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"orderId": "12"
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| orderId | Order id | string | Y | 200 |
Sandbox Note: If the order is a sandbox order (isSandbox=1), balance payment will use fake/simulated payment without real charges.
Note: When a parent order contains multiple sub-orders, you cannot use this API to pay by a single
orderId. Please use the "Pay Balance V2" API withshipmentOrderIdinstead.
# Return
success
{
"code": 200,
"result": true,
"message": "Success",
"data": null,
"requestId": "7dbe69b9-dd82-4ee3-907c-a6fca833e3ce"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
error
{
"code": 1600100,
"result": false,
"message": "Param error",
"data": null,
"requestId": "323fda9d-3c94-41dc-a944-5cc1b8baf5b1"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
# 2.3 Pay Balance V2(POST)
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/pay/payBalanceV2
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/pay/payBalanceV2' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"shipmentOrderId": "12",
"payId": "12"
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| shipmentOrderId | Shipment order Id | string | Y | 200 | |
| payId | PayId | String | N | 200 | Optional, system will auto-generate if not provided |
Sandbox Note: If all sub-orders under the parent order are sandbox orders (isSandbox=1), payBalanceV2 will automatically use sandbox simulated payment without real charges. Sandbox orders and normal orders are not allowed to be in the same parent order.
# Return
success
{
"code": 200,
"result": true,
"message": "Success",
"data": null,
"requestId": "7dbe69b9-dd82-4ee3-907c-a6fca833e3ce"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
error
{
"code": 1600100,
"result": false,
"message": "Param error",
"data": null,
"requestId": "323fda9d-3c94-41dc-a944-5cc1b8baf5b1"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
# 2.4 Query Billing History(POST)
Returns the wallet billing history of the account that owns the CJ-Access-Token. The data is the same as My CJ → Wallet → Billing History; records are sorted by createDate in descending order.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/wallet/billingHistory
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/wallet/billingHistory' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"pageNum": 1,
"pageSize": 10,
"startDay": "2026-09-01",
"endDay": "2026-09-24",
"tradeTypeList": [1, 2]
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| pageNum | Page number | int | N | 20 | Default 1, minimum 1 |
| pageSize | Page size | int | N | 20 | Default 10, range 1~100 |
| startDay | Start date | string | N | 10 | yyyy-MM-dd, UTC natural day, inclusive |
| endDay | End date | string | N | 10 | yyyy-MM-dd, UTC natural day, inclusive. When both dates are given, startDay must not be after endDay and the range must not exceed 366 days |
| orderId | CJ order number | string | N | 64 | Only records of this order |
| tradeTypeList | Transaction types | list<int> | N | 21 items | Values 1~21, see the tradeType table below; omit to query all types |
The customer is always the owner of the
CJ-Access-Token. The request body does not accept any customer identity field.
# Return
success
{
"code": 200,
"result": true,
"message": "Success",
"data": {
"pageNum": 1,
"pageSize": 10,
"total": 829,
"list": [
{
"id": "2096159889473802240",
"cjOrderId": "CJ26090546257798809591",
"createDate": "2026-09-05T08:53:57",
"typeDesc": "Order Payment",
"paymentTypeDesc": "Balance",
"copeMoney": 23.30,
"amount": "-$23.30",
"status": "1",
"statusDesc": "Success",
"afterTransactionMoney": 262035.18,
"currentBalance": "$262,035.18",
"showCurrency": null,
"showCurrencySymbol": null,
"showCurrencyTradeAmount": null,
"showExchangeRate": null,
"image": null,
"message": null,
"storeDisplay": "Shopify-My Store",
"account": null
}
]
},
"requestId": "7dbe69b9-dd82-4ee3-907c-a6fca833e3ce"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| pageNum | Page number | int | 20 | |
| pageSize | Page size | int | 20 | |
| total | Total records | long | 20 | |
| list | Records | list | ||
| id | Record id | string | 32 | |
| cjOrderId | CJ order number | string | 64 | Null when the record is not related to an order |
| createDate | Created time | string | 19 | yyyy-MM-dd'T'HH:mm:ss, UTC |
| typeDesc | Transaction type | string | 64 | Same text as the Type column on My CJ, see the tradeType table below |
| paymentTypeDesc | Payment method | string | 64 | For example Balance / PayPal; may be null |
| copeMoney | Amount | BigDecimal | (18,2) | Unit: $ (USD), always non-negative |
| amount | Amount as displayed | string | 32 | Same as My CJ, with sign and currency symbol, for example -$23.30 / +$8.79 |
| status | Status | string | 1 | 0 Pending, 1 Success, 2 Failed, 3 Frozen, 4 Failed(Canceled) |
| statusDesc | Status name | string | 64 | Same text as the Status column on My CJ. A pending payment cancelled by the customer reads Failed(Canceled) while status stays 2 |
| afterTransactionMoney | Balance after the transaction | BigDecimal | (18,2) | May be null for some historical records. When showExchangeRate is present, the value is converted to showCurrency |
| currentBalance | Balance after the transaction as displayed | string | 32 | For example $262,035.18; null when afterTransactionMoney is null |
| showCurrency | Display currency | string | 3 | Null when the record has no display currency |
| showCurrencySymbol | Display currency symbol | string | 8 | Same as above |
| showCurrencyTradeAmount | Amount in display currency | BigDecimal | (18,2) | Same as above |
| showExchangeRate | Exchange rate from USD to the display currency | BigDecimal | (18,6) | Same as above |
| image | Transfer slip | string | — | Same as the Transfer Slip column of the Billing History export. Multiple images are separated by commas; some values have no https:// prefix (My CJ adds it when displaying). Null when there is none |
| message | Message | string | — | Same as the Message column of the Billing History export: the remark recorded on the transaction, e.g. the remark entered by CJ staff when they adjust the balance. Returned as recorded, not translated; null when empty. For Credit Loan records, a loan number is shown as Loan No: …, and -- is returned when there is no remark |
| storeDisplay | Store info | string | — | Same as the Store Info column of the Billing History export: store type-store name, multiple stores separated by commas. Null when the record is not related to a store |
| account | Account | string | — | Same as the Account column of the Billing History export: the account actually used for the payment, available for some payment methods only. Values in a standard email format are masked, e.g. zha***n@example.com; other values are returned as recorded |
tradeType
| tradeType | typeDesc |
|---|---|
| 1 | Order Payment |
| 2 | Top-up |
| 3 | Top-up with Gift Card |
| 4 | Charging Benefit |
| 5 | Deposit |
| 6 | Withdrawal |
| 7 | Order Refund |
| 8 | Order Refund: Sold Out |
| 9 | System Refund |
| 10 | System Deduction |
| 11 | Affiliate Withdrawal |
| 12 | Deposit Refund |
| 13 | CJ PRIME |
| 14 | Order Payment-Shipping Cost |
| 15 | Paid Sourcing |
| 16 | Paid Customization |
| 17 | Freight Payment |
| 18 | Paid Services |
| 19 | AI Credits Top-up |
| 20 | Credit Loan |
| 21 | Store Purchase |
tradeTypeListfilters by these types. A refund processed by the system may be returned under7while itstypeDescreadsSystem Refund, the same as My CJ.21(Store Purchase) is a payment for products bought in the CJ Store; since October 22, 2026 it is recorded as its own type and no longer counted under1(Order Payment), while such payments made before then remain under1; if your query range includes October 22, 2026 or earlier, include1as well.
error
{
"code": 1600300,
"result": false,
"message": "startDay must not be after endDay",
"data": null,
"requestId": "323fda9d-3c94-41dc-a944-5cc1b8baf5b1"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code. 1600300 invalid parameter; 1610001 wallet query failed, please retry later |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
# 2.5 Query Balance History(POST)
Returns the balance change records of the account that owns the CJ-Access-Token. The data is the same as My CJ → Wallet → Balance History (the transactions that change the CJ wallet balance); records are sorted by createDate in descending order.
Unlike 2.4 Query Billing History, balance history records have no record id and no balance after the transaction. Use 2.4 if you need them.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/wallet/balanceHistory
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/wallet/balanceHistory' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"pageNum": 1,
"pageSize": 10,
"startDay": "2026-09-01",
"endDay": "2026-09-24"
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| pageNum | Page number | int | N | 20 | Default 1, minimum 1 |
| pageSize | Page size | int | N | 20 | Default 10, range 1~100 |
| startDay | Start date | string | N | 10 | yyyy-MM-dd, UTC natural day, inclusive |
| endDay | End date | string | N | 10 | yyyy-MM-dd, UTC natural day, inclusive. When both dates are given, startDay must not be after endDay and the range must not exceed 366 days |
| orderId | CJ order number | string | N | 64 | Only records of this order |
The customer is always the owner of the
CJ-Access-Token. The request body does not accept any customer identity field.
# Return
success
{
"code": 200,
"result": true,
"message": "Success",
"data": {
"pageNum": 1,
"pageSize": 10,
"total": 742,
"list": [
{
"cjOrderId": "SD2609050851390335200",
"createDate": "2026-09-05T09:34:24",
"typeDesc": "Order Refund",
"copeMoney": 8.79,
"amount": "+$8.79",
"status": "1",
"statusDesc": "Success",
"showCurrency": null,
"showCurrencySymbol": null,
"showCurrencyTradeAmount": null,
"showExchangeRate": null,
"message": "Store Orders"
}
]
},
"requestId": "7dbe69b9-dd82-4ee3-907c-a6fca833e3ce"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| pageNum | Page number | int | 20 | |
| pageSize | Page size | int | 20 | |
| total | Total records | long | 20 | |
| list | Records | list | ||
| cjOrderId | CJ order number | string | 64 | Null when the record is not related to an order |
| createDate | Created time | string | 19 | yyyy-MM-dd'T'HH:mm:ss, UTC |
| typeDesc | Transaction type | string | 64 | Same text as the Type column on My CJ Balance History, see the tradeType table in 2.4 |
| copeMoney | Amount | BigDecimal | (18,2) | Unit: $ (USD), always non-negative |
| amount | Amount as displayed | string | 32 | Same as My CJ, with sign and currency symbol, for example +$8.79 / -$23.30 |
| status | Status | string | 1 | 0 Pending, 1 Success, 2 Failed, 3 Frozen, 4 Failed(Canceled) |
| statusDesc | Status name | string | 64 | Same text as the Status column on My CJ Balance History. A pending (status = 0) order payment, withdrawal or system deduction reads Frozen there |
| showCurrency | Display currency | string | 3 | Null when the record has no display currency |
| showCurrencySymbol | Display currency symbol | string | 8 | Same as above |
| showCurrencyTradeAmount | Amount in display currency | BigDecimal | (18,2) | Same as above |
| showExchangeRate | Exchange rate from USD to the display currency | BigDecimal | (18,6) | Same as above |
| message | Message | string | — | Same as the Message column of the Balance History export: a description by transaction type, for example Store Orders or System Refund. For top-ups, loans and some other types it is the remark recorded on the transaction (returned as recorded, may not be in English); -- when there is no description |
error
{
"code": 1600300,
"result": false,
"message": "startDay must not be after endDay",
"data": null,
"requestId": "323fda9d-3c94-41dc-a944-5cc1b8baf5b1"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code. 1600300 invalid parameter; 1610001 wallet query failed, please retry later |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
# 3 Shipping Info
# 3.1 Upload Shipping Info(POST)
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/uploadWaybillInfo
Tips:
- When uploading the waybill file, please submit the request in multipart/form data format.
- This interface can only be called after CJ order payment.
# CURL
curl --location 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/uploadWaybillInfo' \
--header 'CJ-Access-Token:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ' \
--form 'orderId="2511111146000642900"' \
--form 'waybillFile=@"/C:/Users/Desktop/abcd.pdf"' \
--form 'cjOrderId="DP2511111145580643400"' \
--form 'cjShippingCompanyName="USPS"' \
--form 'trackNumber="123123"'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| orderId | Order Id | string | Y | 200 | |
| cjOrderId | CJ Order Id | string | Y | 200 | |
| cjShippingCompanyName | CJ Shipping Company Name | string | Y | 200 | Referer:Get Storage Info, Get:logisticsBrandList |
| trackNumber | Track Number | string | Y | 200 | |
| waybillFile | waybill document | MultipartFile | Y | 200 |
# Return
success
{
"success": true,
"message": "",
"result": true,
"data": true,
"requestId": "52f1888a3b4f451d889a84218f2b50dc"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | Boolean | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
error
{
"code": 806,
"result": false,
"message": "Warehouse “null” does not support logistics carrier “USPS”.",
"data": null,
"requestId": "309ad9d884ff4994b34f0da17853b970",
"success": false
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
# 3.2 Update Shipping Info(POST)
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/updateWaybillInfo
# CURL
curl --location 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/updateWaybillInfo' \
--header 'CJ-Access-Token:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ' \
--form 'orderId="2511111146000642900"' \
--form 'waybillFile=@"/C:/Users/Desktop/abcd.pdf"' \
--form 'cjOrderId="DP2511111145580643400"' \
--form 'cjShippingCompanyName="USPS"' \
--form 'trackNumber="123123"'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| orderId | Order Id | string | Y | 200 | |
| cjOrderId | CJ Order Id | string | Y | 200 | |
| cjShippingCompanyName | CJ Shipping Company Name | string | Y | 200 | Referer:Get Storage Info, Get:logisticsBrandList |
| trackNumber | Track Number | string | Y | 200 | |
| waybillFile | waybill document | MultipartFile | Y | 200 |
# Return
success
{
"success": true,
"message": "",
"result": true,
"data": true,
"requestId": "52f1888a3b4f451d889a84218f2b50dc"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | Boolean | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
error
{
"code": 804,
"result": false,
"message": "This order does not use store platform logistics. Label upload not supported.",
"data": null,
"requestId": "715937dad5844ec49d51be43541eeb00",
"success": false
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
# 3.3 UPDATE POD Pictures(POST)
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/podProductCustomPicturesEdit
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/podProductCustomPicturesEdit' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'platformToken: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"podPicturesEditParams": [
{
"orderCode": "123",
"lineItemId": "111",
"effectImgList": [
"https://oss-cf.cjdropshipping.com/product/2025/04/22/01/245e348-a87b-4196-a3a4-056f6b391301.jpg"
],
"productionImgList": [
"https://oss-cf.cjdropshipping.com/product/2025/04/22/01/245e348-a87b-4196-a3a4-056f6b391301.jpg"
]
}
]
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| podPicturesEditParams | List | Y | |||
| -orderCode | CJ order id | string | Y | 200 | |
| -lineItemId | Unique ID of the order item in CJ | string | Y | 200 | |
| -effectImgList | Product renderings | List | Y | 200 | |
| -productionImgList | Production diagram | List | Y | 200 |
# Return
success
{
"code": 200,
"result": true,
"message": "Congratulation! Well done!",
"data": {
"list": [
{
"orderCode": "123",
"lineItemId": "111",
"result": 2,
"failedMessage": null
},
{
"orderCode": "456",
"lineItemId": "666",
"result": 0,
"failedMessage": "No matching order number found"
}
]
},
"requestId": "fa65ceae2f5740459c3e8dc8cf32124c",
"success": true
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | Object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
data information
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| list | List | Y | ||
| -orderCode | CJ order id | string | 200 | |
| -lineItemId | Unique ID of the order item in CJ | string | 200 | |
| -result | update result 0:fail, 1: Processing, 2: success | int | 20 | |
| -failedMessage | fail reason | string | 200 |
Error
{
"code": 804,
"result": false,
"message": "Param error",
"data": null,
"requestId": "715937dad5844ec49d51be43541eeb00",
"success": false
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | error code | int | 20 | Reference error code |
| result | Whether or not the return is normal | boolean | 1 | |
| message | return message | string | 200 | |
| data | return data | Object | interface data return | |
| requestId | requestId | string | 48 | Flag request for logging errors |
# 4 COGS
# COGS Page Overview
# Page Layout & Tabs
Two tabs are provided to display cost data at different granularities:
- Product-Level COGS: Breakdown of all cost items separated by individual product SKU
- Order-Level COGS: Aggregated full cost summary for the entire order
# Core CJ Logistics Cost Fields
| Field | Definition |
|---|---|
| First-mile Shipping Cost | One-time logistics expense generated when restocking goods from domestic warehouses to overseas warehouses. This cost is incorporated into inventory landed cost upon goods inbound, then allocated to corresponding sales orders during outbound shipment following system allocation rules. |
| Transfer Shipping Cost | One-time cross-warehouse transfer expense generated for private inventory relocation (transfers between domestic and overseas warehouses, or between multiple overseas warehouses). The fee is added to the inventory cost of the target warehouse once transfer inbound completes, and allocated to relevant sales orders at shipment. |
# Supplementary Basic Cost Fields
| Field | Definition |
|---|---|
| Product Fee | Base purchasing cost of the product |
| Outbound Cost | Last-mile delivery freight shipped to end customers |
| Storage Cost | Storage fee charged by overseas warehouses |
| Taxes Handling Fee | Administrative surcharge for tax processing |
| Total Price of a Single Commodity | Overall unit cost on CJ platform, summing product purchasing value, first-mile/transfer freight, storage fees and all other related charges |
# System Restrictions & Current Status
- This COGS detail page serves as the only official external portal for business staff to query first-mile and transfer freight data. No separate front-end page is available to access raw transfer order documents.
- Existing fields on the page only display total fees allocated to each sales order, lacking critical traceability dimensions: restock/transfer batch ID, origin & destination warehouse, unit freight rate, remaining stock quantity per batch.
- All future iterations and optimizations will be limited to this COGS detail page and its supporting
queryCogsOrderProductDetailAPI. Business requirements will be fulfilled by adding new traceability fields; the internal backend detail page linked to transfer order Event ID will not be developed or opened to external users.
# Standard Access Path
- Order list page URL:
https://www.cjdropshipping.com/mine/dropshipping/orderList?orderType=6 - Search target orders on the page → Click the question mark icon next to order COGS ratio to pop up tooltip → Tap "View COGS Details" in the pop-up to jump to the cost breakdown page
# 4.1 Query COGS Basic Data Order Info (POST)
Query basic data order information list based on provided order codes.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/queryCogsBasicDataOrderInfoList
# CURL
curl --location 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/queryCogsBasicDataOrderInfoList' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data '{
"orderCodesList": ["DP2506140734320969300"]
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| orderCodesList | List of CJ order codes | List<String> | Y | - | CJ order number list |
# Return
success
{
"code": 200,
"data": [
{
"cogsBasicDataOrderInfoJson": {
"a": "CJ2506144290356158893",
"c": null,
"d": 1,
"e": 6,
"f": 0.74,
"g": 6.58,
"h": 5.84,
"i": null,
"ii": "38",
"j": "2025-06-14T07:44:31"
},
"orderCode": "DP2506140734320969300",
"originalOrderCode": "",
"paymentDate": "2025-06-14T07:44:31",
"userId": "e11a3d3e3230401ab3984c59949be6a9"
}
],
"message": "",
"success": true
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| orderCode | Order code | string | 200 | |
| originalOrderCode | Original order code | string | 200 | For split orders: original code; for merged orders: pre-merge code |
| paymentDate | Payment time | LocalDateTime | - | |
| userId | User ID | string | 200 | |
| cogsBasicDataOrderInfoJson | Basic data details | object | - | See CogsBasicDataOrderInfoJson below |
# CogsBasicDataOrderInfoJson
| Attribute | Type | JSON Field | Definition |
|---|---|---|---|
| shipmentsOrderId | String | a | Parent order ID |
| merchantNumber | String | s | Customer ID |
| payFlag | Integer | d | Payment flag (1: paid) |
| postage | BigDecimal | f | Total postage after discount |
| totalAmount | BigDecimal | g | Total order amount |
| orderProductAmount | BigDecimal | h | Total product amount |
| paymentDate | LocalDateTime | j | Payment time |
| taxesInfo | Object | k | Tax information |
| productInfoMap | Map | z | Product data (productCode → ProductInfo) |
| disputeInfoMap | Map | x | Dispute data (disputeId → DisputeInfo) |
| diffAmountInfoMap | Map | c | Supplementary payment info (diffCode → DiffAmountInfo) |
| storeOrderInfo | Object | n | Store order information |
| isOutOfStockSplit | Integer | m | Out-of-stock split flag |
| isReissue | Integer | Reissue order flag (0: no, 1: yes) | |
| outStockFee | BigDecimal | rr | Outbound Cost |
| storeCostFee | BigDecimal | tt | Storage Cost |
| resendParcelFeeMap | Map | yy | Re-dispatch fee for problematic parcels |
| isReOrder | Integer | uu | Re-order flag |
| store | String | ii | Warehouse number |
| storeSkuProcessFlag | Integer | oo | Store SKU processing flag |
| countryCode | String | pp | Receiving country code |
# ProductInfo
| Attribute | Type | JSON Field | Definition |
|---|---|---|---|
| productCode | String | pc | Product code |
| groupProductCode | String | q | Group product code (for combined products) |
| sku | String | w | SKU |
| isGroupMain | Integer | e | Main product of combination (0: no, 1: yes) |
| grams | BigDecimal | r | Weight in grams |
| price | BigDecimal | t | Actual paid unit price (Product Fee) |
| quantity | Integer | y | Product quantity |
| productType | String | u | Product type (0: normal, 1: service, 3: packaging, 4: supplier, 5: supplier-shipped, 6: virtual) |
| img | String | z | Product image |
| isGift | Integer | h | Is gift (0: no, 1: yes) |
| couponOrderProductAmount | BigDecimal | j | Coupon amount |
| syncOrderInventoryLockPrivateInfoMap | Map | i | Private inventory deduction info (syncOrderInventoryLockId → SyncOrderInventoryLockPrivateInfoJson list), including First-mile Shipping Cost and Transfer Shipping Cost snapshots |
| headPostage | BigDecimal | n | First-mile Shipping Cost per private inventory item — one-time logistics expense from domestic to overseas warehouse, allocated to orders at outbound shipment |
| labelProcessFee | BigDecimal | lf | Label processing fee per unit (USD) |
# SyncOrderInventoryLockPrivateInfoJson (Private Inventory Deduction Info)
| Attribute | Type | JSON Field | Definition |
|---|---|---|---|
| price | Long | q | Purchase price (in cents) |
| quantity | Integer | w | Quantity used |
| privateOrderCode | String | e | Private inventory order code |
| privateProductCode | String | r | Private inventory product code |
| transferCostDetailList | Map | tcd | Transfer Shipping Cost snapshot details (unitCostKey → TransferCostSnapshotItem) — allocation breakdown of cross-warehouse transfer logistics expenses |
# TransferCostSnapshotItem (Transfer Shipping Cost Snapshot)
Cross-warehouse transfer expense allocation details for private inventory relocation (transfers between domestic and overseas warehouses, or between multiple overseas warehouses).
| Attribute | Type | JSON Field | Definition |
|---|---|---|---|
| unitCost | BigDecimal | uc | Transfer Shipping Cost unit price |
| quantity | Integer | q | Order placement quantity |
| refundQuantity | Integer | rq | Dispute refunded quantity |
| transferOrderMap | Map | tm | Transfer order dimension snapshot (source transfer order code → TransferCostTraceItem) |
# TransferCostTraceItem (Transfer Order Dimension Snapshot)
| Attribute | Type | JSON Field | Definition |
|---|---|---|---|
| quantity | Integer | q | Source transfer order occupied quantity |
| refundQuantity | Integer | rq | Source transfer order refunded quantity |
| amountComposition | Map | a | Per-unit transfer cost composition (contributing transfer order code → per-unit amount) |
# DisputeInfo
| Attribute | Type | JSON Field | Definition |
|---|---|---|---|
| productPriceFinal | BigDecimal | q | Final product refund amount |
| iossTaxesFinal | BigDecimal | e | Final IOSS tax |
| iossTaxHandlingFeeFinal | BigDecimal | r | Final IOSS handling fee |
| ddpHandlingFee | BigDecimal | t | Final DDP handling fee |
| dutyTaxesFinal | BigDecimal | y | Final duty tax |
| icmsTaxesFinal | BigDecimal | u | Final circulation tax |
| postageFinal | BigDecimal | p | Final refunded shipping fee |
| outboundCostFinal | BigDecimal | s | Final refunded outbound cost |
| storageCostFinal | BigDecimal | d | Final refunded storage cost |
# TaxesInfo
| Attribute | Type | JSON Field | Definition |
|---|---|---|---|
| taxesType | Integer | q | Tax type (0: none, 1: IOSS, 2: Brazil duty, 3: US tax) |
| taxes | BigDecimal | w | Tax amount |
| taxHandlingFee | BigDecimal | e | Tax handling fee (Taxes Handling Fee) |
| icmsTaxes | BigDecimal | r | Circulation tax (ICMS) |
| dutyTaxes | BigDecimal | t | Import duty tax |
# DiffAmountInfo
| Attribute | Type | JSON Field | Definition |
|---|---|---|---|
| postage | BigDecimal | q | Supplementary postage (USD) |
| dutyTaxes | BigDecimal | w | Supplementary duty tax (USD) |
| icmsTaxes | BigDecimal | e | Supplementary circulation tax (USD) |
| ddpHandlingFee | BigDecimal | r | Supplementary DDP handling fee (USD) |
| iossHandlingFee | BigDecimal | t | Supplementary IOSS handling fee (USD) |
| iossTaxes | BigDecimal | y | Supplementary IOSS tax (USD) |
# StoreOrderInfo
| Attribute | Type | JSON Field | Definition |
|---|---|---|---|
| storeId | String | q | Store ID |
| storeOrderId | String | w | Third-party platform order ID |
| storeOrderNumber | String | e | Store order number |
| currency | String | r | Currency |
| currencyExchangeRate | BigDecimal | t | Currency to USD exchange rate |
| totalPayment | StoreOrderAmountInfoJson | y | Total payment amount |
| actualItemTotalPrice | StoreOrderAmountInfoJson | u | Total paid product amount |
| totalShippingFee | StoreOrderAmountInfoJson | i | Total shipping fee |
| actualTaxTotalPrice | StoreOrderAmountInfoJson | o | Total tax amount |
| totalNum | Integer | p | Total product quantity |
| orderWeight | Long | a | Total order weight |
| orderWeightUnit | String | s | Weight unit |
| storeName | String | d | Store name |
| platForm | String | f | Platform |
# StoreOrderAmountInfoJson
| Attribute | Type | JSON Field | Definition |
|---|---|---|---|
| amount | BigDecimal | q | Amount (original currency) |
| currency | String | w | Currency |
| usAmount | BigDecimal | e | Amount in USD |
error
{
"code": 1600100,
"result": false,
"message": "Param error",
"data": null,
"requestId": "323fda9d-3c94-41dc-a944-5cc1b8baf5b1"
}
# 4.2 COGS Order Product Detail (POST)
POST /api2.0/v1/shopping/order/queryCogsOrderProductDetailPage
Returns order pages with nested product-level COGS in productDetailList, scoped to the authenticated customer. Date filters use store payment time.
| Parameter | Type | Required | Description |
|---|---|---|---|
| startTime | long | Yes | Inclusive UTC Unix milliseconds; nonnegative |
| endTime | long | Yes | Inclusive UTC Unix milliseconds; startTime ≤ endTime; maximum range 31 days |
| pageNum | integer | No | Default 1; minimum 1 |
| pageSize | integer | No | Default 20; 1–100; pageNum × pageSize ≤ 10000 |
| orderNo | string | No | Order search value supported by the COGS page |
| cjSku | string | No | CJ SKU |
| storeSkuId | string | No | Store SKU ID |
| storeProductName | string | No | Store product name |
| storeIds | string[] | No | At most 100 nonblank store IDs, all owned by the current customer; omit for all accessible stores |
curl --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/queryCogsOrderProductDetailPage' --header 'CJ-Access-Token: YOUR_ACCESS_TOKEN' --header 'Content-Type: application/json' --data '{"startTime":1788220800000,"endTime":1788307199999,"pageNum":1,"pageSize":20}'
| Response field | Meaning |
|---|---|
| data.total / pageNum / pageSize | Matched order count and pagination |
| data.records[] | Order rows |
| orderCode / storeOrderId / shipmentOrderId | CJ order, store order and shipment order identifiers |
| orderSource / country | Order source and country |
| cjPayDate / storePayDate | Payment timestamps in milliseconds |
| currency / storeCurrency | CJ cost currency (USD) / original store currency |
| totalPricePerItem | Original COGS order-level amount, not recalculated from product rows |
| storeSingleProductAmount / storeSingleProductAmountUsd | Store amount in original currency / USD |
| cogs | Original ratio: 0.15 means 15%; never multiplied by 100 |
| transferShippingCost | Visible transfer shipping cost; otherwise null |
| productDetailList[] | Product cost rows using the fields below |
Product fields are explicitly selected. Monetary minor units are converted exactly to major units. Missing amounts stay null, not zero. Totals retain the source value; do not add totals to component fees.
| Product field | Source field | Unit / meaning |
|---|---|---|
| productFee | cjProductAmount | USD product cost |
| postage | cjPostage | USD postage |
| taxes | cjTaxes | USD taxes |
| taxesHandlingFee | cjTaxHandlingFee | USD tax handling fee |
| storageFee | storeCostFee | USD storage fee |
| outboundFee | outStockFee | USD outbound fee |
| firstMileShippingCost | firstMileShippingCost | USD first-mile shipping |
| transferShippingCost | transferShippingCost | USD, only when source visibility flag is true; otherwise null |
| totalPricePerItem | cjSingleProductAmount | Original USD total; not a further cost component |
| storeProductAmount / storePostage / storeTaxes / storeOtherTaxes / storeSingleProductAmount | Same names | Original store currency, identified by storeCurrency |
| storeSingleProductAmountUsd | Same name | USD equivalent already provided by COGS; no new exchange calculation |
| cjSku / storeSkuId / storeProductName / storeProductVariantName | Same names | Product identifiers and descriptive data |
| cogs / currency / storeCurrency | Same names / USD / same name | Ratio and currencies |
Illustrative response (not a production record):
{"code":200,"result":true,"message":"Success","data":{"total":1,"pageNum":1,"pageSize":20,"records":[{"orderCode":"EXAMPLE-ORDER","currency":"USD","storeCurrency":"EUR","totalPricePerItem":12.34,"cogs":0.15,"productDetailList":[{"cjSku":"EXAMPLE-SKU","currency":"USD","storeCurrency":"EUR","productFee":10.00,"postage":2.34,"taxes":null,"transferShippingCost":null,"totalPricePerItem":12.34}]}]}}
# 4.3 Store COGS Count (POST)
POST /api2.0/v1/shopping/order/queryStoreCogsCount
| Parameter | Type | Required | Description |
|---|---|---|---|
| startTime / endTime | long | Yes | Ordered nonnegative UTC Unix milliseconds; maximum range 92 days |
| timeZone | string | No | Default +00:00; valid IANA zone (Asia/Shanghai) or UTC offset (+08:00) |
| storeIds | string[] | No | Same ownership and size rules as 4.2 |
| pageNum / pageSize | integer | No | Defaults 1 / 20; pageNum ≥ 1, pageSize 1–100 |
| isQueryTotalCount | integer | No | Default 0; 1 includes the original six-month trend |
{"startTime":1788220800000,"endTime":1788307199999,"timeZone":"+08:00","pageNum":1,"pageSize":20,"isQueryTotalCount":1}
| Response field | Meaning |
|---|---|
| data.monthCogsCounts[] | Month / cogs pairs; original recent six-month trend, independent of the requested detail date window |
| data.storeCountDetailPage.total / pageNum / pageSize | Pagination of store/day aggregates |
| data.storeCountDetailPage.records[].storeId | Store ID |
| date / day | Original timestamp / day key (yyyyMMdd) in requested timezone |
| storeProductTotalAmount / cjProductTotalAmount | Original store/CJ aggregates converted from cents to USD |
| cogs / currency | Original ratio / USD |
Uses the existing COGS page aggregation and historical-cache semantics. The API does not recalculate exchange rates, costs or ratios. When the trend is not requested, monthCogsCounts is [].
# 4.4 Store Product Cost Detail (POST)
POST /api2.0/v1/shopping/order/queryStoreProductCostDetailPage
Uses the request parameters of 4.2. data.records[] contains flat product rows with the product-cost fields and order identifiers, payment timestamps and country from 4.2; no nested productDetailList. Only the current customer’s data is returned.
Product-name search uses the existing page matching scope (at most 100 product IDs), not an exhaustive name scan. Use a more specific name, cjSku or storeSkuId. Name matching depends on the product service; an empty result may also reflect a failed lookup. For reconciliation, retry without the name and use an exact SKU.
# COGS errors and compatibility
| Code | Meaning |
|---|---|
| 1600300 | Invalid date, timezone, pagination or store filter; HTTP 400 |
| 1600501 | The existing COGS service reported maintenance; retry later |
| 1600000 | Service failure; do not treat as an empty result |
The legacy queryCogsBasicDataOrderInfoList response and its single-letter fields remain compatible. Use the new endpoints for semantic names. No new label-processing-fee calculation is introduced.
# 5 Merge Order
# 5.1 Auto Match Merge Order List (POST)
Get list of automatically matched mergeable orders.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/mergeOrder/autoMatchMergeOrderListV3
# CURL
curl --location 'https://developers.cjdropshipping.com/api2.0/v1/shopping/mergeOrder/autoMatchMergeOrderListV3' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data '{
"filterOrder": true,
"orderStatus": 100
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| filterOrder | Filter manually removed orders | boolean | Y | 1 | |
| orderStatus | Order status | int | Y | 10 | 100: Complete order page, 101: Shopping cart page |
# Return
success
{
"code": 200,
"data": [
{
"haveMoreShopOrder": true,
"mergeShopOrderVOList": [
{
"city": "Shanghai",
"country": "China",
"countryCode": "CN",
"customerName": "John",
"logisticsInfoList": [
{
"logisticsName": "PostNL",
"postage": 18.00,
"arrivalTime": "2023-11-20",
"isChecked": true
}
]
}
]
}
],
"message": "success",
"success": true
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| haveMoreShopOrder | Has multiple store orders | boolean | 1 | false: no, true: yes |
| mergeShopOrderVOList | Store order list | Array | - | |
| - city | City | string | 200 | |
| - country | Country | string | 200 | |
| - countryCode | Country code | string | 20 | |
| - customerName | Customer name | string | 200 | |
| - logisticsInfoList | Logistics options list | Array | - | |
| -- logisticsName | Logistics name | string | 200 | |
| -- postage | Postage | decimal | - | |
| -- arrivalTime | Estimated arrival time | string | 200 | |
| -- isChecked | Currently selected logistics | boolean | 1 | |
| -- basePostage | Base postage | decimal | - | |
| -- packPrice | Packaging postage | decimal | - | |
| -- remoteAmount | Remote area fee | decimal | - |
# 5.2 Auto Merge Query Progress (POST)
Query the asynchronous processing progress of auto match merge order list.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/mergeOrder/autoMergeQueryProgress
# CURL
curl --location 'https://developers.cjdropshipping.com/api2.0/v1/shopping/mergeOrder/autoMergeQueryProgress' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json'
# Return
success
{
"code": 200,
"data": {
"noTask": false,
"step": 2,
"stepCount": [10, 20, 30, 10, 30],
"stepPercent": 5000
},
"message": "success",
"success": true
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| noTask | No submitted tasks to process | boolean | 1 | |
| step | Current step | int | 10 | |
| stepCount | Step ratio array | Array | - | Array length = step count, elements = step weight |
| stepPercent | Current step progress | int | 10 | Max 10000 |
# 5.3 Auto Merge Query Result (POST)
Query asynchronous results of automatically matched merged orders, returning store order information and logistics options.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/mergeOrder/autoMergeQueryResult
# CURL
curl --location 'https://developers.cjdropshipping.com/api2.0/v1/shopping/mergeOrder/autoMergeQueryResult' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json'
# Return
success
{
"code": 200,
"data": [
{
"haveMoreShopOrder": true,
"mergeShopOrderVOList": [
{
"city": "Shanghai",
"country": "China",
"countryCode": "CN",
"customerName": "John",
"logisticsInfoList": [
{
"logisticsName": "PostNL",
"postage": 18.00,
"arrivalTime": "2023-11-20"
}
],
"mergeOrderInfoList": [
{
"orderCode": "CJ123456789",
"orderNumber": "ORD987654",
"platform": "shopify",
"shopName": "My Store"
}
],
"phone": "13800138000",
"shippingAddress": "123 Main St"
}
]
}
],
"message": "success",
"success": true
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| haveMoreShopOrder | Has multiple store orders | boolean | 1 | false: no, true: yes |
| mergeShopOrderVOList | Store order list | Array | - | |
| - mergeOrderInfoList | Merge order info list | Array | - | |
| -- orderCode | CJ order code | string | 200 | |
| -- orderNumber | Customer order number | string | 200 | |
| -- platform | Platform | string | 50 | |
| -- shopName | Shop name | string | 200 |
# 5.4 Submit Merge Order Batch (POST)
Submit merged orders with auto-matched groups, combining multiple eligible orders into one.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/mergeOrder/submitMergeOrderBatchV3
# CURL
curl --location 'https://developers.cjdropshipping.com/api2.0/v1/shopping/mergeOrder/submitMergeOrderBatchV3' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data '[
{
"logisticName": "PostNL",
"orderCodeList": ["CJ123456789", "CJ987654321"],
"orderNumber": "ORD123456",
"orderStatus": 100,
"packType": 0
}
]'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| logisticName | Logistics name | string | Y | 50 | |
| orderCodeList | CJ order codes to merge | List<String> | Y | - | |
| orderNumber | Customer store order number | string | Y | 50 | |
| orderStatus | Order status | int | Y | 10 | 100: Complete order page, 101: Shopping cart |
| packType | Packaging type | int | Y | 1 | 0: SKU, 1: Store |
# Return
success
{
"code": 200,
"data": {
"failGroupCount": 0,
"failOrderCount": 0,
"mergeFailOrderGroupList": [],
"newOrderCodeList": ["CJ999888777"],
"successGroupCount": 1,
"successOrderCount": 2
},
"message": "success",
"success": true
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| failGroupCount | Number of failed groups | int | 10 | |
| failOrderCount | Number of failed orders | int | 10 | |
| mergeFailOrderGroupList | Failed order list with reasons | Array | - | |
| - errorCode | Error code | int | 10 | 200: success, 11001-11007: various errors, 11100: other |
| - orderCodes | Order codes | Array | - | |
| newOrderCodeList | Successfully merged order codes | Array | - | |
| successGroupCount | Number of successful groups | int | 10 | |
| successOrderCount | Number of successful orders | int | 10 |
# 5.5 Submit Merge Progress (POST)
Query the asynchronous processing progress of submitted merged orders.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/mergeOrder/submitProgress
# CURL
curl --location 'https://developers.cjdropshipping.com/api2.0/v1/shopping/mergeOrder/submitProgress' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json'
# Return
success
{
"code": 200,
"data": {
"noTask": false,
"step": 1,
"stepCount": [10, 20, 30, 10, 30],
"stepPercent": 8000
},
"message": "success",
"success": true
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| noTask | No submission tasks to process | boolean | 1 | |
| step | Current step | int | 10 | |
| stepCount | Step ratio array | Array | - | Array length = step count |
| stepPercent | Current step progress | int | 10 | Max 10000 |
# 5.6 Submit Merge Result (POST)
Get asynchronous processing results of submitted merged orders, returning information about successfully merged and failed orders.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/mergeOrder/submitResult
# CURL
curl --location 'https://developers.cjdropshipping.com/api2.0/v1/shopping/mergeOrder/submitResult' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json'
# Return
success
{
"code": 200,
"data": {
"failGroupCount": 0,
"failOrderCount": 0,
"mergeFailOrderGroupList": [],
"newOrderCodeList": ["CJ999888777"],
"successGroupCount": 1,
"successOrderCount": 2
},
"message": "success",
"success": true
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| failGroupCount | Number of failed groups | int | 10 | |
| failOrderCount | Number of failed orders | int | 10 | |
| mergeFailOrderGroupList | Failed order list with reasons | Array | - | |
| - errorCode | Error code | int | 10 | 200: success, 11001: only 1 order selected, 11002: order exception, 11003: empty order, 11004: address mismatch, 11005: no available logistics, 11006: supplier self-shipped order, 11007: order status changed, 11100: other error |
| - orderCodes | Order codes | Array | - | |
| newOrderCodeList | Successfully merged order codes | Array | - | |
| successGroupCount | Number of successful groups | int | 10 | |
| successOrderCount | Number of successful orders | int | 10 |
# 6 Address Management
Address Management APIs maintain the address book for the current account. This is an account-level address-book capability, not a create-order element for any specific ordering flow. The server fills the user context from the current CJ-Access-Token; do not pass userId or token in the request body.
# 6.1 List Addresses (POST)
URL: https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/address/list
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/address/list' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{}'
data[].id is the address-book record ID. Private-inventory SY order creation itself does not use this field.
# 6.2 Create Address (POST)
URL: https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/address/create
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/address/create' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"firstName": "Gilbert",
"lastName": "Soria",
"country": "United States",
"countryCode": "US",
"province": "OH",
"city": "HUBER HEIGHTS",
"address": "3419 BROADMOOR BLVD1",
"addressNew": "Apt 123",
"zip": "222260",
"phone": "9322331159",
"mail": "test@example.com",
"isDefault": "0"
}'
# 6.3 Update Address (POST)
URL: https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/address/update
All create-address fields can be updated. The id field is additionally required. If only the zip code changes, still use this endpoint: first get the full address fields from the address list, then submit id, all mandatory address fields, and the new zip.
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| id | Address ID | string | Required for update | 100 | From the address list response |
| firstName | First name | string | Required for create/update | 100 | |
| lastName | Last name | string | Required for create/update | 100 | |
| country | Country name | string | Required for create/update | 100 | |
| countryCode | Two-letter country code | string | Required for create/update | 10 | Refer to country standards |
| province | Province/state | string | Required for create/update | 100 | |
| city | City | string | Required for create/update | 100 | |
| address | Address line 1 | string | Required for create/update | 200 | |
| addressNew | Address line 2 | string | N | 200 | |
| zip | Zip code | string | N | 30 | Address data field. To change the zip code, submit it through the Update Address endpoint. |
| phone | Phone | string | N | 30 | |
| string | N | 100 | |||
| isDefault | Default address flag | string | N | 1 | 0-no, 1-yes |
| countyTown | County/town | string | N | 100 | |
| consigneeId | Consignee ID | string | N | 100 |
# 6.4 Address API response fields
| Field | Definition | Type | Note |
|---|---|---|---|
| data | Address API business data | object/list/boolean | The list API returns an array; create/update returns the address operation result |
| data[].id | Address ID | string | Address-book record ID; not a private-inventory create-order field |
| data[].firstName / data[].lastName | Name | string | Contact name fields |
| data[].country / data[].countryCode | Country | string | Country name and two-letter code |
| data[].province / data[].city | Province/state and city | string | Address region fields |
| data[].address / data[].addressNew | Address | string | Address line 1 and line 2 |
| data[].zip | Zip code | string | Address zip code |
| data[].phone / data[].mail | Phone/email | string | Contact fields |
| data[].isDefault | Default address flag | string/integer | 0-no, 1-yes |
# 7 Private Inventory Orders
The Private Inventory order APIs provide an OpenAPI flow for preorder/private inventory purchasing. The recommended flow is direct selected-product ordering: query private inventory products → pass multiple variants to get confirmation → get warehouses, logistics, and costs → submit multiple productList items to create the SY order. Cart APIs are optional helpers for temporary storage and review, not prerequisites for ordering.
All APIs operate on the account bound to the current
CJ-Access-Token. If token or account validation fails, the API returns the validation error.
# Private Inventory OpenAPI Sequence Diagrams
Start by calling the product list API to get available products and SKU information. Select product ID, variant ID/SKU, and quantity from /product/listV2, then use either direct mode or cart mode to confirm warehouse, logistics, cost, create the order, and query the order.
Use one of these two integration modes:
- Direct mode: do not use the cart. Build
variantsdirectly from product ID, SKU/variant ID, and quantity, then confirm warehouse, logistics, and cost before creating the order. - Cart mode: add products to the private-inventory cart first, read the cart items, convert the selected cart SKU rows into
variants, and then continue with the same confirmation and creation steps as direct mode.
| Integration step | Purpose | What to call in OpenAPI |
|---|---|---|
| Get product information | Query available products and get product ID, variant ID/SKU, and other order inputs | Call /product/listV2, then select the product rows for this order |
| Choose an integration mode | Decide whether to save items in the cart first | Direct mode: build variants directly. Cart mode: call /shopping/privateInventory/addToCart, then call /shopping/privateInventory/getCart to read the items |
| Confirm warehouse, logistics, and cost | Get candidate warehouses, logistics, and final amount | Call /shopping/privateInventory/getConfirmationWithCost in three passes: variants only → add storageId → add logisticName |
| Create the private-inventory order | Submit final products, warehouse, logistics, and payment option | Call /shopping/privateInventory/createOrder; page payment returns a payment page URL |
| Private-inventory balance payment | Pay the private-inventory order with account balance | Call /shopping/pay/payBalanceV2 with the returned order number/payment ID and orderType=9 |
| Query order status | Get creation result and later status | Call /shopping/privateInventory/order/list |
# Where to view the data on the website
These website links require the same CJ account to be signed in. If the user is not signed in, the website redirects to sign-in first and then returns to the target page.
| Result | Website page | Notes |
|---|---|---|
| After adding items to the private-inventory cart | Private-inventory cart (opens new window) | View the private-inventory products just added to the cart; you can also call /shopping/privateInventory/getCart to read the same data |
| After creating a private-inventory order | Private-inventory order list (opens new window) | View created private-inventory orders; to locate one order, search the order number on the page or append &orderNumber=SY1234567890 to the link |
orderType=2in the order-list link is only the website filter for private-inventory orders. For the balance-payment API, still passorderType=9as described above.
Endpoint paths in the diagrams are clickable and jump to the matching API section.
# Direct mode: order selected products directly
sequenceDiagram
participant You as Your System
participant Product as Product List API
participant Cost as Confirmation/Warehouse/Cost API
participant CreateApi as Create Order API
participant BalancePay as Balance Payment API
participant Orders as Order List API
Note over You,Orders: Direct mode: order by product ID, SKU/variant ID, and quantity without using the cart
You->>Product: GET /product/listV2
Product-->>You: Return product ID, variant ID/SKU, and product information
You->>Cost: POST /shopping/privateInventory/getConfirmationWithCost(variants)
Cost-->>You: Return confirmed products and available warehouses
You->>Cost: POST /shopping/privateInventory/getConfirmationWithCost(variants, storageId)
Cost-->>You: Return logistics and cost for the selected warehouse
You->>Cost: POST /shopping/privateInventory/getConfirmationWithCost(variants, storageId, logisticName)
Cost-->>You: Return final amount
You->>CreateApi: POST /shopping/privateInventory/createOrder(productList, storageId, logisticName, payType)
alt Page payment
CreateApi-->>You: Return order number, payment ID, and payment page URL
else Balance payment
CreateApi-->>You: Return order number and payment ID
You->>BalancePay: POST /shopping/pay/payBalanceV2(shipmentOrderId, payId, orderType)
BalancePay-->>You: Return balance-payment result
end
You->>Orders: POST /shopping/privateInventory/order/list
Orders-->>You: Return private-inventory order status
# Cart mode: save items before ordering
sequenceDiagram
participant You as Your System
participant Product as Product List API
participant AddCart as Add-to-cart API
participant Cart as Cart API
participant Cost as Confirmation/Warehouse/Cost API
participant CreateApi as Create Order API
participant BalancePay as Balance Payment API
participant Orders as Order List API
Note over You,Orders: Cart mode: save items first, then convert cart SKU rows into order input
You->>Product: GET /product/listV2
Product-->>You: Return product ID, variant ID/SKU, and product information
You->>AddCart: POST /shopping/privateInventory/addToCart(productId, variants)
AddCart-->>You: Return add-to-cart result
You->>Cart: POST /shopping/privateInventory/getCart
Cart-->>You: Return cart products, SKUs, and quantities
Note over You,Cart: Convert selected cart SKU rows into variants
You->>Cost: POST /shopping/privateInventory/getConfirmationWithCost(variants)
Cost-->>You: Return confirmed products and available warehouses
You->>Cost: POST /shopping/privateInventory/getConfirmationWithCost(variants, storageId)
Cost-->>You: Return logistics and cost for the selected warehouse
You->>Cost: POST /shopping/privateInventory/getConfirmationWithCost(variants, storageId, logisticName)
Cost-->>You: Return final amount
You->>CreateApi: POST /shopping/privateInventory/createOrder(productList, storageId, logisticName, payType)
alt Page payment
CreateApi-->>You: Return order number, payment ID, and payment page URL
else Balance payment
CreateApi-->>You: Return order number and payment ID
You->>BalancePay: POST /shopping/pay/payBalanceV2(shipmentOrderId, payId, orderType)
BalancePay-->>You: Return balance-payment result
end
You->>Orders: POST /shopping/privateInventory/order/list
Orders-->>You: Return private-inventory order status
# 7.0 Order Element Sources
Before creating an order, let the user confirm the products, quantities, warehouse, logistics option, and payment option. Products can come from the product list, cart, or confirmation response; warehouse, logistics, and amounts should follow the options returned by the APIs.
| Create field / helper item | Source | Used by | Note |
|---|---|---|---|
| Product ID, variant ID, SKU | Product list API /product/listV2, cart, or confirmation response | productList[].productId, productList[].variantId, productList[].sku | Required for final creation. Use the product list API to identify the product and SKU before confirming or creating the order. |
| Quantity | Client selection, cart quantity, confirmation response | productList[].quantity | Required for final creation. Use the quantity selected for each SKU. |
| Storage ID | availableStorehouseList[].storageId returned by getConfirmation / getConfirmationWithCost | getCostInfo.storageId, logistics/list.storageId, createOrder.storageId | Required for final creation. Select from the private-inventory warehouse candidate list. Do not use fixed sample values. |
| Logistics name | availableLogisticList[].logisticName returned by logistics/list or the freight rows returned by getCostInfo | createOrder.logisticName, getConfirmationWithCost.logisticName | Required for final creation. Select a logistics option available for the current warehouse and products. |
| Product unit price | Final stock-up unit price | API calculation | Do not submit price when creating the order. Use the amount returned by the API. |
| Cost details | getCostInfo or getConfirmationWithCost response | Display and pre-order confirmation | Not a create request field. |
| Payment option | User selection | createOrder.payType | Optional. 1=page payment, returns a payment page URL; 2=balance payment, which can continue with the balance payment API. |
# 7.1 Add To Private Inventory Cart (POST)
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/addToCart
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/addToCart' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"productId": "422C91F3-B7D0-47F3-BC66-5E1FE3208BBA",
"variants": [
{"variantId": "V001-SKU-A", "quantity": 100}
]
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| productId | Product ID | string | Y | 200 | From private inventory product query APIs |
| variants | Variant list | list | Y | SKU rows to add to the private-inventory cart | |
| variants[].variantId | Variant ID | string | Y | 200 | |
| variants[].quantity | Quantity | integer | Y | 20 | 1-100000 |
# Response fields
| Field | Definition | Type | Note |
|---|---|---|---|
| data | Add-to-cart result | object/boolean | Some environments may return a boolean directly. |
| data.success | Add succeeded | boolean | Returned when available |
| data.addedCount | Added SKU-line count | integer | Returned when available |
After a successful add-to-cart call, open the private-inventory cart (opens new window) to view the products; on the API side, call
/shopping/privateInventory/getCartto read the cart data.
# 7.2 Get Private Inventory Cart (POST)
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/getCart
The request body can be omitted. If no body is sent, the server treats it as an empty object and queries all private-inventory cart items by default. Pagination parameters are still supported. pageSize is capped at 100 by OpenAPI.
# CURL (omit request body and use defaults)
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/getCart' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
# CURL (paginated query)
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/getCart' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{"pageNum":1,"pageSize":20,"isAll":0}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| pageNum | Page number | integer | N | 20 | Uses service default when omitted |
| pageSize | Page size | integer | N | 20 | Uses service default when omitted. Maximum 100; values greater than 100 are capped at 100. |
| isAll | Query all items | integer | N | 1 | 0-no, 1-yes; default 1 |
# Response fields
| Field | Definition | Type | Note |
|---|---|---|---|
| data.productList | Cart product list | list | Valid cart products grouped by product |
| data.productList[].productId | Product ID | string | Product ID |
| data.productList[].productName | Product name | string | Display field |
| data.productList[].productImage | Product image | string | Display field |
| data.productList[].variants | SKU rows | list | Cart SKU/variant rows under the product |
| data.productList[].variants[].id | Cart SKU-row ID | string | Cart SKU-row identifier |
| data.productList[].variants[].variantId | Variant ID | string | SKU/variant ID |
| data.productList[].variants[].sku | SKU | string | SKU |
| data.productList[].variants[].quantity/count | Quantity | integer | SKU quantity |
| data.productList[].variants[].price | Final stock-up unit price | number | USD. Display/reference only. Price is not required in create-order requests. |
| data.invalidProductList | Invalid product list | list | Returned when available |
| data.totalAmount | Cart product amount | number | USD, display only. Do not pass order total to create-order. |
| data.selectVariantCount | SKU count | integer | Statistics only. Public create flow does not depend on cart selection state. |
| data.currencyInfo | Currency info | object | Usually contains currencyCode and currencySymbol |
# 7.3 Remove Private Inventory Cart Items (POST)
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/removeFromCart
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/removeFromCart' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{"variantIds":["V001-SKU-A"]}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| variantIds | Variant ID list | list | Y | SKU variant IDs to remove |
Deletion identifier note: get variantIds from the SKU row id or variantId returned by getCart.
# Response fields
| Field | Definition | Type | Note |
|---|---|---|---|
| data | Delete result | boolean/object | Usually returns a boolean. If an object is returned, the API passes it through. |
# 7.4 Get Private Inventory Order Confirmation (POST)
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/getConfirmation
# Direct Selected-product Confirmation CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/getConfirmation' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"variants": [
{"variantId": "V001-SKU-A", "productId": "422C91F3-B7D0-47F3-BC66-5E1FE3208BBA", "quantity": 100}
]
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| variants | Variant list | list | N | Pass it for direct selected-product confirmation. Explicit input is recommended and multiple product lines are supported. | |
| variants[].variantId | Variant ID | string | Required in direct selected-product mode | 200 | |
| variants[].productId | Product ID | string | Required in direct selected-product mode | 200 | |
| variants[].quantity | Quantity | integer | Required in direct selected-product mode | 20 | Quantity to confirm for this SKU |
# Response fields
| Field | Definition | Type | Note |
|---|---|---|---|
| data.orders | Confirmation order groups | list | Product, logistics, and amount information grouped for the confirmation page |
| data.availableStorehouseList | Private-inventory warehouse candidates | list | Select warehouses from this field. Use storageId from this list for logistics, cost, and create-order requests. |
| data.availableStorehouseList[].storageId | Warehouse ID | string | Pass it as logistics/list.storageId, getCostInfo.storageId, and createOrder.storageId |
| data.availableStorehouseList[].displayName | Warehouse name | string | Warehouse name |
| data.availableStorehouseList[].countryCode | Warehouse country/region code | string | Display or region field |
| data.availableStorehouseList[].areaId | Warehouse area ID | integer | Display or region field |
| data.availableStorehouseList[].addresses | Warehouse address | string | Returned when available |
| data.availableStorehouseList[].address | Warehouse address alias | string | Same address value for direct client display |
| data.availableStorehouseList[].zipCode | Warehouse zip code | string | Returned when available |
| data.availableStorehouseList[].selected | Selected flag | boolean | Whether this row matches the request storageId |
| data.selectedStorageId | Selected storage ID | string | The matched warehouse ID; empty when omitted or unavailable |
| data.selectedStorehouse | Selected warehouse object | object | Same fields as availableStorehouseList[]; empty when omitted or unavailable |
| data.orders[].logisticList | Confirmation logistics candidates | list | Confirmation-page logistics candidates. Use logistics/list.availableLogisticList when selecting the final create-order logistics. |
| data.orders[].logisticList[].logisticName / enName | Logistics name | string | Candidate logistics display/name fields when returned |
| data.orders[].logisticList[].shippingCost / freightAmount | Logistics fee | number | USD, returned when available |
| data.orders[].logisticList[].estimateDays / minDeliveryDay / maxDeliveryDay | Estimated delivery time | string/number | Returned when available |
| data.orders[].logisticList[].selected | Selected flag | boolean | Confirmation-page selected status when returned |
| data.orders[].products | Confirmed product lines | list | Product lines may be returned directly under orders[] |
| data.orders[].confirmGroupOrderVOList | Confirmation product groups | list | Product lines may also be returned under group objects |
| data.orders[].confirmGroupOrderVOList[].products | Group product lines | list | Use together with orders[].products when building final createOrder.productList |
| data.orders[].products[].id / variantId | Variant ID | string | Use as productList[].variantId for creation |
| data.orders[].products[].productId | Product ID | string | Use as productList[].productId for creation |
| data.orders[].products[].sku | SKU | string | Use as productList[].sku for creation |
| data.orders[].products[].productName | Product name | string | Display field returned when available |
| data.orders[].products[].productImage | Product image | string | Display field returned when available |
| data.orders[].products[].quantity / count / itemCount | Quantity | integer | Use as productList[].quantity for creation |
| data.orders[].products[].price / nowPrice | Final stock-up unit price | number | USD. Display/reference only. Price is not required in create-order requests; the final price is calculated in real time by the API. |
| data.orders[].products[].weight | Weight | number | SKU weight returned when available |
| data.totalProductPrice | Product amount total | number | USD, display only. Do not pass order total to create-order. |
| data.currencyInfo | Currency info | object | Usually contains currencyCode and currencySymbol |
# 7.5 Get Private Inventory Available Logistics (POST)
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/logistics/list
Use this API to get available logistics for the selected warehouse. Call it after the user selects products, quantities, and warehouse, then choose the logistics name for create order from the returned list.
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/logistics/list' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"storageId": "WAREHOUSE-HZ-001",
"variantInfoList": [
{"id": "V001-SKU-A", "quantity": 100}
]
}'
| Parameter | Description | Type | Required | Length | Remark |
|---|---|---|---|---|---|
| storageId | Storage ID | string | Y | 200 | Select from availableStorehouseList[].storageId returned by getConfirmation or getConfirmationWithCost |
| variantInfoList | Variant info list | list | Y | Product details | |
| variantInfoList[].id | Variant ID | string | Y | 200 | |
| variantInfoList[].quantity | Quantity | integer | Y | 20 |
# Response fields
| Field | Type | Description |
|---|---|---|
| storageId | string | Warehouse ID used for this logistics query |
| availableLogisticList | list | Available logistics list for the selected warehouse and products |
| availableLogisticList[].logisticName | string | Logistics name used by create order and cost matching |
| availableLogisticList[].displayName | string | Logistics display name |
| availableLogisticList[].logisticCode | string | Logistics code, returned when available |
| availableLogisticList[].shippingCost | number | Logistics fee in USD with 2 decimal places |
| availableLogisticList[].estimateDays | string | Estimated delivery time, returned when available |
| availableLogisticList[].freightIndex | integer | Logistics fee row index, starting from 0 |
| availableLogisticList[].selected | boolean | Selected status in the logistics result; final creation uses the logisticName selected by the caller |
| selectedLogisticName | string | Selected logistics name; empty when no logistics is selected |
| logisticInfoMessage | string | Message returned when storageId is missing or no logistics are returned; normally empty when logistics are available |
# 7.6 Get Private Inventory Cost Details (POST)
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/getCostInfo
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/getCostInfo' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"storageId": "WAREHOUSE-HZ-001",
"variantInfoList": [
{"id": "V001-SKU-A", "quantity": 100}
]
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| storageId | Storage ID | string | Y | 200 | Select from availableStorehouseList[].storageId returned by confirmation |
| variantInfoList | Variant info list | list | Y | Product details | |
| variantInfoList[].id | Variant ID | string | Y | 200 | |
| variantInfoList[].quantity | Quantity | integer | Y | 20 | |
| logisticName | Selected logistics name | string | N | 200 | Optional; used to match a selected freight row for cost/integrated amount calculation. Omit it when only querying logistics candidates. |
# Response fields
| Field | Definition | Type | Note |
|---|---|---|---|
| data.freightAmount / data.logisticsCost / data.shippingCost | Logistics fee | number | Field name depends on the cost result |
| data.warehouseFee / data.storehouseCost | Warehouse/outbound fee | number | Field name depends on the cost result |
| data.serviceFee | Service fee | number | USD |
| data.freightTrialList | Available logistics freight rows | list | Source of logistics/list.availableLogisticList |
| data.freightTrialList[].logisticName / enName | Logistics name | string | Candidate value for createOrder.logisticName |
| data.freightTrialList[].shippingCost | Shipping fee | number | USD |
| data.freightTrialList[].selected | Selected flag | boolean | If client-passed logisticName does not match, OpenAPI does not fall back to this default selected value. |
| data.costDetails | Cost details | list | Returned when available |
| data.errorEnList / data.errorSuggestionList | Errors and suggestions | list | Returned when available |
# 7.7 Get Confirmation with Cost Details (POST)
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/getConfirmationWithCost
This API returns confirmation data, warehouse options, and cost details in one response. Call it without storageId to get warehouse options; pass the selected storageId to get cost details; pass the selected logisticName to get the final amount.
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/getConfirmationWithCost' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"storageId": "WAREHOUSE-HZ-001",
"logisticName": "CJ Packet Ordinary",
"variants": [
{"variantId": "V001-SKU-A", "productId": "422C91F3-B7D0-47F3-BC66-5E1FE3208BBA", "quantity": 100}
]
}'
# Request parameters
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| storageId | Selected warehouse ID | string | N | 200 | Select from availableStorehouseList[].storageId. Required when cost details are needed. |
| logisticName | Selected logistics name | string | N | 200 | Select from logistics/list.availableLogisticList[].logisticName when amountDetail.totalAmount is needed. |
| variants | Variant list | list | N | Recommended for direct selected-product confirmation. Multiple product lines are supported. | |
| variants[].variantId | Variant ID | string | Required when using variants | 200 | |
| variants[].productId | Product ID | string | Required when using variants | 200 | |
| variants[].quantity | Quantity | integer | Required when using variants | 20 | Quantity to confirm for this SKU. |
First call this API without storageId; pass storageId after the warehouse is selected; pass logisticName after the logistics option is selected to get the final amount.
# Candidate warehouse fields
availableStorehouseList is the warehouse selection list for both getConfirmation and getConfirmationWithCost. Fields are:
| Field | Type | Description |
|---|---|---|
| availableStorehouseList[].storageId | string | Warehouse ID that can be passed as storageId in logistics, cost, confirmation-with-cost, or create-order requests. |
| availableStorehouseList[].displayName | string | Warehouse name. |
| availableStorehouseList[].countryCode | string | Warehouse country/region code |
| availableStorehouseList[].areaId | integer | Warehouse area ID |
| availableStorehouseList[].addresses | string | Warehouse address |
| availableStorehouseList[].address | string | Warehouse address alias for direct client use |
| availableStorehouseList[].zipCode | string | Warehouse zip code when returned |
| availableStorehouseList[].selected | boolean | Whether this warehouse was passed in this request and is used for cost calculation. It is false when storageId is omitted or does not match |
# Response data structure
| Field | Type | Description |
|---|---|---|
| confirmation | object | Confirmation data. Warehouse candidates are returned at top-level availableStorehouseList. |
| confirmation.orders | list | Confirmation order groups with product, logistics, and amount information. |
| confirmation.orders[].products | list | Confirmed product lines returned directly under an order group when available. |
| confirmation.orders[].confirmGroupOrderVOList[].products | list | Confirmed product lines returned under group objects when available. |
| confirmation.orders[].logisticList | list | Confirmation-page logistics candidates. Use logistics/list.availableLogisticList for final create-order logistics selection. |
| availableStorehouseList | list | Candidate warehouse list, including warehouse ID, warehouse name, country/region, address, zip code, and selected status. |
| selectedStorageId | string | Warehouse ID passed in this request and found in candidates; empty when omitted or unavailable |
| selectedStorehouse | object | Matched warehouse object with the same fields as availableStorehouseList[], with selected=true; empty when omitted or unavailable |
| costInfo | object | Cost details for the selected warehouse, same as getCostInfo.data; returned only when a valid storageId is passed. |
| amountDetail | object | Amount summary. All amounts are in USD with 2 decimal places. It includes product line amounts, service fee, and the selected shipping fee. totalAmount is returned only when warehouse and logistics are selected and all key amounts exist |
| amountDetail.productAmountList | list | Product line amount details, including variantId, productId, sku, quantity, final stock-up unit price unitPrice, and line subtotal productAmount; wholesale price or other price types are not returned |
| amountDetail.productAmountList[].unitPrice | number | Final stock-up unit price, USD, 2 decimal places |
| amountDetail.productAmountList[].productAmount | number | Product line subtotal, USD, 2 decimal places |
| amountDetail.productAmount | number | Product total amount in USD with 2 decimal places; empty if any product amount is missing |
| amountDetail.serviceFee | number | Service fee in USD with 2 decimal places from costInfo.serviceFee |
| amountDetail.requestedLogisticName | string | Logistics name passed in this request and used to match a freight row; empty if not passed |
| amountDetail.selectedFreight | object | Freight row used for the total. If logisticName is passed but not matched, this field is empty and total amount is not calculated. |
| amountDetail.shippingCost | number | Selected shipping fee in USD with 2 decimal places from amountDetail.selectedFreight.shippingCost |
| amountDetail.totalAmount | number | Product amount + service fee + shipping fee in USD with 2 decimal places; returned only when warehouse and logistics are selected and all key amounts exist |
| amountDetail.totalAmountCalculated | boolean | Whether the total amount is calculated successfully. If false, check missingAmountItems. |
| amountDetail.missingAmountItems | list | Missing amount items. When logistics is not selected, it usually contains selectedFreight; the total amount is not forced when any key item is missing |
| costInfoMessage | string | Explanation returned when storageId is missing, unavailable, no warehouse is available, or variant info is unavailable for cost calculation; normally empty when costInfo exists |
# 7.8 Create Private Inventory Order (POST)
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/createOrder
Before creating a private-inventory order, make sure the products, warehouse, logistics option, and payment option are selected. Page payment returns a payment page URL; for balance payment, use the create result to continue with the private-inventory balance payment API.
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/createOrder' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"productList": [
{"variantId": "V001-SKU-A", "productId": "422C91F3-B7D0-47F3-BC66-5E1FE3208BBA", "sku": "CJJJJTJT00873-Black", "quantity": 100},
{"variantId": "V002-SKU-B", "productId": "D9B2A2E0-88A1-44A6-9F7D-PRIVATE-B", "sku": "CJJJJTJT00873-White", "quantity": 50}
],
"logisticName": "CJ Packet Ordinary",
"storageId": "WAREHOUSE-HZ-001",
"payType": 1
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| productList | Final product list | list | Y | Cannot be empty and may contain multiple product lines. | |
| productList[].variantId | Variant ID | string | Y | 200 | SKU/variant ID |
| productList[].productId | Product ID | string | Y | 200 | |
| productList[].sku | SKU | string | Y | 200 | |
| productList[].quantity | Quantity | integer | Y | 20 | Final order quantity for this SKU |
| productList[].price | Final stock-up unit price | BigDecimal | N | (18,2) | Optional and not required. It is not used for order billing; use the price returned by the API. |
| logisticName | Logistics name | string | Y | 200 | Select from availableLogisticList[].logisticName returned by logistics/list |
| storageId | Storage ID | string | Y | 200 | Select from availableStorehouseList[].storageId returned by getConfirmation or getConfirmationWithCost |
| payType | Payment option | integer | N | 10 | 1=page payment, returns a payment page URL after order creation; 2=balance payment |
For page payment, a payment page URL is returned after the order is created. For balance payment, call the private-inventory balance payment API with the order number and payment ID from the create result.
# Response fields
| Field | Definition | Type | Note |
|---|---|---|---|
| data.orderId / data.orderCode | SY order number | string | Private-inventory order number after successful creation. The field name depends on the create result. |
| data.payId | Payment order ID | string | Returned when available |
| data.cjPayUrl | Payment page URL | string | Returned for page payment |
| data.price | Created order amount | number | USD, returned when available |
| data.riskInterceptOrderList | Risk-intercepted orders | list | May be returned when risk control blocks the order |
| data.checkPlaceOrderInfo | Orderability check details | object | Returned when orderability validation fails |
| data.checkPlaceOrderInfo.confirmStatus | Orderable flag | boolean | false means the submitted product, warehouse, logistics, inventory, price, or weight is not currently orderable |
| data.checkPlaceOrderInfo.productInfoVOList | Unavailable products | list | Contains variant ID, SKU, and unavailable reason |
| data.availableLogisticList | Current available logistics | list | Returned when logisticName is unavailable; fields are the same as logistics/list.availableLogisticList |
| data.requestedLogisticName | Requested logistics name | string | Logistics name submitted but not matched |
After the order is created, open the private-inventory order list (opens new window) to view it; to locate one order directly, search the order number on the page or append
&orderNumber=ORDER_NUMBERto the link.
# 7.9 Balance Payment V2 (POST)
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/pay/payBalanceV2
This API supports balance payment for multiple order types, distinguished by orderType:
- Private-inventory order (orderType=9): Pay after creating a private-inventory order. Use
data.orderIdordata.orderCodefromcreateOrderasshipmentOrderId;payIdis optional. - Makeup bill (orderType=24): Pay a makeup payment order created by
makeup/createPayOrderusing account balance. Use thedata.payOrderCodefromcreatePayOrderasshipmentOrderId;payIdis required (usecreatePayOrder→data.payId). - Default (no orderType): Normal dropshipping-order balance payment.
# CURL - Private-inventory order example
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/pay/payBalanceV2' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"shipmentOrderId": "SY1234567890",
"orderType": 9,
"payId": "PAY1234567890"
}'
# CURL - Makeup bill example
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/pay/payBalanceV2' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"shipmentOrderId": "2605260000000001",
"orderType": 24,
"payId": "PAY260526000001"
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| shipmentOrderId | Order number | string | Y | 100 | Private-inventory: use createOrder → orderId; Makeup: use createPayOrder → payOrderCode |
| orderType | Order type | integer | N | 20 | 9=private-inventory; 24=makeup bill (MD_BK parent-order makeup); omit for normal dropshipping |
| payId | Payment ID | string | N/required | 100 | Optional for private-inventory; required for makeup bill — use createPayOrder → data.payId |
# Response fields
| Field | Definition | Type | Note |
|---|---|---|---|
| code | Error code | int | See the error code standard table |
| result | Success flag | boolean | true means the API was processed successfully |
| message | Response message | string | Processing result message |
| data | Payment result identifier | string | Usually the order number for this payment; use the actual response value |
| requestId | Request ID | string | For troubleshooting |
# 7.10 Query Private Inventory Order List (POST)
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/order/list
Type 1 uses the existing Direct/Sample order set, not a sample-only filter. Type 3 retains existing deposit-query behavior and may return no records.
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/order/list' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"pageNum": 1,
"pageSize": 10,
"orderContent": "SY1234567890",
"createOrderDateStart": 1717200000000,
"createOrderDateEnd": 1719791999000
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| pageNum | Page number | integer | N | 20 | Default 1, minimum 1. Specifies which page to return |
| pageSize | Page size | integer | N | 20 | Default 10, maximum 200. A larger value returns a parameter error |
| orderType | Procurement type | integer | N | 1 | Default 2; 1=Direct/Sample, 2=Private inventory, 3=Deposit, 4=Wholesale. Query only; creation/payment types are unchanged |
| orderContent | Search keyword | string | N | 100 | Pass one keyword at a time. Supports private-inventory order number starting with SY, payment order number, SKU, product name, and other searchable order-list content |
| orderStatus | Order status | string | N | 50 | Common values: 3=Awaiting Payment, 11=Payment Incoming, 10=Pending, 6=Awaiting Dispatch, 12=Dispatched, 7=Completed, 13=Closed, 8=Canceled. If omitted, orders in viewable statuses are returned |
| payStatus | Unpaid sub-status | integer | N | 1 | Only works when orderStatus=3. Empty=Awaiting Payment and Payment Incoming, 0=Awaiting Payment only, 1=Payment Incoming only |
| createOrderDateStart | Created time start | long | N | 20 | Millisecond timestamp. Returns orders created after this timestamp |
| createOrderDateEnd | Created time end | long | N | 20 | Millisecond timestamp. Returns orders created before this timestamp |
| isAmountDifference | Amount difference flag | integer | N | 1 | Empty=no filter, 1=orders with amount differences only, 0=orders without amount differences only |
# Response fields
| Field | Definition | Type | Note |
|---|---|---|---|
| data.pageSize | Page size | number | Page size of this response |
| data.pageNumber | Page number | number | Page number of this response |
| data.totalRecords | Total records | number | Total orders matching the filters |
| data.totalPages | Total pages | number | Total pages calculated by pageSize |
| data.content | Order list | list | Private-inventory order details on the current page |
data.content[] order fields:
| Field | Definition | Type | Note |
|---|---|---|---|
| orderCode | SY order number | string | Unique private-inventory order number |
| status | Order status code | string | Examples: 3, 11, 10, 6, 12, 7, 13, 8 |
| statusDesc | Order status description | string | Display text such as Awaiting Payment, Pending, or Dispatched |
| disputeStatus | Dispute-related order status | string | Returned when dispute records exist |
| storageId | Warehouse ID | string | Private-inventory warehouse ID used by the order |
| storageNo2Name | Warehouse name | string | Warehouse English name or display name |
| stockout | Stockout flag | boolean | true means the order has stockout information |
| logisticName | Logistics name | string | Logistics route selected when the order was created |
| logisticsMode | Logistics mode | string | Logistics method or route type |
| postage | Postage | number | Amount in USD |
| showPostage | Display postage | number | Amount converted to the account display currency |
| trackingNumber | Tracking number | string | Carrier tracking number, returned when available |
| cjTrackingNumber | CJ tracking number | string | CJ-side tracking number, returned when available |
| paymentExpirationTime | Payment expiration time | number | Millisecond timestamp for unpaid orders |
| inventoryReserved | Inventory reserved flag | boolean | Usually true when the order is unpaid and not expired |
| createDate | Created time | string | Example: 2021-10-12 01:33 |
| createDateTime | Created timestamp | number | Millisecond timestamp |
| paymentDate | Paid time | string | Returned after payment, same format as createDate |
| paymentDateTime | Paid timestamp | number | Millisecond timestamp, returned after payment |
| orderAmount | Product subtotal | number | Product amount in USD |
| showOrderAmount | Display product subtotal | number | Product amount converted to the account display currency |
| amount | Order total | number | Total amount in USD, usually including products, postage, service fee, and taxes |
| showAmount | Display order total | number | Total amount converted to the account display currency |
| payableAmount | Payable strikethrough amount | number | Original or payable display amount when available |
| showPayableAmount | Display payable strikethrough amount | number | Converted amount in the account display currency |
| discountMoney | Platform discount amount | number | Discount amount in USD |
| productDiscountMoney | Product discount amount | number | Product discount in USD |
| postageDiscountMoney | Postage discount amount | number | Postage discount in USD |
| serviceFee | Service fee | number | Service fee in USD |
| showServiceFee | Display service fee | number | Service fee converted to the account display currency |
| iossNumber | IOSS number | string | Returned when IOSS declaration is used |
| iossType | IOSS declaration type | integer | 1=do not use IOSS, 2=use my IOSS, 3=use CJ IOSS |
| iossTaxes | IOSS taxes | number | Tax amount in USD |
| taxesFlag | Tax payment-on-behalf flag | integer | 0=no, 1=yes |
| taxesType | Tax type | integer | 0=none, 1=EU IOSS, 2=Brazil Duty tax |
| orderQuantity | Total item quantity | integer | Sum of all item quantities in the order |
| stockoutRefundStatus | Stockout refund status | string | 0=pending refund, 1=refunded, 2=rejected |
| impStorageFlag | Inventory-order flag | string | Private-inventory related flag |
| isContainPack | Contains packaging products | integer | 0=no, 1=yes |
| orderSourceType | Order source type | string | For example Excel upload or store synchronization |
| paymentSign | Payment-in-progress prompt flag | string | 0=no prompt, 1=bank card payment in progress prompt |
| handlerResult | Stockout handling result | string | Split shipment, replacement, stockout refund, etc. |
| refundAmount | Refund amount | number | Returned when a refund exists |
| refundStatus | Refund status | integer | 1=pending refund, 2=refunded |
| refundTime | Refund time | string | Returned when a refund exists |
| orderType | Order type | integer | Same codes as the orderType filter: 1=Direct/Sample, 2=Private inventory, 3=Deposit, 4=Wholesale. Historical orders may return null or 0 |
| orderCategory | Order category | string | Private-inventory orders are usually SY |
| paymentType | Payment type | string | Stripe, PayPal, Checkout, etc.; may be returned after payment |
| variantTypeSum | Variant type count | integer | Number of SKU/variant types in the order |
| diffType | Difference source type | integer | 1=manual creation, 2=order review, 3=postage supplement |
| diffAmount | Difference amount | number | Difference amount in USD |
| showDiffAmount | Display difference amount | number | Difference amount converted to the account display currency |
| openDispute | Can open dispute | boolean | true means the current status allows opening a dispute |
| abnormalPerformanceType | Fulfillment exception type | integer | 0=none, 1=exception, 2=completed |
| paymentOrderCodeList | Payment order numbers | list | Payment order numbers associated with this order |
| isRepeatPayment | Repeat payment flag | integer | 0=no, 1=yes |
| isShowInventoryRecord | Show inventory record flag | integer | 0=do not show, 1=show |
| canPayPostage | Can pay postage flag | integer | Returned when postage supplement payment may be needed |
| postagePayStatus | Postage payment status | integer | 1=waiting for logistics info, 2=to be paid, 3=payment in progress, 4=paid |
| postagePayStatusDesc | Postage payment status description | string | Display text for postage payment status |
| postagePayStatusRemark | Postage payment remark | string | Extra description for the postage payment status |
| selfPickAddressInfo | Self-pickup address information | object | Returned for self-pickup orders |
| selfPickCode | Self-pickup code | string | Returned for self-pickup orders |
| currencyInfo | Currency information | object | Display currency, exchange rate, and related information |
| isReceipt | Receipt flag | integer | 0=no, 1=yes |
| canViewWarehouseVideo | Can view warehouse operation video | boolean | true means the video can be viewed |
| noViewWarehouseVideoReason | Reason video cannot be viewed | integer | Reason code returned when video cannot be viewed |
data.content[].supplierList[] and product fields:
| Field | Definition | Type | Note |
|---|---|---|---|
| supplierId | Supplier ID | string | Supplier ID of the products |
| supplierName | Supplier name | string | Supplier display name |
| productList | SPU list | list | Products grouped by supplier |
| productList[].productId | Product ID | string | CJ product SPU ID |
| productList[].productVariantListList | Variant list | list | SKU/variant list under the product |
| productVariantListList[].productCode | Order product ID | string | Order product line ID |
| productVariantListList[].orderCode | Order number | string | Same as orderCode |
| productVariantListList[].stanProductId | Variant ID | string | CJ product variant ID |
| productVariantListList[].sku | SKU | string | Product SKU |
| productVariantListList[].cjProductId | Product ID | string | CJ product SPU ID |
| productVariantListList[].cjProductName | Product name | string | CJ product English name |
| productVariantListList[].cjImage | Product image | string | Product image URL |
| productVariantListList[].property | Property | string | Product property |
| productVariantListList[].variantKey | Variant key | string | Variant specification value |
| productVariantListList[].quantity | Quantity | integer | Purchased quantity |
| productVariantListList[].allocateNum | Allocated quantity | integer | Quantity stocked in or allocated from inventory |
| productVariantListList[].originalPrice | Original price | number | Original price in USD |
| productVariantListList[].showOriginalPrice | Display original price | number | Original price converted to the account display currency |
| productVariantListList[].price | Unit price | number | Unit price in USD |
| productVariantListList[].showPrice | Display unit price | number | Unit price converted to the account display currency |
| productVariantListList[].discount | Discount rate | number | Returned when a discount exists |
| productVariantListList[].weight | Weight | number | Product weight, usually in grams |
| productVariantListList[].refundStatus | Product refund status | integer | 1=pending refund, 2=refunded |
| productVariantListList[].productType | Product type | string | Product type identifier |
| productVariantListList[].stockout | Stockout flag | boolean | true means this product is out of stock |
| productVariantListList[].handlerResult | Product handling result | string | Stockout or exception handling result |
| productVariantListList[].originalSku | Original SKU | string | Returned when the SKU has changed |
| productVariantListList[].groupProduct | Group product flag | boolean | true means this is a bundle/group product |
| productVariantListList[].isPod | POD product flag | integer | POD product identifier |
| productVariantListList[].unCertified | Missing product information flag | integer | 1=product information missing; other values mean complete |
| productVariantListList[].productGroupChildList | Child products | list | Returned for bundle/group products |
| productGroupChildList[].id | Child variant ID | string | Child product variant ID |
| productGroupChildList[].sku | Child SKU | string | Child product SKU |
| productGroupChildList[].nameEn | Child product name | string | Child product English name |
| productGroupChildList[].image | Child product image | string | Child product image URL |
| productGroupChildList[].itemCount | Child quantity | integer | Child product quantity |
| productGroupChildList[].allocateNum | Child allocated quantity | integer | Quantity stocked in or allocated for the child product |
| productGroupChildList[].variantKey | Child variant key | string | Child product specification value |
| productGroupChildList[].packWeight | Child package weight | number | Single package weight |
| productGroupChildList[].totalPackWeight | Child total package weight | number | Quantity multiplied by package weight |
| productGroupChildList[].price | Child product price | number | Price in USD |
The response may include more order display fields. Use the fields above as the main reference; unlisted extension fields should be interpreted according to the actual returned value.
# Common Return
success
{
"code": 200,
"result": true,
"message": "Success",
"data": {},
"requestId": "2b97f15603384fe4832e85617cf07d9c"
}
error
{
"code": 1600100,
"result": false,
"message": "Param error",
"data": null,
"requestId": "2b97f15603384fe4832e85617cf07d9c"
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| code | Error code | int | 20 | Reference error code |
| result | Whether the return is normal | boolean | 1 | |
| message | Return message | string | 200 | Parameter or business error message when the query fails |
| data | Return data | object | Order-list pagination data on success, or null on failure | |
| requestId | Request ID | string | 48 | Used for log troubleshooting |
# 8 Private Inventory Outbound Orders
Private inventory outbound APIs let an OpenAPI client create an OMS private inventory outbound order, poll inventory-lock progress, submit the outbound order, and check payment/parent-order status. All APIs use the account resolved from CJ-Access-Token. Do not pass customer identity or OMS internal fields such as userNum, userId, merchantId, permissionCode, systemInvoke, createUserId, createUserName, thirdStorage, or deliveryType.
The private inventory used for outbound can be reviewed by signing in to MyCJ and opening the “Warehouse → Private Inventory” module to view the corresponding private order and inventory information.
# 8.1 API list
| API | Method | Description |
|---|---|---|
/api2.0/v1/shopping/privateInventory/outbound/address/list | POST | Query address candidates for the current token user |
/api2.0/v1/shopping/privateInventory/outbound/product/query | POST | Query outboundable products by warehouse, SKU/SPU, or privateOrderId |
/api2.0/v1/shopping/privateInventory/outbound/product/batch-refresh | POST | Refresh selected products before creation |
/api2.0/v1/shopping/privateInventory/outbound/create | POST | Create or update an outbound order; submit=true can submit after creation |
/api2.0/v1/shopping/privateInventory/outbound/progress | POST | Query creation progress, lock failures, submit/payment status |
/api2.0/v1/shopping/privateInventory/outbound/submit | POST | Submit an outbound order |
/api2.0/v1/shopping/privateInventory/outbound/detail | POST | Query outbound order detail |
/api2.0/v1/shopping/privateInventory/outbound/cancel | POST | Cancel an unfinished outbound order |
Recommended flow: address/list → product/query → product/batch-refresh → create → poll progress; after creation completes, call submit or create with submit=true, then keep polling progress for payment/parent-order status. If submit returns insufficient inventory or lock failure, do not retry the same request. Query detail, reduce quantities or remove failed product lines, call create again with the same orderId, and submit again after progress becomes submit-ready.
# 8.1.1 Sequence Diagram and Integration Notes
Endpoint labels using outbound/... become clickable after the page renders; click the blue underlined endpoint text inside the diagram to jump to the matching API section.
sequenceDiagram
autonumber
participant Client as OpenAPI Client
participant API as CJ OpenAPI
Client->>API: outbound/address/list query address candidates
API-->>Client: address candidates
Client->>API: outbound/product/query(storageId, skuOrSpu/privateOrderId)
API-->>Client: product candidates
Client->>API: outbound/product/batch-refresh(products)
API-->>Client: latest outboundable quantity
Client->>API: outbound/create(form, address, productList, submit)
API-->>Client: orderId + nextAction=POLL_CREATE_PROGRESS
loop Poll creation progress
Client->>API: outbound/progress(orderId)
API-->>Client: createProgress/createStatus/lockFails/nextAction
end
alt lockFails not empty or nextAction=ADJUST_LOCK_FAIL_PRODUCTS
Client->>API: outbound/detail(orderId)
API-->>Client: outbound order and product-line echo data
Client->>API: outbound/create(orderId + adjusted product lines)
API-->>Client: orderId + nextAction
else lockFails empty and nextAction=SUBMIT_ORDER
Client->>API: outbound/submit(orderId)
API-->>Client: submitAccepted + nextAction
end
Client->>API: outbound/progress(orderId)
API-->>Client: submitStatus/paymentStatus/shipmentOrderId/paymentOrderId
opt Query detail or cancel an unfinished outbound order
Client->>API: outbound/detail(orderId)
API-->>Client: outbound order detail
Client->>API: outbound/cancel(orderId, reason)
API-->>Client: cancel result
end
Integration note: OpenAPI customers do not use OMS page login and should not pass internal identity fields such as userId, userNum, or customerNo. Customer identity is resolved from CJ-Access-Token and injected server side. Clients should follow /progress and /submit responses to decide the next action.
# 8.1.2 Address Module and Outbound Address Reuse Sequence
The Address Management module maintains the address book for the current account. Prepare address data through List Addresses, Create Address, and Update Address, then call the private-inventory outbound address/list to get address candidates for the current token and fill the address object in create. The current public Address Management docs expose list, create, and update only; no public delete-address endpoint was found, so the sequence diagram does not include a delete flow.
Endpoint labels using Address module address/... and outbound/... become clickable after the page renders.
sequenceDiagram
autonumber
participant Client as OpenAPI Client
participant API as CJ OpenAPI
Client->>API: Address module address/list query address book
API-->>Client: Address book list
opt Need to create address
Client->>API: Address module address/create submit full address fields
API-->>Client: Operation result
end
opt Need to update address
Client->>API: Address module address/update(id + full address fields)
API-->>Client: Operation result
end
Client->>API: outbound/address/list get outbound address candidates
API-->>Client: Fields for create.address
Client->>API: outbound/create(address + productList)
API-->>Client: Return orderId and next action
# 8.2 Address List (POST)
URL: https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/outbound/address/list
The request body can be empty. Use the response fields to fill the address object in the create API.
Request example:
{}
Response example:
{
"code": 200,
"result": true,
"message": "Success",
"data": [
{
"id": "ADDR001",
"name": "Gilbert Soria",
"countryCode": "US",
"province": "OH",
"city": "HUBER HEIGHTS",
"address": "3419 BROADMOOR BLVD1",
"addressNew": "Apt 123",
"zip": "222260",
"phone": "9322331159",
"mail": "test@example.com"
}
]
}
| Response field | Type | Description |
|---|---|---|
| data[].id | string | Address record ID for address-book display only. |
| data[].name | string | Full recipient name; can fill address.customerName. |
| data[].firstName / data[].lastName | string | Recipient first name / last name. |
| data[].country / data[].countryCode | string | Country name / two-letter country code. |
| data[].province / data[].city / data[].countyTown | string | Province/state, city, county/town; countyTown can fill address.town. |
| data[].address / data[].addressNew | string | Address line 1 / address line 2. |
| data[].zip / data[].phone / data[].mail | string | ZIP code, phone, email. |
| data[].consigneeId | string | Consignee ID; can fill address.consigneeId. |
# 8.3 Query Outboundable Products (POST)
URL: https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/outbound/product/query
| Parameter | Definition | Type | Required | Note |
|---|---|---|---|---|
| storageId | Warehouse ID | string | Y | Selected outbound warehouse. |
| skuOrSpu | SKU/SPU keyword | string | N | Pass at least one of skuOrSpu and privateOrderId. |
| privateOrderId | Private inventory order number | string | N | Mapped to downstream privateOrderCode. |
| orderId | Outbound order number | string | N | Pass when updating an outbound order; mapped to downstream orderCode. |
| Response field | Type | Description |
|---|---|---|
| data[].id | string | Product-line ID; used when updating an existing outbound product line. |
| data[].uid | string | Row unique key, usually privateOrderId + stanProductId. |
| data[].productId / data[].spu / data[].sku | string | Product ID, SPU, SKU. |
| data[].stanProductId | string | Standard variant ID; required by the create API. |
| data[].productName / data[].productImg | string | Product name and image. |
| data[].value1 / data[].value2 / data[].value3 | string | SKU option values. |
| data[].price | number | Current display unit price from Product Center; OMS fetches the latest price again during creation. |
| data[].privateOrderId | string | Private inventory order number. |
| data[].availableQuantity | integer | Current outboundable quantity. |
| data[].lockQuantity | integer | Quantity already locked by the current outbound order when editing. |
# 8.4 Batch Refresh Selected Inventory (POST)
URL: https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/outbound/product/batch-refresh
| Parameter | Definition | Type | Required | Note |
|---|---|---|---|---|
| storageId | Warehouse ID | string | Y | Selected outbound warehouse. |
| orderId | Outbound order number | string | N | Used to exclude quantities already locked by the current order when editing. |
| products | Selected products | list | Y | Must not be empty. |
| products[].privateOrderId | Private inventory order number | string | Y | Mapped to downstream privateOrderCode. |
| products[].stanProductId | Standard variant ID | string | Y | Variant whose inventory needs refreshing. |
| products[].price | Display price | number | N | Inventory refresh does not rely on this field. |
Response example:
{
"code": 200,
"result": true,
"message": "Success",
"data": [
{
"privateOrderId": "PO26050001",
"stanProductId": "CJVAR001",
"uid": "PO26050001-CJVAR001",
"availableQuantity": 118
}
]
}
| Response field | Type | Description |
|---|---|---|
| data[].privateOrderId | string | Private inventory order number. |
| data[].stanProductId | string | Standard variant ID. |
| data[].uid | string | Row unique key. |
| data[].availableQuantity | integer | Current outboundable quantity. |
The current response mainly returns privateOrderId, stanProductId, uid, and availableQuantity. Use /product/query or /detail for full display fields such as name, image, SKU, and price.
# 8.5 Create Private Inventory Outbound Order (POST)
URL: https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/outbound/create
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/outbound/create' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"orderNumber": "OUTBOUND-API-001",
"storageId": "08898c4735bf43068d5d677c1d217ab0",
"platform": "API",
"storeName": "API Store",
"postagePayNode": 4,
"address": {
"customerName": "Gilbert Soria",
"shippingAddress": "3419 BROADMOOR BLVD1",
"shippingAddress2": "Apt 123",
"city": "HUBER HEIGHTS",
"country": "United States",
"countryCode": "US",
"province": "OH",
"zipCode": "222260",
"phone": "9322331159",
"email": "test@example.com"
},
"productList": [
{
"sku": "CJJJJTJT00873-Black",
"stanProductId": "CJVAR001",
"privateOrderId": "PO26050001",
"quantity": 2
}
],
"submit": false
}'
| Parameter | Definition | Type | Required | Note |
|---|---|---|---|---|
| orderId | Outbound order number | string | Required for update | Omit when creating; mapped to downstream orderCode. |
| orderNumber | Custom order number | string | Y | OMS custom order number. |
| storageId | Warehouse ID | string | Y | Shipping warehouse. |
| platform | Store platform | string | N | Defaults on the server if omitted. |
| storeName | Store name | string | N | Client display field. |
| postagePayNode | Postage payment node | integer | Y | 4=pay before outbound, 5=pay after outbound, 6=no payment required. |
| reason | Application reason | string | Required when postagePayNode=6 | Application reason. |
| reasonEn | English application reason | string | N | English application reason. |
| address.customerName | Recipient | string | Y | Can be filled from address-list name. |
| address.shippingAddress / address.shippingAddress2 | Address line 1 / line 2 | string | Line 1 required | Shipping address. |
| address.city / address.province / address.town | City / province / town | string | City required | town can be filled from address-list countyTown. |
| address.countryCode / address.country | Country code / country name | string | countryCode required | Two-letter country code is used by OMS validation. |
| address.zipCode / address.phone / address.email | ZIP / phone / email | string | N | Shipping contact fields. |
| address.taxId / address.consigneeId | Tax ID / consignee ID | string | N | Optional. |
| productList | Product lines | list | Y | Must not be empty. |
| productList[].id | Existing product-line ID | string | Required when updating a line | Omit when creating a new outbound order. |
| productList[].uid | Row unique key | string | N | Recommended for troubleshooting; current creation logic does not depend on it. |
| productList[].sku | SKU | string | Y | Product SKU. |
| productList[].stanProductId | Standard variant ID | string | Y | From /product/query. |
| productList[].price | Display price | number | N | Not a trusted input; OMS writes the latest Product Center price during creation. |
| productList[].privateOrderId | Private inventory order number | string | Y | Mapped to downstream privateOrderCode. |
| productList[].quantity | Outbound quantity | integer | Y | Must be greater than 0 and not exceed available inventory. |
| submit | Auto submit | boolean | N | Default false. |
Success response:
| Response field | Type | Description |
|---|---|---|
| data.orderId | string | Outbound order number; downstream field is orderCode. |
| data.createTaskStarted | boolean | Whether the async creation task has started. |
| data.submitRequested | boolean | Whether auto-submit was requested. |
| data.nextAction | string | Next action, usually POLL_CREATE_PROGRESS. |
# 8.6 Query Progress (POST)
URL: https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/outbound/progress
Request body:
{
"orderId": "SD260526000001"
}
Response example:
{
"code": 200,
"result": true,
"message": "Success",
"data": {
"orderId": "SD260526000001",
"createProgress": 60,
"createStatus": "CREATE_SUB_ORDER_SUCCESS",
"nextAction": "WAIT_LOCK_ARRIVE",
"lockFails": []
}
}
| Response field | Type | Description |
|---|---|---|
| data.orderId | string | Outbound order number. |
| data.progress / data.createProgress | number | Creation progress, currently mainly 0/60/100. |
| data.createStatus | string | PROCESSING, CREATE_SUB_ORDER_SUCCESS, TASK_COMPLETE, or LOCK_FAIL. |
| data.lockFails | list | Products that failed to lock inventory; adjust quantities if present. |
| data.lockFails[].sku / data.lockFails[].privateOrderId | string | Failed SKU / private inventory order number. |
| data.lockFails[].quantity / data.lockFails[].lockQuantity | integer | Requested outbound quantity / actual locked quantity. |
| data.nextAction | string | WAIT_CREATE, WAIT_LOCK_ARRIVE, ADJUST_LOCK_FAIL_PRODUCTS, SUBMIT_ORDER, etc. |
| data.submitStatus / data.paymentStatus | string | UNKNOWN when submit/payment aggregation is not returned by the current version. |
Lock-failure handling: when createStatus=LOCK_FAIL, nextAction=ADJUST_LOCK_FAIL_PRODUCTS, or lockFails is not empty, do not call /submit directly and do not keep relying on create.submit=true auto-submit. First call /detail to get the current outbound order and product-line echo data. Then delete failed product lines or reduce productList[].quantity according to lockFails[].lockQuantity / availableQuantity, call /create again with orderId to update the outbound order, and continue polling /progress until createProgress=100, createStatus=TASK_COMPLETE, lockFails is empty, and nextAction=SUBMIT_ORDER. Partial lock success does not mean the whole order can be submitted; submit only after every updated product line can be locked.
# 8.7 Submit Outbound Order (POST)
URL: https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/outbound/submit
| Parameter | Definition | Type | Required | Note |
|---|---|---|---|---|
| orderId | Outbound order number | string | Y | data.orderId returned by the create API. |
Response fields:
| Response field | Type | Description |
|---|---|---|
| data.orderId | string | Outbound order number. |
| data.submitAccepted | boolean | OMS has accepted the submit request. |
| data.nextAction | string | Next action, usually POLL_SUBMIT_PROGRESS, WAIT_APPROVAL, PAY, or FINISHED; ADJUST_LOCK_FAIL_PRODUCTS means inventory is insufficient or product lines failed to lock. |
Insufficient inventory / lock-failure response example:
{
"code": 1603001,
"result": false,
"message": "Private inventory is insufficient. Please call /shopping/privateInventory/outbound/detail, reduce productList.quantity or remove failed product lines, call /shopping/privateInventory/outbound/create again with the same orderId, then submit again.",
"data": {
"orderId": "SD260526000001",
"createStatus": "LOCK_FAIL",
"submitAccepted": false,
"nextAction": "ADJUST_LOCK_FAIL_PRODUCTS",
"actionRequired": "ADJUST_QUANTITY_AND_RESUBMIT",
"lockFails": [
{
"sku": "CJNSXZXX001-Black-S",
"privateOrderId": "SY260526000001",
"quantity": 10,
"lockQuantity": 6
}
],
"suggestedSteps": [
"Call /shopping/privateInventory/outbound/detail with orderId to review product lines.",
"Reduce productList.quantity or remove failed product lines according to lockFails/availableQuantity.",
"Call /shopping/privateInventory/outbound/create again with the same orderId to update the outbound order.",
"Poll /shopping/privateInventory/outbound/progress until lockFails is empty and nextAction is SUBMIT_ORDER, then submit again."
]
}
}
Before submitting, confirm that /progress returns a submit-ready status: lockFails must be empty, and nextAction must not be ADJUST_LOCK_FAIL_PRODUCTS. If /submit returns the insufficient-inventory / lock-failure business error above, this is not a system service exception. Adjust product quantities or remove failed product lines according to data.lockFails / availableQuantity, call /create again with the same orderId, keep polling /progress, and call /submit again only after the order becomes submit-ready.
After the outbound order is submitted successfully, the customer can sign in to MyCJ and view it on the https://www.cjdropshipping.com/mine/dropshipping/orderList?orderType=7 (opens new window) page.
# 8.8 Query Outbound Order Detail (POST)
URL: https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/outbound/detail
| Parameter | Definition | Type | Required | Note |
|---|---|---|---|---|
| orderId | Outbound order number | string | Y | Used for edit display, retry after lock failure, or detail view. |
Main response fields:
| Response field | Type | Description |
|---|---|---|
| data.orderId / data.orderNumber | string | Outbound order number / custom order number. |
| data.storageId / data.platform / data.storeName | string | Warehouse, store platform, and store name. |
| data.postagePayNode | integer | Postage payment node. |
| data.address | object | Shipping information, same fields as the create API address. |
| data.productList | list | Product lines, same fields as the create API plus display fields such as availableQuantity, lockQuantity, and price. |
| data.orderStatus / data.submitStatus | string | OMS order status / API aggregated submit status. |
# 8.9 Cancel Outbound Order (POST)
URL: https://developers.cjdropshipping.com/api2.0/v1/shopping/privateInventory/outbound/cancel
| Parameter | Definition | Type | Required | Note |
|---|---|---|---|---|
| orderId | Outbound order number | string | Y | Outbound order to cancel. |
| reason | Cancel reason | string | N | Client-side remark. |
Response fields:
| Response field | Type | Description |
|---|---|---|
| data.orderId | string | Cancelled outbound order number. Some OMS versions may return a boolean or raw downstream object. |
| data.cancelled | boolean | Whether cancellation succeeded. |
Submit, detail, and cancel APIs all verify that the outbound order belongs to the current
CJ-Access-Tokencustomer. If the OMS status does not allow the operation, the OMS error is returned.
# 9 Makeup / Supplement Payments
Makeup bill API path prefix: /api2.0/v1/shopping/makeup/*. Use it to list unpaid makeup bills, create a makeup payment order (returns payId and cjPayUrl), and pay by balance using the payId. type: 0=Make-up Orders / 1=Other Make-up; diffUseType subdivides Other Make-up usage.
# 9.1 Sequence Diagram
sequenceDiagram
autonumber
participant Client as OpenAPI Client
participant API as CJ OpenAPI
participant Browser as Browser/Payment Page
Client->>API: POST /shopping/makeup/list(pageNum, pageSize, type, diffUseType)
API-->>Client: Return makeup page data, unpaid counts, and unpaid total amount
Client->>API: POST /shopping/makeup/createPayOrder(orderCodes, type, diffUseType)
API-->>Client: Return payOrderCode, payId, amount, cjPayUrl, and paymentPagePath
alt Redirect to payment page
Client->>Browser: Redirect to cjPayUrl https://www.cjdropshipping.com/mine/payment?pid={payId}
Browser-->>Client: User completes payment on the payment page
else Direct balance payment
Client->>API: POST /shopping/pay/payBalanceV2(shipmentOrderId=payOrderCode, payId, orderType=24)
API-->>Client: Return balance payment result
end
Note over Client,API: After payId is created, the client either redirects to the payment page or calls POST /shopping/pay/payBalanceV2(orderType=24) to pay directly by balance
Client->>API: POST /shopping/makeup/list(pageNum, pageSize, type)
API-->>Client: Return refreshed makeup status
# 9.2 Get Makeup List (POST)
URL: https://developers.cjdropshipping.com/api2.0/v1/shopping/makeup/list
Request example:
{
"pageNum": 1,
"pageSize": 20,
"type": 0
}
| Parameter | Definition | Type | Required | Note |
|---|---|---|---|---|
| pageNum | Page number | integer | N | Default 1. |
| pageSize | Page size | integer | N | Default 10, maximum 200. |
| type | Supplement payment type | integer | N | 0=Make-up Orders, 1=Other Make-up. If empty, the API returns the first type that has unpaid records. |
| diffUseType | Supplement usage type | integer | N | Filter for type=1: 1=Balance Top-up, 2=Repayment, 3=Transfer Shipping Fee. For type=0, omit it or pass 0. |
Response example:
{
"code": 200,
"result": true,
"message": "Success",
"data": {
"type": 0,
"totalAmount": 12.35,
"unPaymentCountList": [
{ "type": 0, "count": 2 },
{ "type": 1, "count": 0 }
],
"pageData": {
"pageSize": 20,
"pageNumber": 1,
"totalRecords": 2,
"totalPages": 1,
"content": [
{
"orderCode": "BK260526000001",
"cjOrderCode": "ZF260526000001",
"status": 0,
"amount": 12.35,
"reason": "Postage difference",
"orderType": 1,
"diffUseType": 0,
"createAt": 1779763200000
}
]
}
},
"requestId": "2b97f15603384fe4832e85617cf07d9c"
}
| Response field | Type | Description |
|---|---|---|
| data.type | integer | Current supplement payment type. |
| data.totalAmount | number | Total unpaid amount under the current filter, in USD. |
| data.unPaymentCountList[].type / count | integer | Unpaid count by supplement payment type. |
| data.pageData.content[].orderCode | string | Makeup bill number, BT prefix (e.g. BT2606061320024499900); pass it in orderCodes when paying by balance. |
| data.pageData.content[].cjOrderCode | string | Original CJ order number being made up; type varies (private inventory outbound SD…, dropshipping/direct, etc.), e.g. SD2606060858539645300. |
| data.pageData.content[].status | integer | Status: 0=to submit, 1=processing, 2=failed, 3=cancelled, 4=completed, 5=paying. |
| data.pageData.content[].amount | number | Makeup amount, in USD. |
| data.pageData.content[].reason | string | English makeup reason. |
| data.pageData.content[].orderType | integer | Related order type: 1=dropshipping, 2=direct, 3=private inventory, 4=fulfillment service, 5=dispute refund. |
| data.pageData.content[].diffUseType | integer | Usage type: 0=order supplement payment, 1=Balance Top-up, 2=Repayment, 3=Transfer Shipping Fee. |
| data.pageData.content[].createAt | long | Created time, Unix timestamp in milliseconds. |
# 9.3 Create Makeup Payment Order (POST)
URL: https://developers.cjdropshipping.com/api2.0/v1/shopping/makeup/createPayOrder
This API matches the MyCJ page flow “select makeup bills → Pay”: take orderCode values from the makeup list, call this API, and receive a generated makeup payment order and payId. The page redirects to https://www.cjdropshipping.com/mine/payment?pid={payId} after receiving payId; OpenAPI returns the same-format cjPayUrl and the relative paymentPagePath for integration. This API only creates a payment order and does not pay by balance.
Request example:
{
"orderCodes": ["BT2606061320024499900"],
"type": 0
}
| Parameter | Definition | Type | Required | Note |
|---|---|---|---|---|
| orderCodes | Makeup bill numbers | array<string> | Y | Values from the makeup list orderCode; at least one value is required. |
| type | Supplement payment type | integer | N | Default 0; 0=Make-up Orders, 1=Other Make-up. |
| diffUseType | Supplement usage type | integer | Required when type=1 | For type=0, omit it or pass 0. For type=1, pass 1=Balance Top-up, 2=Repayment, or 3=Transfer Shipping Fee. |
Response example:
{
"code": 200,
"result": true,
"message": "Success",
"data": {
"payOrderCode": "2605260000000001",
"payId": "PAY260526000001",
"amount": 12.35,
"cjPayUrl": "https://www.cjdropshipping.com/mine/payment?pid=PAY260526000001",
"paymentPagePath": "/mine/payment?pid=PAY260526000001"
},
"requestId": "2b97f15603384fe4832e85617cf07d9c"
}
| Response field | Type | Description |
|---|---|---|
| data.payOrderCode | string | Payment order number generated for this makeup payment. |
| data.payId | string | Payment center pay ID; the MyCJ page uses it to open the payment page. |
| data.amount | number | Amount to pay, in USD. |
| data.cjPayUrl | string | Full CJ payment page URL, formatted as https://www.cjdropshipping.com/mine/payment?pid={payId}. |
| data.paymentPagePath | string | MyCJ payment page path, formatted as /mine/payment?pid={payId}. |
Makeup payment: after obtaining
payIdfromcreatePayOrder, the client can either redirect to thecjPayUrlpayment page, or call/shopping/pay/payBalanceV2(distinguished byorderType) to pay with the current account balance.
# Phase 2 query additions
# Order creation dates
GET /api2.0/v1/shopping/order/list accepts the following optional query parameters, including when status=CANCELLED.
| Parameter | Type | Required | Description |
|---|---|---|---|
| createDateFrom | integer (int64) | N | Inclusive creation time, UTC Unix milliseconds. |
| createDateTo | integer (int64) | N | Inclusive end time, UTC Unix milliseconds. |
Send both dates together, in ascending order, with a maximum interval of 90 days. Omit both to retain the existing query. These parameters are independent of payment-date filters and do not remove their existing restrictions.
# Dropshipping list and detail additions
Order lists expose a products array, with productCode and sku identifying each product and supplierId, supplierName, discount, and originalPrice holding its snapshots. The order-level postageDiscountPrice is original postage before discount (USD). This includes cancelled-history lists. Single, batch, and /shopping/order/queryOrderInfo detail responses expose the same stored snapshots under the following fields. Missing source values remain null. These fields do not change existing totals or product prices.
| Response field | Type | Description |
|---|---|---|
| postageDiscountPrice | decimal | Original postage before discount, USD. |
| productList[].supplierId | string | Supplier ID recorded on the order product. |
| productList[].supplierName | string | Supplier name recorded on the order product. |
| productList[].discount | decimal | Stored product discount value, returned without conversion. |
| productList[].originalPrice | decimal | Stored original product price, USD. |
# 9.4 Makeup History (POST)
/api2.0/v1/shopping/makeup/historyList
Read the current authenticated customer's makeup bills across non-draft states. Status codes: 1 = processing, 2 = failed, 3 = cancelled, 4 = completed, 5 = payment in progress; draft status 0 is excluded. The existing /makeup/list unpaid-bill endpoint retains its behavior.
| Request field | Type | Required | Description |
|---|---|---|---|
| pageNum | integer | N | Starts at 1; default 1. |
| pageSize | integer | N | 1–100; default 10. |
| status | integer[] | N | Nonempty subset of 1, 2, 3, 4, 5. Omit for all non-draft states. |
| diffUseType | integer | N | Known usage codes: 0 = order makeup payment, 1 = balance top-up, 2 = repayment, 3 = transfer shipping makeup payment. Omit to include all usages. |
| createDateFrom | integer (int64) | N | Inclusive creation time, UTC Unix milliseconds. |
| createDateTo | integer (int64) | N | Paired with createDateFrom; ascending range no longer than 90 days. |
{"pageNum":1,"pageSize":10,"status":[1,2,3,4,5]}
The response data contains pageSize, pageNumber, totalRecords, totalPages, and content. Each content entry contains orderCode, cjOrderCode, status, diffUseType, amount (USD), reason, createAt (UTC milliseconds), paymentDate (UTC milliseconds), and payOrderCode. Amounts and dates may be null when absent in the source. Reasons use the stored English translation when available, otherwise the original text. Invalid dates, status values, or pagination are rejected.
# 10 Split Order
Split an order that has not been submitted yet in My CJ "Store Orders" (Imported › Orders, Orders Picking) into multiple sub-orders by product. The rules are the same as splitting an order manually in My CJ. After the split, the original order becomes split, and each sub-order number is "original order number-split count-sequence", e.g. SD123-1-1, SD123-1-2; sub-orders split from a POD order get new order numbers starting with GX.
# 10.1 Call Sequence
- Get the order line items:
lineItemIdis returned by 1.1 Create Order V2 / 1.2 Create Order V3, 1.7 Query Order, 1.16 Query Orders In Batch and the order webhook; you can also usevid(every line in Query Order has it). - (Optional) Call 10.2 Get Splittable Items to check whether an order can be split and which line items can be assigned. You can also split directly without it.
- Submit the split plans with 10.3 Submit Split Task (1 to 100 orders at a time), then poll 10.4 Get Split Task until
taskStatusis 1 (completed) or 2 (failed); the new sub-order numbers are in the task result. - To get the products of each sub-order, query the sub-order numbers with 1.7 Query Order or 1.16 Query Orders In Batch.
After the split:
- All
lineItemIdvalues of the original order become invalid; sub-orders get newlineItemIdvalues.storeLineItemIdis kept from the original order and can be used to match line items before and after the split (store orders only; it may be empty for orders created via API, manually or by Excel, which can be matched byvidand quantity). - If a sub-order has incomplete product information (e.g. an invalid variant), it goes to Imported › Invalid Orders and is not included in the returned sub-order numbers.
- Right after the split, querying with the original order number may take a few seconds to return a sub-order.
- Splitting through the API does not send the split message (
ORDERSPLIT); use the sub-order numbers returned by the API. Accounts with order webhooks enabled receive one order message for the original order with statusOTHER. - Order logs are the same as splitting manually in My CJ.
# 10.2 Get Splittable Items (POST)
Check whether orders can be split and which line items can be assigned. This API is optional; you can split directly without calling it.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/splitOrder/getSplittableItems
# CURL
curl --location 'https://developers.cjdropshipping.com/api2.0/v1/shopping/splitOrder/getSplittableItems' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data '{
"orderCodeList": ["SD2510081234567890", "SD2510081234567999"]
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| orderCodeList | CJ order numbers | List<String> | Y | - | Up to 100 per request |
# Return
success
{
"code": 200,
"result": true,
"message": "Success",
"data": [
{
"orderCode": "SD2510081234567890",
"orderNumber": "#1001",
"canSplit": true,
"reason": null,
"supportQtySplit": true,
"productList": [
{
"lineItemId": "2510081234567891",
"vid": "2547992D-CEE1-4BFD-99AC-9E30354F771F",
"sku": "CJNSSYLY01043-Claret-S",
"quantity": 1,
"isGroup": false
},
{
"lineItemId": "2510081234567892",
"vid": "A9C95BCB-D824-4AA1-A389-E86F3CCB10EF",
"sku": "CJJSAQXF00016-Orange",
"quantity": 2,
"isGroup": false
}
]
},
{
"orderCode": "SD2510081234567999",
"orderNumber": "#1002",
"canSplit": false,
"reason": "Combined orders cannot be split. Please undo the combination first.",
"supportQtySplit": true,
"productList": []
}
],
"requestId": "9eddf3f5-bd3d-4fae-a4f2-028cbb90db97",
"success": true
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| data | Orders | Array | - | One element per order |
| - orderCode | CJ order number | string | 200 | |
| - orderNumber | Store order number | string | 200 | |
| - canSplit | Can be split | boolean | 1 | Based on the order rules in 10.5 |
| - reason | Why it cannot be split | string | 200 | Empty when splittable |
| - supportQtySplit | Can be split by quantity | boolean | 1 | When false, a line item can only be put into one sub-order as a whole (e.g. Temu orders) |
| - productList | Assignable line items | Array | - | Empty array when not splittable; packaging and bundle components are not included |
| -- lineItemId | Line item ID | string | 50 | |
| -- vid | Variant ID | string | 200 | |
| -- sku | Variant SKU | string | 200 | |
| -- quantity | Quantity of this line | int | 10 | |
| -- isGroup | Bundle product | boolean | 1 | Its components go to the same sub-order with it |
If any order number does not exist or does not belong to your account, the whole request returns order not found: {orderCode1}, {orderCode2}…; if there are too many orders, it returns Up to 100 orders per request.. On timeout, code is 1612001 and it returns The request timed out. Please try again later.; retry later.
# 10.3 Submit Split Task (POST)
Submit split plans for one or more orders. They are processed one by one. Up to 100 orders per task.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/splitOrder/submitTask
# CURL
curl --location 'https://developers.cjdropshipping.com/api2.0/v1/shopping/splitOrder/submitTask' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data '[
{
"orderCode": "SD2510081234567890",
"splitOrderList": [
{ "productList": [ { "vid": "A9C95BCB-D824-4AA1-A389-E86F3CCB10EF", "quantity": 1 } ] }
]
},
{
"orderCode": "SD2510081234567777",
"splitOrderList": [
{ "productList": [ { "lineItemId": "2510081234567781", "quantity": 3 } ] }
]
},
{
"orderCode": "SD2510081234567999",
"splitOrderList": [
{ "productList": [ { "lineItemId": "2510081234567991", "quantity": 1 } ] }
]
}
]'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| orderCode | CJ order number | string | Y | 200 | The request body is an array; each element is one order, up to 100. cjOrderCode in 1.7 Query Order (cjOrderId in 1.6 List Order) |
| splitOrderList | Sub-orders to split out | Array | Y | - | Each element is one sub-order |
| - productList | Products in this sub-order | Array | Y | - | Specify each product by lineItemId or vid, plus quantity |
| -- lineItemId | Line item ID | string | Either one | 50 | Pass either lineItemId or vid; lineItemId is used if both are passed |
| -- vid | Variant ID | string | Either one | 200 | Pass either lineItemId or vid; only when this variant has one line in the order, otherwise use lineItemId |
| -- quantity | Quantity in this sub-order | int | Y | 10 | Positive integer |
- Products not assigned to any sub-order (or the remaining quantity of a line) go to one last sub-order automatically.
- Do not pass packaging or bundle components; they follow their main product automatically and are rejected if passed.
- Temu orders can only be split by whole line items; a line item cannot be split across sub-orders.
# Return
success
{
"code": 200,
"result": true,
"message": "Success",
"data": {
"taskId": "1843210987654321"
},
"requestId": "7dc61955-c0e8-4731-bb9b-393b4fffeaaf",
"success": true
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| taskId | Task ID | string | 50 | Used by 10.4 |
The whole request is rejected (no task is created) when:
| Case | message |
|---|---|
| An order is missing a required field, or the request body is an empty array | {field} must be not empty (only the first missing field is reported) |
| Too many orders | Up to 100 orders per task. Please submit in batches. |
| The same order number appears more than once | duplicate orderCode: {orderCode} |
| An order number does not exist or does not belong to your account | order not found: {orderCode1}, {orderCode2}… |
| The previous submission is still being accepted | We are working on it. Please wait patiently. |
Other rules (the rules in 10.5 other than required fields) are checked order by order in the task; one failed order does not affect the others. On timeout, code is 1612001 and it returns The request timed out. Please query the orders before retrying.. If the request times out or you get no response (no task ID), query the original order numbers with 1.16 Query Orders In Batch to see whether sub-orders were created, or simply submit again: orders that were already split are only marked as failed and are not split twice.
# 10.4 Get Split Task (GET)
Get the task progress and, for each order, whether it was split, the sub-order numbers and the reason.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/splitOrder/getTask?taskId=1843210987654321
# CURL
curl --location 'https://developers.cjdropshipping.com/api2.0/v1/shopping/splitOrder/getTask?taskId=1843210987654321' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| taskId | Task ID | string | Y | 50 | taskId returned by 10.3 Submit Split Task |
# Return
success
{
"code": 200,
"result": true,
"message": "Success",
"data": {
"taskId": "1843210987654321",
"taskStatus": 1,
"total": 3,
"processed": 3,
"splitSuccessCount": 1,
"splitFailedCount": 1,
"nonSplittableCount": 1,
"splitSuccessList": [
{
"orderCode": "SD2510081234567890",
"orderNumber": "#1001",
"newOrderCodeList": ["SD2510081234567890-1-1", "SD2510081234567890-1-2"]
}
],
"splitFailedList": [
{
"orderCode": "SD2510081234567777",
"orderNumber": "#1003",
"reason": "quantity exceeds the order quantity: 2510081234567781"
}
],
"nonSplittableList": [
{
"orderCode": "SD2510081234567999",
"orderNumber": "#1002",
"reason": "Combined orders cannot be split. Please undo the combination first."
}
]
},
"requestId": "323fda9d-3c94-41dc-a944-5cc1b8baf5b1",
"success": true
}
| Field | Definition | Type | Length | Note |
|---|---|---|---|---|
| taskId | Task ID | string | 50 | |
| taskStatus | Task status | int | 1 | 0 processing; 1 completed; 2 failed (task interrupted) |
| total | Orders in the task | int | 10 | |
| processed | Orders processed | int | 10 | |
| splitSuccessCount | Split successfully | int | 10 | |
| splitFailedCount | Split failed | int | 10 | |
| nonSplittableCount | Non-splittable | int | 10 | |
| splitSuccessList | Orders split successfully | Array | - | While processing, only processed orders are listed (same below) |
| - orderCode | Original order number | string | 200 | |
| - orderNumber | Store order number | string | 200 | |
| - newOrderCodeList | Sub-order numbers | List<String> | - | |
| splitFailedList | Orders failed to split | Array | - | Each element has orderCode, orderNumber and reason |
| nonSplittableList | Non-splittable orders | Array | - | Each element has orderCode, orderNumber and reason |
- Poll at an interval of at least 2 seconds until
taskStatusis 1 (completed) or 2 (failed). taskStatus2 means the task was interrupted: results of processed orders are kept; orders not processed are listed insplitFailedListwith reasonThe task was interrupted before this order was processed. Please resubmit it.(orPrevious task login expired. Task failed.if the account credential expired). These orders were not split and can be submitted again.- If an order fails because of a processing error, the reason is
System error.. - If the task ID does not exist or does not belong to your account, it returns
task not found. - On timeout,
codeis 1612001 and it returnsThe request timed out. Please try again later.; retry later.
# 10.5 Split Rules and Error Messages
The rules below apply to 10.2–10.4. When a rule is not met, message is the matching reason; see the return code standard table for error codes.
| Rule | message |
|---|---|
| The order does not exist or does not belong to your account | order not found |
| Only orders in Imported › Orders and unsubmitted orders in Orders Picking can be split | Only unsubmitted orders in Imported > Orders or Orders Picking can be split. |
| The order has already been split (sub-orders can be split again) | Order has been split. Please don't split it twice. |
| Combined orders cannot be split; undo the combination in My CJ first | Combined orders cannot be split. Please undo the combination first. |
| Orders from store platforms that do not support splitting (e.g. TikTok, Shopee) | The platform reason, e.g. The TikTok order not support split |
| Abnormal orders cannot be split | Abnormal orders cannot be combined or split. |
| Supplier-shipped orders cannot be split | Sorry, the order cannot be split. |
| Pre-occupied orders cannot be split: release Occupied orders in My CJ (Release Pre-Occupy); wait until Occupying orders finish | Please release pre-occupy before performing this operation. |
| The order must have at least 2 splittable items | Single-item order cannot be split. |
| lineItemId / vid must match one assignable line item of the order; use lineItemId if the vid matches multiple lines | invalid lineItemId: {lineItemId} / invalid vid: {vid} / vid matches multiple line items, use lineItemId instead: {vid} |
| Quantity must be a positive integer, and the total of a line item across sub-orders cannot exceed its quantity | quantity must be a positive integer / quantity exceeds the order quantity: {lineItemId} |
| There must be at least 2 sub-orders after the split (including the one for remaining products) | At least 2 sub-orders are required. |
| Temu orders can only be split by whole line items | "Temu" orders do not support splitting by quantity. |
| A required field is empty | {field} must be not empty |
# Error Codes
| Error Code | Meaning | What to do |
|---|---|---|
| 1612001 | Try again later: the previous batch submission is still being accepted, or the request timed out (message is a timeout notice) | Retry later. On a timeout of 10.3, query the order first to check whether sub-orders were created before retrying |
| 1612003 | The order cannot be split or the request is invalid; message is the matching reason in the table above | Fix the order or the request according to message, then submit again |
| 1600000 | System busy (System busy, please contact CJ IT) | Retry later; contact CJ if it keeps failing |
# 11 Change Orders
Change an order the same way as on My CJ: update the shipping address, or cancel an unpaid order. Whether an order can be changed is decided by the order service with the same rules as My CJ; when it refuses, you get one of the codes below with the reason in message. Rate limit: the per-user QPS of your account level applies (1–6 requests/second, see Access Frequency Restrictions).
| Code | Meaning | What to do |
|---|---|---|
| 1613001 | Another change to your orders is being processed | Retry later |
| 1613002 | The request timed out and the result is unknown | Query the order with 1.7 Query Order before retrying |
| 1613003 | The order cannot be changed; message gives the reason (e.g. the order status changed, a tracking number has already been generated, the order source does not allow it, the address check failed) | Do not retry as is; fix the request according to message |
| 1603100 | The order does not exist or is not yours | Check the order number |
| 1600000 | System busy | Retry later; contact CJ if it keeps failing |
# 11.1 Update Shipping Address (POST)
Updates the shipping address of a sub-order. Send only the fields you want to change; fields you leave out (or send as null) keep their current values, and an empty string clears an optional field such as shippingAddress2. Required fields (shippingCustomerName, shippingCountryCode, shippingCountry, shippingCity, shippingAddress) can be changed but not cleared (1600300). Field names and lengths are the same as in 1.1 Create Order V2. If the order's current address is missing a required field, the change is refused with 1613003 and the field is named in message; if it is an address field (for example the city), send it as well, otherwise contact CJ.
What can be changed depends on the order status (same as My CJ):
| Order status | What can be changed | Shipping method |
|---|---|---|
Not paid yet (CREATED, IN_CART) | All fields, including country and zip code | Checked and re-quoted for the new address with logisticName (or the order's current shipping method if you leave it out). If that method cannot deliver to the new address, the change is refused with 1613003 and nothing is modified — when you change the country, send a logisticName that delivers there (see 1.1 Freight Calculation). In rare cases the method passes the check but cannot be quoted; it is then removed, logisticsCleared is true, and you must choose one with 1.14 Modify Order Logistics before paying |
Paid, held after payment because of the address (shown as UNPAID in 1.7) | All fields | Shipping method cannot be changed (a different logisticName returns 1613003); shipping cost is not re-quoted. If the price changes, the order may wait for a supplementary payment (9 Makeup / Supplement Payments) |
In a parent order but not paid yet (UNPAID), or paid with no tracking number yet | Name, address lines, phone, province, city, county, tax ID, email. Country, zip code and shipping method cannot be changed — sending a different value returns 1613003 | Unchanged. If the current shipping method cannot deliver to the new address, the change is refused and nothing is modified. If the warehouse has already started processing the order, the change is refused |
| Tracking number generated, or shipped | Cannot be changed (1613003) | — |
Orders from some sources (for example Temu US, TikTok US, Mabang, SHEIN, Temu cooperative warehouses) cannot be changed; the order service returns 1613003 with the reason.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/updateShippingAddress
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/updateShippingAddress' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data '{
"orderCode": "SD2611010000001",
"shippingAddress": "9 New Road",
"shippingPhone": "+1 555 0100"
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| orderCode | CJ sub-order number | string | Y | 50 | cjOrderCode from 1.7 Query Order |
| shippingCustomerName | Recipient name | string | N | 200 | |
| shippingCountryCode | Destination country code | string | N | 10 | Two-letter code. Must be sent together with shippingCountry |
| shippingCountry | Destination country | string | N | 100 | Must be sent together with shippingCountryCode |
| shippingProvince | Province / state | string | N | 200 | |
| shippingCity | City | string | N | 200 | |
| shippingCounty | County | string | N | 100 | |
| shippingAddress | Address line 1 | string | N | 500 | |
| shippingAddress2 | Address line 2 | string | N | 500 | |
| shippingZip | Zip code | string | N | 20 | |
| shippingPhone | Phone | string | N | 20 | |
| string | N | 100 | |||
| taxId | Tax ID | string | N | 50 | |
| consigneeID | Consignee ID | string | N | 100 | |
| logisticName | Shipping method | string | N | 50 | Only for orders not paid yet (CREATED, IN_CART). Same as logisticName in 1.1; the new address is checked and quoted with it. Leave it out (or empty) to keep the current method |
At least one address field is required.
# Return
{
"code": 200,
"result": true,
"message": "Success",
"data": {
"orderCode": "SD2611010000001",
"logisticName": "CJPacket Ordinary",
"logisticsCleared": false
},
"requestId": "2c4e6a8b-0d1f-4e3a-8c5b-7d9e1f3a5b7c"
}
| Field | Definition | Type | Note |
|---|---|---|---|
| orderCode | CJ sub-order number | string | |
| logisticName | Shipping method after the change | string | null if the order has no shipping method |
| logisticsCleared | The change removed the order's shipping method | boolean | Choose a new one with 1.14 before paying. If both logisticName and logisticsCleared are null, the address was changed but the result could not be read back — check the order with 1.7 |
Shipping cost and order amount may change; query them with 1.7 Query Order.
# 11.2 Cancel Order (POST)
Cancels an unpaid parent order, or removes one sub-order from an unpaid parent order — the same as Cancel on My CJ. This is not a refund: paid orders cannot be cancelled with this endpoint, and cancelled sub-orders do not get a cancelled status — they go back to where you choose with returnTo (the cart by default, same as My CJ). To remove orders that have not been put into a parent order yet (CREATED, IN_CART), use 1.8 Order Delete.
| Endpoint | Order status | Result |
|---|---|---|
| 1.8 Order Delete | CREATED, IN_CART | The order goes to the trash |
| 11.2 Cancel Order | Unpaid parent order (UNPAID) | Sub-orders go back to the cart / trash / created orders |
The order service refuses (1613003 with the reason) when, for example: the parent order has only one sub-order and you cancel that sub-order (cancel the parent order instead); the parent order is already being submitted; the order has been paid; the order is a private inventory outbound order.
Cancelling can take a moment. If the result is not ready, status is PROCESSING; query it with 11.3 Query Cancel Result. A refusal can therefore come back in two ways: right away as error code 1613003, or later as status = FAILED — handle both.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/cancel
# CURL
curl --location --request POST 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/cancel' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' \
--header 'Content-Type: application/json' \
--data '{
"cjOrderId": "CJ2611010000001",
"returnTo": "CART"
}'
| Parameter | Definition | Type | Required | Length | Note |
|---|---|---|---|---|---|
| cjOrderId | CJ parent order number | string | Either one | 50 | cjOrderId from 1.7 Query Order. Cancels the whole parent order |
| cjOrderCode | CJ sub-order number | string | Either one | 50 | cjOrderCode from 1.7. Removes only this sub-order from its parent order |
| returnTo | Where the sub-orders go | string | N | - | CART (default), TRASH, CREATED (back to created orders) |
# Return
{
"code": 200,
"result": true,
"message": "Success",
"data": {
"cjOrderId": "CJ2611010000001",
"cjOrderCode": null,
"status": "SUCCESS",
"message": null
},
"requestId": "2c4e6a8b-0d1f-4e3a-8c5b-7d9e1f3a5b7c"
}
| Field | Definition | Type | Note |
|---|---|---|---|
| cjOrderId / cjOrderCode | The order you sent | string | |
| status | Result | string | SUCCESS; PROCESSING not finished yet, query with 11.3; FAILED see message |
| message | Why it failed | string | Only when FAILED |
# 11.3 Query Cancel Result (GET)
Returns the result of the latest 11.2 Cancel Order request for the order. Send the same order number you sent to 11.2. Results are kept for about 2 hours.
# URL
https://developers.cjdropshipping.com/api2.0/v1/shopping/order/cancelResult
# CURL
curl --location --request GET 'https://developers.cjdropshipping.com/api2.0/v1/shopping/order/cancelResult?cjOrderId=CJ2611010000001' \
--header 'CJ-Access-Token: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
| Parameter | Definition | Type | Required | Note |
|---|---|---|---|---|
| cjOrderId | CJ parent order number | string | Either one | Same as in 11.2 |
| cjOrderCode | CJ sub-order number | string | Either one | Same as in 11.2 |
# Return
Same as 11.2. status can also be NOT_FOUND: there is no cancel request for this order, or its result has expired — query the order with 1.7 Query Order to see its current status.
← 4 Storage 6 Logistic →