Temu Get Orders
Version | Date | Created / Updated | Notes |
---|---|---|---|
v1.0 | Hristiyan | First publish |
The get orders on Temu consist of a couple of calls we need to make in order to get the full information of the order. We need to get the order list first, then the order price details and then the shipping info (address) so we need to do 3 subsequent calls to obtain the full information. We should not store the order until we have tried to make all 3 calls for it and obtained the full info. However for all shipped orders we wont be able to receive the address but we still want to store them in our system so if we are receiving cancelled or shipped orders we do not want to treat them as incomplete if any of the required information is missing. This is applicable only for RFS or Partially Shipped orders.
All validations, enrichments etc. are as per the abstraction - Order management general requirements
Get Order List
API Call : POST https://openapi-b-eu.temu.com/openapi/router
API Name: bg.order.list.get
We need to use specific parameters to define the timeframes for the orders we wish to retrieve. The parameters we'll use are updateAtStart
and updateAtEnd
, both in Unix timestamp format. We'll reference the last_date_run
table to select the relevant date and overlap it with 1 hour.. Therefore, updateAtStart
will be the last_date_run
minus 1 hour, and updateAtEnd
will be the current time. For the first cron run, we should retrieve orders from the past 90 days.
Find a request sample with params below :
{
"type": "bg.order.list.get",
"timestamp": timestamp,
"app_key": "app_key",
"data_type": "JSON",
"access_token": "access_token",
"pageSize": 100,
"pageNumber": 1,
"updateAtStart": 1736858614,
"updateAtEnd": 1737031414
}
Request mapping :
Temu field | Field type | Notes/Mapping |
---|---|---|
pageSize |
INTEGER | Default is 10 but I suggest we use 100 |
pageNumber |
INTEGER | Start from 1 and if more pages available we need to get them too |
updateAtStart |
INTEGER | last_date_run - 1hour |
updateAtEnd |
INTEGER | CURRTIME() |
Example response :
{
"result": {
"result": {
"totalItemNum": 1,
"pageItems": [
{
"parentOrderMap": {
"parentOrderLabel": [
{
"name": "soon_to_be_overdue",
"value": 0
},
{
"name": "past_due",
"value": 1
},
{
"name": "pending_buyer_cancellation",
"value": 0
},
{
"name": "pending_buyer_address_change",
"value": 0
},
{
"name": "pending_risk_control_alert",
"value": 0
}
],
"parentShippingTime": null,
"updateTime": 1736430759,
"latestDeliveryTime": 1736981999,
"fulfillmentWarning": [],
"parentOrderTime": 1736430158,
"regionId": 76,
"parentOrderSn": "PO-076-13925293151271879",
"parentOrderPendingFinishTime": 1736430759,
"siteId": 105,
"expectShipLatestTime": 1736550600,
"parentOrderStatus": 2,
"hasShippingFee": true
},
"orderList": [
{
"canceledQuantityBeforeShipment": 0,
"quantity": 1,
"orderSn": "076-13925398008871879",
"goodsId": 603617570475412,
"orderLabel": [
{
"name": "customized_products",
"value": 0
},
{
"name": "US_to_CA",
"value": 0
}
],
"orderStatus": 2,
"inventoryDeductionWarehouseId": null,
"fulfillmentType": "fulfillBySeller",
"spec": "red",
"originalOrderQuantity": 1,
"thumbUrl": "https://img-eu.kwcdn.com/local-goods-img/20a3d4c00b/c87965db-9759-4c04-8f74-33207865cf38_800x800.jpeg.format.jpg",
"inventoryDeductionWarehouseName": null,
"goodsName": "test1",
"productList": [
{
"productSkuId": 254794717573,
"soldFactor": 1,
"extCode": "",
"productId": 76946267699
}
],
"skuId": 67055176970656
}
]
}
]
},
"success": true,
"errorCode": 0,
"serverTime": 1736946409576,
"errorMsg": "SUC"
},
"success": true,
"requestId": "eu-868812e7-4b99-4643-b22d-dda0f615106f",
"errorCode": 1000000,
"errorMsg": ""
}
Response Mapping :
Temu field | Hemi Field | Notes | |||||
---|---|---|---|---|---|---|---|
result |
|||||||
result |
|||||||
totalItemNum |
N/A | ||||||
pageItems |
|||||||
parentOrderMap |
|||||||
parentOrderLabel |
|||||||
name |
N/A | ||||||
value |
N/A | ||||||
parentShippingTime |
N/A | ||||||
updateTime |
Orders > Order Modified Time |
||||||
latestDeliveryTime |
N/A | ||||||
fulfillmentWarning |
N/A | ||||||
parentOrderTime |
Orders > Order Created Time |
||||||
regionId |
Orders Temu > Region ID |
New field! | |||||
parentOrderSn |
Orders > Marketplace Order ID |
||||||
parentOrderPendingFinishTime |
N/A | ||||||
siteId |
N/A | ||||||
expectShipLatestTime |
Orders > Ship By Date |
||||||
parentOrderStatus |
Orders > Marketplace Status |
Status mapping provided in a table below. Please note that we will receive numeric value but we need to store the order state instead. | |||||
hasShippingFee |
N/A | ||||||
orderList |
|||||||
canceledQuantityBeforeShipment |
We need to implement a logic and if we have any cancelled quantity before shipping we want to store the order on Orders > Status = Pending and keep it on Pending for 30 min. This way we will allow for the Get refunds cron to run within this timeframe and store the refund and all the info for the cancelled quantity. We want to then look at updateTime and after 30 min the order should be on Ready for Shipping or Cancelled, depending on how many quantity was cancelled. |
||||||
quantity |
N/A | This is the quantity remaining after the canceledQuantityBeforeShipment . We dont need this. |
|||||
orderSn |
Order Item Line > Marketplace Order Item ID |
We will need this when shipping | |||||
goodsId |
Product In Order > Channel Item ID |
||||||
orderLabel |
|||||||
name |
N/A | ||||||
value |
N/A | ||||||
orderStatus |
Product In Order > Status |
Status mapping provided in a table below. Please note that we will receive numeric value but we need to store the order state instead. | |||||
inventoryDeductionWarehouseId |
N/A | ||||||
fulfillmentType |
N/A | ||||||
spec |
N/A | ||||||
originalOrderQuantity |
Product In Order > Quantity |
||||||
thumbUrl |
N/A | ||||||
inventoryDeductionWarehouseName |
N/A | ||||||
goodsName |
Product In Order > Item Title |
||||||
productList |
|||||||
productSkuId |
Product In Order > Item Order Line ID |
This needs to be unique value, so we store productSkuId + price of the product |
|||||
soldFactor |
N/A | ||||||
extCode |
N/A | ||||||
productId |
N/A | ||||||
skuId |
Product In Order > Item Transaction ID |
AND mapp the below based on the Notes:
Product In Order
> SKU
* | Please note that in the skuId
field we are receiving Temu’s own SKU and not directly the seller one. To map accordingly we need to check Product Account Temu > SKU ID
and from there map to the correct Seller product to pick the SKU.
In case there is no Temu SKU ID to map to we fill in all other info and we treat this product as not having SKU and from there we invoke the right handle from the Abstraction.
In case there are more than one records with the same SKU ID we are to treat it as we can’t map it again (almost as the above case) with the difference we want to store an Order error “Multiple Products present in the system with Temu SKU IDs skuId
”.
Also please note - It is possible that we receive more than 1 quantity for the same SKU as separate single quantity rows, we need to take this into consideration and compile them when saving. |
| | success
| | | | | N/A | |
| | errorCode
| | | | | N/A | |
| | serverTime
| | | | | N/A | |
| | errorMsg
| | | | | N/A | |
| success
| | | | | | N/A | |
| requestId
| | | | | | N/A | |
| errorCode
| | | | | | N/A | |
| errorMsg
| | | | | | N/A | |
Order & Order Item Status Mapping :
Temu Order State | Temu Value | Hemi Status | Description |
---|---|---|---|
PENDING | 1 | Pending | Order is pending. After payment, the PO (parentOrder) enters the pending state. The order is temporarily suspended, and there is a cooling-off period after payment, including order processing time for risk control and other measures. |
UN_SHIPPING | 2 | Ready for Shipping | Order is awaiting shipment. The user can still cancel the order in this state. It is necessary to monitor the order cancellation status and accept the order in a timely manner. |
CANCELED | 3 | Cancelled | Order has been canceled by the user. |
SHIPPED | 4 | Shipped | Order has been shipped and completed. |
RECEIPTED | 5 | Shipped | Order has been received and signed for. |
PARTIAL DELIVERY | 41 | Partially Shipped | Part of the order is shipped |
PARTIAL RECEIPT | 51 | Partially Shipped | Part of the order is signed |
Example error response : 200 OK
{
"result": {
"result": null,
"success": false,
"errorCode": 1001,
"serverTime": 1736952438784,
"errorMsg": "Invalid request parameters"
},
"success": true,
"requestId": "eu-8f597c9a-9449-4dd1-9d3f-99599084c67c",
"errorCode": 1000000,
"errorMsg": ""
}
Get Order Price Details
API Call : POST https://openapi-b-global.temu.com/openapi/router
API Name : bg.order.amount.query
Using this call we obtain the prices for the order and ordered items. Please note that the prices are in cents-based representation which means we need to add a decimal point when storing the prices. We can find out where to add the decimal point by dividing the amount by 100, so all prices from the response need to be divided by 100.
Request sample with params :
{
"type": "bg.order.amount.query",
"timestamp": timestamp,
"app_key": app_key,
"data_type": "JSON",
"access_token": access_token,
"parentOrderSn": "PO-076-01400291382311012"
}
Request mapping :
Temu field | Field type | Notes/Mapping |
---|---|---|
parentOrderSn |
STRING | Orders > Marketplace Order ID |
Example response:
{
"result": {
"parentOrderMap": {
"taxTotalAfterDiscount": {
"amount": 30,
"currency": "EUR"
},
"estimatedRevenueDeduction": {
"amount": 0,
"currency": "EUR"
},
"parentOrderSn": "PO-076-01400291382311012",
"taxTotal": {
"amount": 30,
"currency": "EUR"
},
"refundsTotal": {
"amount": null,
"currency": "EUR"
},
"estimatedRevenue": {
"amount": 409,
"currency": "EUR"
},
"discountFromTEMU": {
"amount": 0,
"currency": "EUR"
},
"shippingAmountTotal": {
"amount": 279,
"currency": "EUR"
},
"discountFromSeller": {
"amount": 0,
"currency": "EUR"
},
"basePriceTotal": {
"amount": 100,
"currency": "EUR"
}
},
"orderList": [
{
"unitBasePrice": {
"amount": 100,
"currency": "EUR"
},
"unitRetailPriceVatExcl": {
"amount": 136,
"currency": "EUR"
},
"quantity": 1,
"orderSn": "076-01400333325351012",
"unitRetailPriceVatIncl": {
"amount": 146,
"currency": "EUR"
},
"basePrice": {
"amount": 100,
"currency": "EUR"
}
}
]
},
"success": true,
"requestId": "eu-f35ce2b1-28a6-4413-8d64-d1647338cc87",
"errorCode": 1000000,
"errorMsg": ""
}
Mapping :
Temu Field | Hemi Field | Notes | |||
---|---|---|---|---|---|
result |
|||||
parentOrderMap |
|||||
taxTotalAfterDiscount |
|||||
amount |
Orders > Total VAT |
OR
Orders
> Total Salex Tax
| If we have Account
> Country
= United States, we store in Total Sales Tax
, for any other country we store in Total VAT
|
| | | | currency
| N/A | |
| | | estimatedRevenueDeduction
| | | |
| | | | amount
| N/A | |
| | | | currency
| N/A | |
| | | parentOrderSn
| | N/A | |
| | | taxTotal
| | | |
| | | | amount
| N/A | |
| | | | currency
| N/A | |
| | | refundsTotal
| | | |
| | | | amount
| N/A | |
| | | | currency
| N/A | |
| | | estimatedRevenue
| | | |
| | | | amount
| Orders
> Order Total Amount
| |
| | | | currency
| N/A | |
| | | discountFromTEMU
| | | |
| | | | amount
| Orders Temu
> Temu Discount
| We want to sum this along with the Seller Discount
and store the sum in Orders
> Discount Value
|
| | | | currency
| N/A | |
| | | shippingAmountTotal
| | | |
| | | | amount
| Orders
> Shipping Service Cost
| |
| | | | currency
| N/A | |
| | | discountFromSeller
| | | |
| | | | amount
| Orders Temu
> Seller Discount
| We want to sum this along with the Temu Discount
and store the sum in Orders
> Discount Value
|
| | | | currency
| N/A | |
| | | basePriceTotal
| | | |
| | | | amount
| Orders
> Order Subtotal Amount
| |
| | | | currency
| Orders
> Order Currency
| |
| | orderList
| | | | |
| | | unitBasePrice
| | | |
| | | | amount
| Product In Order
> Item Price
| |
| | | | currency
| N/A | |
| | | unitRetailPriceVatExcl
| | | |
| | | | amount
| N/A | |
| | | | currency
| N/A | |
| | | quantity
| | N/A | |
| | | orderSn
| | N/A | This will be our Order Item Line
> Marketplace Order Item ID
so we need to map against it to find out which product the price is for. |
| | | unitRetailPriceVatIncl
| | | |
| | | | amount
| N/A | |
| | | | currency
| N/A | |
| | | basePrice
| | | |
| | | | amount
| N/A | |
| | | | currency
| N/A | |
| success
| | | | N/A | |
| requestId
| | | | N/A | |
| errorCode
| | | | N/A | |
| errorMsg
| | | Order Error
> Message
| | If we have success
= false, during obtaining the prices we need to save into Order Error
with type Order Download
. We also need to save the order with Orders
> Order Status
= Incomplete
Please note: even if we have this error we still want to obtain all info for the order (make the Shipping details call if it goes last) and store as much info as possible in our OMS. It will just be on an Incomplete state due to this crucial piece of information about price missing |
As our mapping reference for price is on Order Item Line level we have to assume there are options for 1 SKU with multiple quantity to have different pricing. In such cases we want to invoke our standard handling of this - splitting the SKU in multiple lines and grouping by price. So if we have a SKU with qty 3 ordered and we have 2 with price 20.00 and 1 with price 15.00 we should end up with 2 Product in Order records with the same SKU that will then have different prices and will have the right Order Item Lines there after
Example error response : 200 OK
{
"success": false,
"requestId": "eu-e6afcea8-48ef-4c3b-b156-ed933cbc5b37",
"errorCode": 7000000,
"errorMsg": "BUSINESS_SERVICE_ERROR"
}
Get Shipping Details
API Call : POST https://openapi-b-eu.temu.com/openapi/router
API Name: bg.order.shippinginfo.get
Using this call we will obtain the shipping information on the order. We have a required parameter of parentOrderSn
which is a string, meaning we can get single order’s address per call. We want to pick it from Orders
> Marketplace Order ID
Find a request sample with params below :
{
"type": "bg.order.shippinginfo.get"
"timestamp": timestamp,
"app_key": "app_key",
"data_type": "JSON",
"access_token": "access_token",
"parentOrderSn": "PO-069-1706194671671363"
}
Request mapping :
Temu field | Field type | Notes/Mapping |
---|---|---|
parentOrderSn |
STRING | Orders > Marketplace Order ID |
Example response :
{
"result": {
"result": {
"receiptAdditionalName": null,
"regionName3": "Lavender",
"regionName4": null,
"regionName1": "France",
"mail": "c437jtmpir13028@eu.shipping.temuemail.com",
"regionName2": "Bread",
"mobile": "+33 1 23 45 67 89",
"addressLineAll": "25 aaasteet",
"receiptName": "kanye west",
"addressLine1": "25 aaasteet",
"backupMobile": null,
"addressLine2": "",
"postCode": "99991",
"addressLine3": null
},
"success": true,
"errorCode": 1000000,
"errorMsg": null
},
"success": true,
"requestId": "eu-94fa2a34-dfda-4d81-a24d-4669ac382787",
"errorCode": 1000000,
"errorMsg": ""
}
Mapping :
Temu Field | Hemi Field | Notes | ||
---|---|---|---|---|
result |
||||
result |
||||
receiptAdditionalName |
N/A | |||
regionName3 |
Orders > Shipping City |
|||
regionName4 |
N/A | |||
regionName1 |
Orders > Shipping Country Name |
We also want to fill the 2 digit country code based on the country into Orders > Shipping Country Code |
||
mail |
Orders > Buyer mail |
|||
regionName2 |
Orders > Shipping State Province |
|||
mobile |
Orders > Shipping Phone |
|||
addressLineAll |
N/A | |||
receiptName |
Orders > Shipping Buyer Name |
|||
addressLine1 |
Orders > Shipping Street 1 |
|||
backupMobile |
N/A | |||
addressLine2 |
N/A | |||
postCode |
Orders > Shipping Postal Code |
|||
addressLine3 |
N/A | |||
success |
N/A | Incase of any error on this result level we will receive success = false |
||
errorCode |
N/A | |||
errorMsg |
Order Error > Message |
With type Order Download . We only want to look at this field if we receive success = false on this result level |
||
success |
N/A | Incase of any error on this result level we will receive success = false |
||
requestId |
N/A | |||
errorCode |
N/A | |||
errorMsg |
Order Error > Message |
With type Order Download . We only want to look at this field if we receive success = false on this result level . Incase we have errors on both result levels, we want to combine the error messages when saving the error. We also need to save the order with Orders > Order Status = Incomplete |
This means that if this call is returning any kind of error message with that “false” status we still want to store everything we can on the order in OMS just make sure we’ve tried all 3 calls to obtain all info and then due to this specific error here make the whole order as incomplete when storing it, store the right message and that’s it |
Example error response : 200 OK
{
"result": {
"result": null,
"success": false,
"errorCode": 40003,
"errorMsg": "invalid param"
},
"success": true,
"requestId": "eu-72da2dee-2ebf-4f00-b554-798c7b45b144",
"errorCode": 1000000,
"errorMsg": ""
}