Marketplaces / TikTok Marketplace Integration v2 / TikTok - Order management / TikTok - Ship Orders

TikTok - Ship Orders

Summary of changes:

Version Date Created / Updated Notes
v1.1 20.06.2024 Hristiyan Georgiev TikTok has new API version and updates. The scope was also updated to the latest changes on TikTok. Everything that is not tagged with v1.1 remains the same.
v1.2 6.01.2025 Hristiyan Georgiev Added additional error response and handling
v1.3 23.01.2025 Hristiyan Added new call and logic for shipping.

The purpose of this page is to give good understanding of the TikTok’s shippment logic.

<v1.1> To ship order on TikTok, first we should get & store all the available couriers for TikTok because it is mandatory when shipping an order to push shipping_provider_id. We are not able to ship with provider which is not part of the TikTok shipping provider list!

For us to successfully ship an order, we need to have the correct shipping providers from TikTok, but in order to get those providers, we need to first find out which are the delivery options and then based on that get the shipping providers. There are two separate calls for that.

Get delivery options

This API is used to obtain the list of Delivery options subscribed by the seller's designated warehouse. We need to have it in order to download all possible couriers and then do mapping, set default couriers etc. based on those TikTok Couriers. Basically this call can be incorporated with the Get Shipping providers call and could be our first step.

We want to truncate the table before we call and then freshly store all the available delivery options. We want to do that in order to avoid missing some new/removed delivery options.

API Call : GET /logistics/202309/warehouses/{warehouse_id}/delivery_options API Docs : https://partner.tiktokshop.com/docv2/page/650aa46ebace3e02b75d9afa?external_id=650aa46ebace3e02b75d9afa

We need to pass the shop_cipher as query property which was obtained with the Get Authorised Shops call found here TikTok - Authentication & Database structure

warehouse_id is taken from Location TikTok > Warehouse ID Execute the call for every Account Location. Location TikTok is connected to the Account through Account Location → Location → Location TikTok.

Example call :

https://open-api.tiktokglobalshop.com/logistics/202309/warehouses/7000714532876273410/delivery_options?app_key=123abc&sign=5361235029d141222525e303d742f9e38aea052d10896d3197ab9d6233730b8c&timestamp=1625484268&shop_cipher=ROW_RHkDDABBAAB8tKAVoAqsMTjsQZFLyNfY

Example response :

{
    "code": 0,
    "data": {
        "delivery_options": [
            {
                "description": "send by seller services.",
                "dimension_limit": {
                    "max_height": 0,
                    "max_length": 0,
                    "max_width": 0,
                    "unit": "CM"
                },
                "id": "6956548250505578241",
                "name": "ecom_logistics_type_SOF",
                "type": "SEND_BY_SELLER",
                "weight_limit": {
                    "max_weight": 0,
                    "min_weight": 0,
                    "unit": "GRAM"
                }
            },
            {
                "description": "LSV-DS-UK-Std",
                "dimension_limit": {
                    "max_height": 120,
                    "max_length": 120,
                    "max_width": 120,
                    "unit": "CM"
                },
                "id": "7021054158430013190",
                "name": "ecom_logistics_type_Standard",
                "type": "STANDARD",
                "weight_limit": {
                    "max_weight": 15000,
                    "min_weight": 0,
                    "unit": "GRAM"
                }
            }
        ]
    },
    "message": "Success",
    "request_id": "202406271539596AFC13A540D7110209C0"
}

Response mapping :

TikTok Field Hemi Mapping Comments
code N/A
data N/A
delivery_options N/A
description TikTok Delivery Options > Description New table suggested. This should be slave table of Account TikTok
dimension_limit N/A
max_height N/A
max_length N/A
max_width N/A
unit N/A
id TikTok Delivery Optoins > Delivery Option ID Note! It is possible to have more than one option so we need to be able to store them all and then use them all when doing the Get Shipping Providers call.
name N/A
type N/A
weight_limit N/A
max_weight N/A
min_weight N/A
unit N/A
message N/A
request_id N/A

Since we cannot associate this call with any order or product, we cannot store an error but we want to be able to see the error when cron is run from the terminal with DEVMODETRUE.

After we have the delivery option ids, we are ready to get the shipping providers with the following call :

Get Shipping Providers

This API is used to obtain the shipping provider corresponding to the specified delivery option. We can have many delivery options so we need to call each one of them and store the different couriers across different delivery option ids.

Using this call, we will need to store the shipping carriers provided from TikTok - will be stored into Courier table. We would want to map the shipping provider name but to send the shipping provider id to TikTok MPs. We will have courier mapping so we can map the respective TikTok courier to what we have in Hemi set as courier.

If TikTok add or remove some couriers, we want to respectively add/remove them from the Courier table. We don’t want to truncate the table with each run.

We want to introduce a default courier field which will be in the Account TikTok . The field will be an enum dropdown menu where the user can select the desired default courier. The field should not be required. Even if there is a selected default courier, we should first check if we have mapping from the courier on order with a record in table Courier and pick this with priority. We should only pick the default courier if there is no mapping for the selected courier. We should not be able to send a shipping update and store an error in Order Errors with Type > Shipping if we don’t have mapped courier and if we don’t have default courier set.


API Call: GET /logistics/202309/delivery_options/{delivery_option_id}/shipping_providers

API Docs: https://partner.tiktokshop.com/docv2/page/650aa48d4a0bb702c06d85cd?external_id=650aa48d4a0bb702c06d85cd

We need to pass the shop_cipher as query property which was obtained with the Get Authorised Shops call found here TikTok - Authentication & Database structure

The delivery_option_id parameter value will be what we have received from the above call and stored in TikTok Delivery Options > Delivery Option ID

Example Request:

https://open-api.tiktokglobalshop.com/logistics/202309/delivery_options/6955034615128000261/shipping_providers?app_key=123abc&sign=5361235029d141222525e303d742f9e38aea052d10896d3197ab9d6233730b8c&timestamp=1625484268&shop_cipher=ROW_RHkDDABBAAB8tKAVoAqsMTjsQZFLyNfY

Example Response:

{
  "code": 0,
  "data": {
    "shipping_providers": [
      {
        "id": "7117858858072016686",
        "name": "USPS"
      }
    ]
  },
  "message": "Success",
  "request_id": "202203070749000101890810281E8C70B7"
}

Ship Order

We want to use the new shipment model through the Order Shipment table. We want all triggers & validatios to be as per our abstraction

Order management general requirements

<v1.3> With this call we are able to do partial shipment on orders, we could even ship single quantity of multi-quantity order. </v1.3>

When we send shipping request and If chosen courier is deleted from TikTok list, and we try to ship with this courier, we want to store an error in Order Errors with Type = Shipping (suggested error message: The courier you want to ship with is not part of TikTok couriers anymore.) and we will not send shipping request for this order. If there are no preselected carriers into the table TikTok couriers, we also want to store an error stating there is no courier selected.

We want to introduce Courier mapping, we already have a slave table called TikTok Couriers Mapping for this use.

**The mapping will works based on: If Order Shipment > Carrier match Courier > Name we send the selected courier from TikTok Courier Mapping > TikTok Courier

If there is no match or no value in the mapping table we need to go into a second case which is to check directly in TikTok Couriers table for the chosen courier. The check here is done against the Shipping Provider Name column and if we find a match, we send the respective Shipping Provider ID

If there is no match on both of the above cases and we try to send a courier which is not part of the TikTok list, we want to store an error in Order Error table with Type = Shipment which states that the selected courier is not part of TikTok’s courier list.

<v1.3>

API Call: POST /fulfillment/202309/orders/{order_id}/packages

Docs: https://partner.tiktokshop.com/docv2/page/6503c95456e2bb0289ee4e81?external_id=6503c95456e2bb0289ee4e81

We should pick the order_id from Orders > Marketplace Order ID. The shipping provider id will be taken based on the mapping logic explained above.

We need to pass the shop_cipher as query property which was obtained with the Get Authorised Shops call found here TikTok - Authentication & Database structure

Example Call:

{
  "order_line_item_ids": [
    "576719323145669659",
    "576720553421999387"
  ],
  "shipping_provider_id": "6599541761693270018",
  "tracking_number": "H00KDA0040709141"
}

Mapping:

Integration Field Integration Notes Integration required Hemi Mapping Hemi Notes
order_line_item_ids Yes Order Item Line > Marketplace Order Item ID
shipping_provider_id Yes TikTok Courier > Shipping Provider ID Will be taken from the TikTok Carriers table; - The table will have 2 fields - TikTok Shipping Provider name & TikTok shipping Provider ID.

We would want to map the shipping provider name but to send the shipping provider id to TikTok. | | tracking_number | | Yes | Order Shipment > Tracking Number | |

Example response:

{
    "code": 0,
    "data": {
        "order_id": "576719323145473051",
        "order_line_item_ids": [
            "576719323145669659"
        ],
        "package_id": "1153248654705789979",
        "warning": {
            "message": "The tracking number you entered matches multiple logistics providers. Ensure you select the correct logistics provider."
        }
    },
    "message": "Success",
    "request_id": "202501231255414BC57038C018AD323E5E"
}

We don’t want to map anything from the success response. We also want to ignore the warning object in this case. </v1.3>

<v1.2> Example error response :

{
    "code": 21008099,
    "data": null,
    "message": "Package has been shipped. Please not ship the package again.",
    "request_id": "20250123132004A3CFD57654E368327149"
}

Incase we receive any error in the response, we will have a code different than 0. In this case we want to store the error message in the Order Errors table with Type = Shipping. </v1.2>

</v1.1>

Is this article helpful?
0 0 0