TikTok - Cancel Order
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 | 26.09.2024 | Hristiyan Georgiev | expanded logic for refund type |
v1.3 | 06.03.2025 | Milen Markov | Addition for cancellations of ‘partially shipped’ orders |
The purpose of this page is to give good understanding of the flow, where seller can cancel the order before the order is shipped.
<v1.1>
Cancel Order
API Call: POST /return_refund/202309/cancellations
API Docs: https://partner.tiktokshop.com/docv2/page/650aecb64a0bb702c076b03d#Back To Top
All triggers, validations etc are as per the abstraction Refunds send general logic
<v1.3> We need to be picking orders on Orders
> Status
= Ready for Shipping or Partially Shipped (only for the products that are not shipped). </v1.3>
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 request:
{
"cancel_reason": "ecom_order_delivered_refund_and_return_reason_wrong_product_seller",
"order_id": "577087614418520388",
"order_line_item_ids": [
"577087614418716996"
],
"skus": [
{
"quantity": 1,
"sku_id": "1729386416015578024"
}
]
}
Mapping:
Integration Field | Notes | Integration required | Hemi Mapping | Hemi Notes | |
---|---|---|---|---|---|
cancel_reason |
Yes | Order Payment Details > Reason |
We need to store the reasons in Hemi. Please see table with reasons below. | ||
order_id |
Yes | Orders > Marketplace Order ID |
|||
order_line_item_ids |
List of order line item ids to cancel. In the US and UK markets, when an item is out of stock, partial cancellation on the single item level is supported. To initiate a partial cancellation, we need to specify the item's order line id. | No | Order Item Line > Marketplace Order ID |
We need to create a validation and only use this object if we are doing a partial product refund and add the order_line_item_ids that is/are being refunded |
We want to skip this if we are doing a full refund and not include the property in the payload in such case as we will use the sku_id |
| skus
| | | No | | We have to exclude this object if we are sending partial product refund. |
| | quantity
| | Yes | | We need to calculate this since we do not do refunds based on quantity in Hemi. This would be the count of Order Refund Row Line
records |
| | sku_id
| | Yes | Product In Order
> Item Order Line ID
| |
Response example:
{
"code": 0,
"data": {
"cancel_id": "4035319218955782461",
"cancel_status": "CANCELLATION_REQUEST_SUCCESS"
},
"message": "Success",
"request_id": "202203070749000101890810281E8C70B7"
}
Mapping:
Integration Field | Hemi Mapping | Hemi Notes | |
---|---|---|---|
code |
|||
data |
|||
cancel_id |
Order Payment Details > Transaction ID |
with type “refund“ | |
cancel_status |
N/A | We expect to recieve CANCELLATION_REQUEST_SUCCESS or CANCELLATION_REQUEST_COMPLETE or CANCELLATION_REQUEST_PENDING . If we receive any other status we want to store an error stating that we have not received the expected status. | |
message |
N/A | ||
request_id |
N/A |
The successful response will be with code : 0
and message : Success
. If we receive a different code
than 0, this means there was an error and we need to store it in Order Errors
table with Type
= Refund Send
. The errors need to be mapped as per below response codes and we will receive the code but want to store the message :
Code | Message |
---|---|
25001001 | Invalid request parameters |
25001011 | There are processing return or cancel order exists |
25001014 | Unknown reason |
25001015 | This return/refund reason can not be used by sellers, please select the correct return/refund reason and try again. |
25001020 | The reason is offline |
25001021 | Reason not match order status |
25001028 | Another repeated request is processing |
25001045 | Unable to cancel shipment with the courier |
25001046 | Request was intercepted by TikTok risk control |
25001051 | Not allowed to return or cancel since order is completed or cancelled |
25005010 | Unable to cancel individual line items within this request |
25005011 | The requested line item(s) for refund or return exceeds the allowable limit. |
25020005 | No permission to process this order |
TikTok Refund Reasons
These reasons should be added in the Order Refund Reasons
table for distinct marketplace TikTok. The reasons should be available in the dropdown menu from the refund panel. The refund reasons should be in a format [REFUND] - reason and cancellations should be [CANCELLATION] - reason. We want to store the reason id in the backend but display the reason name in the refund panel.
TikTok seem to have slightly different reasons for the different regions.The difference is that we need to add “_uk” at the end of most of the reason IDs that is for the UK region but there are some minor differencies in the reasons themselves. So we need to create a validation that will check the TikTok account region (I suggest we do this validation based on Account
> Country
) and then use the correct reason based on the region.
Refund reason name | Reason id US | Reason id UK |
---|---|---|
[REFUND] Package lost | seller_shipped_refund_package_lost | seller_package_lost_uk |
[REFUND] Product wouldn't arrive on time | seller_shipped_refund_miss_estimated_delivery_date | ecom_order_shipped_refund_reason_not_arrive_on_time_seller_uk |
[REFUND] Missing product or accessories | ecom_order_delivered_refund_reason_missing_product_seller | ecom_order_delivered_refund_reason_missing_product_seller_uk |
[REFUND] Package wasn't received | ecom_order_delivered_refund_reason_not_received_seller | ecom_order_delivered_refund_reason_not_received_seller_uk |
[REFUND] Product doesn't match description | ecom_order_delivered_refund_reason_not_match_description_seller | ecom_order_delivered_refund_reason_not_match_description_seller_uk |
[REFUND] Package or product is damaged | ecom_order_delivered_refund_reason_damaged_seller | ecom_order_delivered_refund_reason_damaged_seller_uk |
[REFUND] Wrong product was sent | ecom_order_delivered_refund_reason_wrong_product_seller | ecom_order_delivered_refund_reason_wrong_product_seller_uk |
[REFUND] Missed estimated delivery date | seller_shipped_refund_miss_estimated_delivery_date | ecom_order_delivered_refund_reason_missed_delivery_date_seller_uk |
[REFUND] Product is defective or doesn't work | ecom_order_delivered_refund_reason_defective_seller | ecom_order_delivered_refund_reason_defective_seller_uk |
[REFUND] Suspected Counterfeit | buyer_refund_suspected_counterfeit_seller_uk | buyer_refund_suspected_counterfeit_seller_uk |
Cancel reason name | Reason id US | Reason id UK |
---|---|---|
[CANCELLATION] Out of stock | seller_cancel_reason_out_of_stock | seller_cancel_reason_out_of_stock_uk |
[CANCELLATION] Pricing error | seller_cancel_reason_wrong_price | seller_cancel_reason_wrong_price_uk |
[CANCELLATION] Buyer did not pay on time | seller_cancel_unpaid_reason_buyer_hasnt_paid_within_time_allowed | seller_cancel_unpaid_reason_buyer_hasnt_paid_within_time_allowed_uk |
[CANCELLATION] Unable to deliver to buyer address | seller_cancel_paid_reason_address_not_deliver | seller_cancel_paid_reason_address_not_deliver_uk |
Return Order
This is a post shipment refund that is initiated from the seller on the behalf of the buyer. Do not confuse it with buyer initiated return.
API Call: POST /return_refund/202309/returns
API Docs: https://partner.tiktokshop.com/docv2/page/650ae5fc4a0bb702c075d05d
We need to be picking orders on Orders
> Status
= Shipped or Partially Shipped.
All other triggers, validations etc are as per the abstraction Refunds send general logic
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 request:
{
"currency": "USD",
"handover_method": "DROP_OFF",
"order_id": "576473917261320779",
"order_line_item_ids": [
"455764739172614518516"
],
"refund_total": "10.5",
"return_reason": "ecom_order_delivered_refund_reason_missing_product_seller",
"return_type": "REFUND",
"shipment_type": "PLATFORM",
"skus": [
{
"quantity": 1,
"sku_id": "1729386416015578024"
}
]
}
Mapping:
Integration Field | Notes | Integration required | Hemi Mapping | Hemi Notes | |
---|---|---|---|---|---|
currency |
No | N/A | |||
handover_method |
No | N/A | |||
order_id |
Yes | Orders > Marketplace Order ID |
|||
order_line_item_ids |
No | Order Item Line > Marketplace Order ID |
We need to create a validation and only use this object if we are doing a partial refund and add the order_line_item_ids that is/are being refunded |
We want to skip this if we are doing a full refund and not include the property in the payload in such case as we will use the sku_id |
| refund_total
| | | No | Order Payment
Details
> Total Amount
| For Order Payment
with Type
= Refund |
| return_reason
| | | Yes | Order Payment
Details
> Reason
| As per the reasons table above. |
| return_type
| | Which type to create:
- REFUND
- RETURN_AND_REFUND | Yes |
Order Payment Details
>Refund Type
| We need to create a mapping. If we haveOrder Payment Details
>Refund Type
= Order Full Refund we send REFUND <v1.2>If we haveOrder Payment Details > Refund Type
= Partial Refund we send REFUND If we haveOrder Payment Details > Refund Type
= Items Full Refund we send REFUND</v1.2> If we haveOrder Payment Details
>Refund Type
= Return we send RETURN_AND_REFUND | |shipment_type
| | | No | N/A | | |skus
| | | No | | We have to exclude this object if we are sending partial line refund. | | |quantity
| | Yes | | We need to calculate this since we do not do refunds based on quantity in Hemi. I suggest we calculate it based on theOrder Refund Row
>Amount
but its up to devs to decide | | |sku_id
| | Yes |Product In Order
>Item Order Line ID
| |
Example response :
{
"code": 0,
"data": {
"return_id": "4035319218955782461",
"return_status": "RETURN_OR_REFUND_REQUEST_PENDING"
},
"message": "Success",
"request_id": "202203070749000101890810281E8C70B7"
}
Response mapping :
Integration Field | Hemi Mapping | Hemi Notes | |
---|---|---|---|
code |
|||
data |
|||
return_id |
Order Payment Details > Transaction ID |
with type “refund“ | |
return_status |
N/A | ||
message |
N/A | ||
request_id |
N/A |
The successful response will be with code : 0
and message : Success
. If we receive a different code
than 0, this means there was an error and we need to store it in Order Errors
table with Type
= Refund Send
. The errors need to be mapped as per below response codes and we will receive the code but want to store the message :
Code | Message |
---|---|
25001001 | Invalid request parameters |
25001003 | Invalid order status |
25001010 | There are completed return or cancel order exists |
25001011 | There are processing return or cancel order exists |
25001014 | Unknown reason |
25001015 | This return/refund reason can not be used by sellers, please select the correct return/refund reason and try again. |
25001020 | The reason is offline |
25001021 | Reason not match order status |
25001028 | Another repeated request is processing |
25001042 | Return package create failed. |
25001046 | Request was intercepted by TikTok risk control |
25001051 | Not allowed to return or cancel since order is completed or cancelled |
25005005 | Refund total is bigger than the refundable amount |
25005010 | Unable to cancel individual line items within this request |
25005011 | The requested line item(s) for refund or return exceeds the allowable limit. |
25020005 | No permission to process this order |
</v1.1>