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

TikTok - Get 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 24.09.2024 Hristiyan Georgiev ADded logic for the address info
v1.3 07.11.2024 Hristiyan Georgiev Additional logic for storing the City
v1.4 13.01.2024 Bogomil Pavlov Order Status Transition Logic
v1.5 23.01.2024 Hristiyan Georgiev Changed AWAITING_COLLECTION mapping status
v1.6 09.06.2025 Bogomil Pavlov Address mapping changes for US
v1.7 12.06.2025 Hristiyan Georgiev Changes in the line items mapping, also added logic for handling partial shipments.
v1.8 23.06.2025 Bogomil Pavlov Additional Logic for address mapping for US
v1.9 11.07.2025 Hristiyan Georgiev New field for city added by TikTok and logic updates.

The purpose of Get Orders section is to describe in details how we will download orders from TikTok in Hemi & how we will enrich already downloaded orders.

<v1.1>

Basically, to download orders we need to make “Get Order List“ API call.

https://www.notion.so

The first run will check for new orders in the last 90 days and afterwards we will get the date from last_date_run table and filter orders using property:

update_time_ge - {last_date_run - 2 hours}

When we download the order we need to check if the order already exist in Hemi, if it does not exist, we need to store all related information in Hemi and also- to download the order in Hemi on respectively statuses.

Order statuses:

TikTok status Hemi Status Hemi Notes
UNPAID Pending This is our status that means there is something still to be done with the order prior to it being ready for any fulfilment.
Before the order is paid buyer can cancel or it passed the payment deadline (24hours UK) the order will be auto cancelled;
ON_HOLD Pending Currently ON_HOLD status is only available in the UK market): Payment has been finished, but order allow buyer to cancel without seller approval. Not allow seller fulfill order under ON_HOLD status.
PARTIALLY_SHIPPING Partially Shipped One or more (but not all) items in the order have been shipped
AWAITING_SHIPMENT Pending AND Ready For Shipping For the first one hour, the status in Hemi will be “Pending“ because of the grace period in which client can cancel the order for free.
After this 1 hour, the status need to be updated to ““Ready for Shipping“. Now() - Orders>Order Paid Time > 1hour
AWAITING_COLLECTION <v1.5> Shipped </v1.5>
IN_TRANSIT Shipped If we download an order on status “In_Transit“, we need to make sure we will store the order in Hemi with respectively internal status, which will be “Shipped“
DELIVERED Shipped It is possible to download order on this status. If the order does not exist in Hemi, we should download it with the respectively status.
COMPLETED Shipped It is possible to download order on this status. If order does not exist in Hemi, we should download it with the respectively status.
CANCELLED Canceled If we download an order on status “Cancelled“, we need to make sure we will store the order in Hemi with respectively internal status, which will be “Canceled“

<v1.4> Order Status Transitions:

Hemi Status Transition Comment
Pending From “Pending“ we can move to any other Hemi Status Pending status is indicating that something need to happen on the order like clear debit, waiting acceptance etc.
Incomplete From “Incomplete” we can move to any further status (RFS, Shipped, Partially Shipped, Cancelled) if we read the order again and it has everything in it. We are moving status of course only if we are updating the info for the order in Hemi (for example - we are missing Shipping Address - if on the next read we have the Address we update it on the order and change to the relevant status)
Awaiting Acknowledge From “Awaiting Acknowledge“ we can move to any other Hemi Status besides “Pending”
Ready For Shipping From ”Ready For Shipping” we can move to “Shipped“, “Partially Shipped” or “Cancelled“ only Ready For Shipping indicates the order can be shipped successfully have all required information stored and payment cleared
Partially Shipped From “Partially Shipped“ we can move to “Cancelled“ or “Shipped“ Partially Shipped indicating that the order has been partially dispatched.
Shipped From “Shipped“ we can move to “Cancelled“ Shipped indicating that the order has been dispatched.
Cancelled “Cancelled“ is our final status. Cancelled is the Hemi final status and we cannot revert back or move forward.

</v1.4>

If the order does not exist in Hemi, and order paid time is less than 1 hour (NOW() - Order Paid Time < 1 hour) we will download the order on status Awaiting Shipment and in Hemi the status will be “Pending“. ( Buyer has 1 hour grace period to cancel the order freely, thats why we need to verify the order paid time); Orders which are on status “pending“ will be picked by the next run of the cron, requirements will be verified, and only if the requirements are covered, the status will be changed to “Ready For Shipping“;

If the order not exist in Hemi, and order paid time is greater than 1 hour (NOW() - Order Paid Time > 1 hour) we will download the order on status “Ready For Shipping“. Before we set order to “RFS“ status, we need to make sure the order contain all crucial mandatory information from the MP, should have payment, should be checked for bundles, shipment cost should be broken down on all items, sellers and original prices (cost) added, taxes and fees applied as per our standard enrichment process you can find here: Order management general requirements

(we take care of bundles internally and use our standard logic for debundling).

If the order already exists, we need to check the status of the order and to check if the order status can be changed, according to order status on the marketplace. (detailed table with statuses is described above, under “Get Order List“ mapping).

If the order does not exist in Hemi but its status is “In Transit“ , “Delivered“, “Completed“ оr “Cancelled“, we will download this order in Hemi and the order will be with the respectively status in Hemi (as per table with statuses above)

Get Order List

API Call: POST /order/202309/orders/search

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

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

We also need to use the page_size to specify the maximum number of orders to obtain in a single page. Must be 1-100. Up to the devs to decide how many orders we want per page.

In the body of the request we have a few properties that we can filter orders with. We want to use the update_time_ge used for selecting orders that were last updated after (or at) a specified time. An update is defined as any change in order status, including the creation of a new order. Includes updates made by Tiktok and by the seller. Unix timestamp. We want to be sending this property with the time from last_date_run - 2 hours. No other properties to be used.

Example query & body:

https://open-api.tiktokglobalshop.com/order/202309/orders/search?app_key=123abc&sign=5361235029d141222525e303d742f9e38aea052d10896d3197ab9d6233730b8c&timestamp=1625484268&shop_cipher=ROW_RHkDDABBAAB8tKAVoAqsMTjsQZFLyNfY&page_size=20&sort_order=ASC&page_token=6AsPQsUMvH3RkchNUPPh22NROHkE0D8pmq/N5M1kHYcZmtRyv9aVrNv65W7Q6tFA+7D1ud64MPNz5OaT&sort_field=create_time
{
  "buyer_user_id": "7213489962827123654",
  "create_time_ge": 1623812664,
  "create_time_lt": 1623812664,
  "is_buyer_request_cancel": false,
  "order_status": "UNPAID",
  "shipping_type": "TIKTOK",
  "update_time_ge": 1623812664,
  "update_time_lt": 1623812664
}

Example Response:

{
  "code": 0,
  "data": {
    "next_page_token": "6AsPQsUMvH3RkchNUPPh22NROHkE0D8pmq/N5M1kHYcZmtRyv9aVrNv65W7Q6tFA+7D1ud64MPNz5OaT",
    "orders": [
      {
        "buyer_email": "v2b2V5@chat.seller.tiktok.com\n",
        "buyer_message": "Please ship asap!",
        "cancel_order_sla_time": 1619621355,
        "cancel_reason": "Pricing error",
        "cancel_time": 1678389618,
        "cancellation_initiator": "SELLER",
        "collection_due_time": 1678389618,
        "collection_time": 1678389618,
        "cpf": "3213-31231412",
        "create_time": 1619611561,
        "delivery_due_time": 1678389618,
        "delivery_option_id": "7091146663229654785",
        "delivery_option_name": "Shipped from seller",
        "delivery_option_required_delivery_time": 1678389618,
        "delivery_sla_time": 1678389618,
        "delivery_time": 1678389618,
        "delivery_type": "HOME_DELIVERY",
        "fulfillment_type": "FULFILLMENT_BY_SELLER",
        "has_updated_recipient_address": false,
        "id": "576461413038785752",
        "is_buyer_request_cancel": false,
        "is_cod": false,
        "is_on_hold_order": false,
        "is_replacement_order": false,
        "is_sample_order": "FALSE\n",
        "line_items": [
          {
            "currency": "USD",
            "display_status": "IN_TRANSIT",
            "id": "577004003246575904",
            "is_dangerous_good": false,
            "is_gift": false,
            "item_tax": [
              {
                "tax_amount": "1.4",
                "tax_rate": "0.0825",
                "tax_type": "SALES_TAX"
              }
            ],
            "original_price": "33.59",
            "package_id": "1154282547825709344",
            "package_status": "FULFILLING",
            "platform_discount": "0",
            "product_id": "1729480280653534101",
            "product_name": "DOCKERS Mens Boxer Briefs Breathable Cotton Underwear for Men Pack of 5",
            "rts_time": 1749535754,
            "sale_price": "17",
            "seller_discount": "16.59",
            "seller_sku": "DOSTBB501- AST- LG",
            "shipping_provider_id": "7117858858072016686",
            "shipping_provider_name": "USPS",
            "sku_id": "1729480280653927317",
            "sku_image": "https://p19-oec-ttp.tiktokcdn-us.com/tos-useast5-i-omjb5zjo8w-tx/2da1eda4bb224dd996f11600942dc24f~tplv-omjb5zjo8w-origin-jpeg.jpeg?from=1568152328",
            "sku_name": "Black | Heather Charcoal | B25 Heather Charcoal..., Large",
            "sku_type": "NORMAL",
            "tracking_number": "9361289671049544353625"
          },
          {
            "currency": "USD",
            "display_status": "AWAITING_SHIPMENT",
            "id": "577004003246641440",
            "is_dangerous_good": false,
            "is_gift": false,
            "item_tax": [
              {
                "tax_amount": "1.4",
                "tax_rate": "0.0825",
                "tax_type": "SALES_TAX"
              }
            ],
            "original_price": "33.59",
            "package_id": "1154282547825643808",
            "package_status": "TO_FULFILL",
            "platform_discount": "0",
            "product_id": "1729480280653534101",
            "product_name": "DOCKERS Mens Boxer Briefs Breathable Cotton Underwear for Men Pack of 5",
            "sale_price": "17",
            "seller_discount": "16.59",
            "seller_sku": "DOSTBB507- AST- LG",
            "sku_id": "1729480280654648213",
            "sku_image": "https://p16-oec-ttp.tiktokcdn-us.com/tos-useast5-i-omjb5zjo8w-tx/59438372e12c40db94a5a87a32f76a18~tplv-omjb5zjo8w-origin-jpeg.jpeg?from=1568152328",
            "sku_name": "Castlerock | Heather Charcoal | Valentines Flor..., Large",
            "sku_type": "NORMAL",
            "tracking_number": ""
          }
        ],
        "need_upload_invoice": "NEED_INVOICE\n",
        "packages": [
          {
            "id": "1152321127278713123"
          }
        ],
        "paid_time": 1619611563,
        "payment": {
          "buyer_service_fee": "1000",
          "currency": "IDR",
          "original_shipping_fee": "5000",
          "original_total_product_price": "5000",
          "platform_discount": "5000",
          "product_tax": "21.3",
          "retail_delivery_fee": "1.28",
          "seller_discount": "5000",
          "shipping_fee": "5000",
          "shipping_fee_platform_discount": "5000",
          "shipping_fee_seller_discount": "5000",
          "shipping_fee_tax": "11",
          "small_order_fee": "3000",
          "sub_total": "5000",
          "tax": "5000",
          "total_amount": "5000"
        },
        "payment_method_name": "CCDC",
        "recipient_address": {
          "address_detail": "Unit one building 8",
          "address_line1": "TikTok 5800 bristol Pkwy",
          "address_line2": "Suite 100",
          "address_line3": " ",
          "address_line4": " ",
          "delivery_preferences": {
            "drop_off_location": "Front Door"
          },
          "district_info": [
            {
              "address_level": "L0",
              "address_level_name": "Country",
              "address_name": "United Kingdom"
            }
          ],
          "full_address": "1199 Coleman Ave San Jose, CA 95110",
          "name": "Zay",
          "phone_number": "(+1)213-***-1234",
          "postal_code": "95110",
          "region_code": "US",
          "post_town": "Ribbleton"
        },
        "replaced_order_id": "576461416728782174",
        "request_cancel_time": 1678389618,
        "rts_sla_time": 1619611688,
        "rts_time": 1619611563,
        "seller_note": "seller note",
        "shipping_due_time": 1678389618,
        "shipping_provider": "TT Virtual express",
        "shipping_provider_id": "6617675021119438849",
        "shipping_type": "TIKTOK",
        "split_or_combine_tag": "COMBINED",
        "status": "UNPAID",
        "tracking_number": "JX12345",
        "tts_sla_time": 1619611761,
        "update_time": 1619621355,
        "user_id": "7021436810468230477",
        "warehouse_id": "6955005333819123123"
      }
    ],
    "total_count": 22113
  },
  "message": "Success",
  "request_id": "202203070749000101890810281E8C70B7"
}

Mapping:a

Integration Field Integration Notes Hemi Mapping Hemi Notes
code
data
next_page_token
orders
buyer_email Orders > Buyer Mail
buyer_message The note from buyer. Orders> Note
cancel_order_sla_time N/A
cancel_reason N/A
cancel_time N/A
cancellation_initiator N/A
collection_due_time N/A
collection_time N/A
cpf N/A
create_time Orders > Order Created Time
delivery_due_time N/A
delivery_option_id Orders TikTok > Delivery Option ID New field! We need to store this in order to be able to ship the order.
delivery_option_name Delivery option name. For display purposes only. Orders > Shipping Service
delivery_option_required_delivery_time Order should be delivered before this time. Orders> Delivery By Time
delivery_sla_time N/A
delivery_time N/A
delivery_type Indicates whether it is PickUp DropOff (PUDO) location. The PUDO location is selected by the buyer when placing orders.
  • HOME_DELIVERY: not a PUDO location
  • COLLECTION_POINT: a PUDO location | Orders> Order Type | We need to map TikTok’s statues to ours as follows :

-HOME_DELIVERY we map to Home Delivery -COLLECTION_POINT we map to Click & Collect | | | | fulfillment_type | | | - Fulfillment type. Only orders with fulfillment type can be shipped by sellers. FULFILLMENT_BY_SELLER: is a method where sellers fulfill orders directly from their own inventory, without using Tiktok's fulfillment centers. In this model, the seller is responsible for storing, packaging, and shipping the products to customers.

  • FULFILLMENT_BY_TIKTOK: is a service offered by TIktok where sellers can send their products to Tiktok's fulfillment centers. Tiktok then takes care of storing, picking, packing, and shipping the products to customers. Orders> Marketplace Fulfillment Channel If we receive FULFILLMENT_BY_SELLER we want to store it as “Fulfillment by merchant” If we receive FULFILLMENT_BY_TIKTOK we want to store it as “Fulfillment by platform”
    has_updated_recipient_address N/A
    id TikTok order ID Orders> Marketplace Order Id
    is_buyer_request_cancel N/A
    is_cod N/A
    is_on_hold_order N/A
    is_replacement_order N/A
    is_sample_order N/A
    line_items We want to group lines by seller_sku and sale_price
    currency N/A
    display_status <v1.7> Product In Order Line > Fulfillment Status We only need to map if we receive the following statuses :

    -IN_TRANSIT , AWAITING_COLLECTION, DELIVERED, COMPLETED we store as “Fully Shipped”. There is also a possibility of partial shipment on the order so we could use this status and combine items by the tracking_number to identify which products have been shipped and then create Order Shipment row with the relevant information </v1.7> | | | | | id | | | Order Item Line > Marketplace Order Item ID | | | | | | is_dangerous_good | | | N/A | | | | | | is_gift | | | N/A | | | | | | item_tax | | | | | | | | | | tax_amount | | Product In Order > Sales Tax Amount | Note : Currently only sales tax is available. | | | | | | tax_rate | | N/A | | | | | | | tax_type | | N/A | We are searching for tax_type = SALES_TAX and then safe into the Sales Tax Amount . If there is other tax_type we skip and not save the tax_amount | | | | | original_price | | Sku original price (VAT included for crossborder shop). Single quantity. | Product in Order > Item Original Price | The price of the item without discount amount. | | | | | package_id | | | <v1.7> Product In Order Line > Package ID </v1.7> | | | | | | package_status | | | N/A | | | | | | platform_discount | | Sku discount by platform for this particular line | Product in Order TikTok > Platform Discount | Since TikTok are providing items on line level (and not providing us quantity), if we have 2 or more lines for the same item, we need to calculate the platform discount for all lines (for this same product) and store it in Hemi calculated for all lines for this product. | | | | | product_id | | Product id. (origin is item id) | Product in Order > Channel Item ID | | | | | | product_name | | Product name. | Product in Order > Item Title | | | | | | sale_price | | Line sale price (VAT included for crossborder shop). Single quantity. | Product in Order > Item Price | This is the price that the item was sold for a single line | | | | | seller_discount | | | Product in Order TikTok > Seller Discount | Since TikTok are providing items on line level (and not providing us quantity), if we have 2 or more lines for the same item, we need to calculate the seller_discount for all lines (for this same product) and store it in Hemi calculated for all lines for this product. | | | | | seller_sku | | Seller input sku in order snapshot | Product in Order > SKU | | | | | | shipping_provider_id | | | N/A | | | | | | shipping_provider_name | | | <v1.7>Order Shipment > Courier</v1.7> | | | | | | sku_id | | Sku id | Product in Order > Item Order Line ID | | | | | | sku_image | | Sku image in order snapshot | N/A | | | | | | sku_name | | Sku properties | N/A | | | | | | sku_type | | | N/A | | | | | | tracking_number | | | <v1.7>Product In Order Line > Shipping Tracking Number AND Order Shipment > Tracking Number </v1.7> | We should combine all order items with the same tracking number and save them into the same shipment. We also need to create the Order Shipment record on status Completed. | | | | need_upload_invoice | | | | N/A | | | | | packages | | | | | | | | | | id | | | N/A | | | | | paid_time | | | The date and time that the order was paid. Unix timestamp for second. | Order > Order Paid Time | | | | | payment | | | | | | | | | | buyer_service_fee | | | N/A | | | | | | currency | | Currency for payment. | Order > Currency | | | | | | original_shipping_fee | | | N/A | | | | | | original_total_product_price | | | N/A | | | | | | platform_discount | | Product discount by platform. | Order > Discount Value | Note! Will be sum ofplatform_discoun & seller_discount | | | | | product_tax | | | N/A | | | | | | retail_delivery_fee | | | N/A | | | | | | seller_discount | | | N/A | | | | | | shipping_fee | | Buyer paid shipping fee. Shipping_fee = original_shipping_fee - shipping_fee_seller_discount - shipping_fee_platform_discount | Order > Shipping Service Cost | | | | | | shipping_fee_platform_discount | | Shipping fee discount by platform | Order TikTok > Platform Shipping Discount | | | | | | shipping_fee_seller_discount | | Shipping fee discount by seller. | Order TikTok> Seller Shipping Discount | | | | | | shipping_fee_tax | | The tax on the shipping price. | Order > Total Shipping Sales Tax | | | | | | small_order_fee | | | N/A | | | | | | sub_total | | Order subtotal amount | Order > Оrder Subtotal Аmount | | | | | | tax | | Buyer paid total taxes of the order. | Order > Total Tax Amount | | | | | | total_amount | | Buyer paid total payment. | Order > Оrder Тotal Аmount | | | | | payment_method_name | | | Payment method name, only for display | Order > Order Payment Method | | | | | recipient_address | | | | | | | | | | address_detail | | | N/A | | | | | | address_line1 | | The first line of the street address | Orders > Shipping Street 1

    | | | | | | address_line2 | | The second line of the street address | Orders > Shipping Street 2 | | | | | | address_line3 | | The third line of the street address. Usually only for the Brazilian market | N/A | | | | | | address_line4 | | The fourth line of the street address. Usually only for the Brazilian market | N/A | | | | | | delivery_preferences | | | | | | | | | | drop_off_location | | N/A | | | | | | district_info | | | | | | | | | | address_level | | N/A | <v1.2> We want to have a logic and if we have TikTok account that is for the United Kingdom to ignore address level L0 and only store information from address_level L1,L2,L3,L4 If we have TikTok Account with country United States we store information from <v1.6> L0, L1, L3 </v1.6>As a suggestion we can identify which country we have it by Account > Country</v1.2> | | | | | | address_level_name | The name of administrative division that can be used by seller for ship. e.g. state/county/city/district/town etc. | N/A | We need to do mapping and store the address_name based on what has been given in address_level_name Mapping as follows : county we map to Orders > Shipping State Province <v1.8> ”State” we map to Orders > Shipping State Province OR ”Federal District” we map to Orders > Shipping State Province </v1.8> country we map to Orders > Shipping Country Name city we map to Orders > Shipping City <v1.9> This should only be valid for a country different than the UK, for UK we have a new field in the response from which we store the city from </v1.9> district we map to Orders > Shipping City town we map to Orders > Shipping City <v1.9> This should only be valid for a country different than the UK, for UK we have a new field in the response from which we store the city from </v1.9>

We might have more than one address_name so we want to store everything. If we have city/district/town for the same address we store the city with priority, then is town, and last is district. This means if we have all 3 of them, we will only store the city and so on. <v1.2>If we have county and state for the same address we store state with priority</v1.2> <v1.3> We need to implement additional logic and if there is no city/disctrict/town address_level we need to get the city from the full_address field in the payload. We need to store everything after the last comma in this address into Orders > Shipping City Name </v1.3><v1.9> This logic should not be valid for accounts with country = United Kingdom </v1.9>

| | | | | | address_name | | Based on mapping above | | | | | | full_address | | Address with detailed info. | Orders TikTok > Full Address | New field. We want to store the full address just in case.

| | | | | name | | | Orders > Shipping Buyer Name | | | | | | phone_number | | | Orders > Shipping Phone | | | | | | postal_code | | | Orders > Shipping Postal Code | | | | | | region_code | | | Orders > Shipping Country Code | | | | | | <v1.9>post_town | | | Orders > Shipping City | This field will only be present in UK orders. For any other countries, we keep our logic as it is now.</v1.9> | | | | replaced_order_id | | | | N/A | | | | | request_cancel_time | | | | N/A | | | | | rts_sla_time | | | | N/A | | | | | rts_time | | | | N/A | | | | | seller_note | | | | N/A | | | | | shipping_due_time | | | If the order hasn't updated its status to "AWAITING_COLLECTION" before this time, the order will be canceled by TikTok Shop | Orders > Ship By Date | | | | | shipping_provider | | | The name of the current shipping provider. | Orders > Shipping Carrier | We will not always receive this (as per test performed with test orders - only when order is shipped with the TikTok carrier) | | | | shipping_provider_id | | | | N/A | | | | | shipping_type | | | | N/A | | | | | split_or_combine_tag | | | | N/A | As per TT notes, this will be introduced on a later stage. | | | | status | | | | Orders > Order Status | | | | | tracking_number | | | Tracking number | Orders > Shipping Track Number | | | | | tts_sla_time | | | | N/A | | | | | update_time | | | | N/A | | | | | user_id | | | | Orders > Buyer User ID | | | | | warehouse_id | | | | N/A | | | | total_count | | | | | N/A | | | message | | | | | | N/A | | | request_id | | | | | | N/A | |

Once we download an order, we should always create a payment record (we should always treat an order as paid, unless the status of order is ”UNPAID” or “ON_HOLD” or we have “AWAITING_SHIPMENT” and Order Status = Pending (this wil be for the first hour of when the order was made)). As per abstraction: Order management general requirements

<v1.5> The only difference we want from the abstraction is to be able to store orders which have Product on Order > Item Price equal to 0 on a Ready for Shipping status. This is needed because TikTok often does 100% discounts for influencers etc. and it happens that we receive orders with 0 cost of products. In this case, we still want to have the order on Ready for Shipping and export it. </v1.5>

</v1.1>

Is this article helpful?
0 0 0