Marketplaces / TikTok Marketplace Integration v2 / TikTok - Authentication & Database structure

TikTok - Authentication & Database structure

Summary of Changes: (The purpose of this table is to keep traceability and Product team to highlight the things that were changed into the scope, based on comments or discussions)

Date Version Created/Updated Comment
14/05/2024 1.1 Hristiyan 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.1>

Purpose of this document is to provide information on the TikTok authentication requirements & Database structure.

Sandbox account:

End points:

Auth: https://auth-sandbox.tiktok-shops.com

All others APIs: https://open-api-sandbox.tiktokglobalshop.com

Please note that we need to add the end points to integration in order to switch between sandbox and prod account

Credentials: TikTok sandbox shop: https://seller-sandbox.tiktok.com/uk/homepage

Username: sandbox_uklc_1ujluezusia@shop.tiktok.com Pass: 98dAQAiG8N3

Authentication

Docs:

TikTok Shop Partner Center

First, we need to get an authorization code, using this link:

https://auth.tiktok-shops.com/oauth/authorize?app_key=123abc&state=123 which we have to generate based on the details we have in Integration Credentials and sent to the Account TikTok > Client email. From there once the link is followed we need to approve the authorization and in the url will receive the auth_code using callbacks. We want to have a button in Account TikTok table which will be called Start TikTok authorisation. Upon pressing this button the user should receive the link in the email that was filled. After the button is pressed, we should raise the flag of Account TikTok1 > OAuth Began = Yes

Into this link, we need to replace app_key and state with our app_key & our state code. The key will be in the Integration Credentials table

Example:

appKey = '123abc'//your key
state = '123abs'//your origin state
//expect url  below, trim the space
https://auth.tiktok-shops.com/oauth/authorize?app_key=key&state=123abs

After successful authorization approval, the seller will be redirected to the Redirect URL we provided in ourapp. This URL will contain a temporary auth_code as a query parameter. This code will expiree in 30 min and can only be used once.

{redirect_url}?code=FeBoANmHP3yqdoUI9fZOCw&state={state}

In the generated link after the redirect we will get the field Auth_Code which is required for the integration(in order to get the Access token)

Once we get the authorization code, we need to “exchange“ it for an access token & refresh token:

1. Request access token and refresh token

To request access and refresh tokens we need to ensure we have a valid auth_code before requesting

API Call: GET **auth.tiktok-shops.com/api/v2/token/get

Docs: https://partner.tiktokshop.com/docv2/page/6632a7a926b40c02d97de61b#Back To Top

Request Parameters:

TikTok Field Description Type Required Hemi Field Notes
app_key string Yes N/A App key in Partner Center app page.

This will be available in the Integration Credentials table | | app_secret | Your private app secret, please keep it as a secret. | string | Yes | N/A | App secret in Partner Center app page

This will be available in the Integration Credentials | | auth_code | The auth_code we obtained in the first step | string | Yes | N/A | | | grant_type | The way we grant token. Only "authorized_code" is accepted. | string | Yes | authorized_code | |

If all the parameters entered in the GET request are valid, the response will contain the following parameters:

Parameter Type Description Sample
access_token string User access token needed to make calls to TikTok Shop Open API endpoints TTP_RLM6CIADWF606TZGFO5XGA
access_token_expire_in Unix timestamp Expiration timestamp for access token, with default expiration time set to seven days. The Unix timestamp represents the date and time the access token will expire. 1630401330
refresh_token string A token to refresh the access token TTP_C2XWDN63ON-FOHJSMR0WSG
refresh_token_expire_in Unix timestamp Expiration timestamp for refresh token. The Unix timestamp represents the date and time the refresh token will expire. 1630401510
open_id string The ID to help you identify a TikTok Shop seller in your platform ephr6QAAAADhos3OBMztFEwRCWQGzDmfXm_7O2OTJyaYKA15pIaiEg
seller_name string The name of the seller you are authorizing for your app Test Name
seller_base_region string The region where the seller is based US
user_type int Type of user, with possible values: 0: Seller 1: Creator 1
request_id string ID to track the API request 2022080809462301024509910319695C45

Example Response:

{      
"code":0,      
"message":"success",      
"data":{      
        "access_token":"TTP_Fw8rBwAAAAAkW03FYd09DG-9INtpw361hWthei8S3fHX8iPJ5AUv99fLSCYD9-UucaqxTgNRzKZxi5-tfFMtdWqglEt5_iCk",      
        "access_token_expire_in":1660556783,      
        "refresh_token":"TTP_NTUxZTNhYTQ2ZDk2YmRmZWNmYWY2YWY2YzkxNGYwNjQ3YjkzYTllYjA0YmNlMw",      
        "refresh_token_expire_in":1691487031,      
        "open_id":"7010736057180325637",      
        "seller_name":"Jjj test shop",      
        "seller_base_region":"ID",      
        "user_type":0      
    },      
"request_id":"2022080809462301024509910319695C45"      
}

Mapping:

TikTok Field Description Type Required Hemi Field Notes
code N/A
message N/A
data
access_token Token for you access data of tt seller string N/A To be stored in cache
access_token_expire_in Expire date for your at. Initial expire duration is 7 days Unix timestamp N/A
refresh_token Token to refresh your access token string To be stored in Hemi but not visible in the UI If the access token is expired, we use the refresh token to get a new access token and its expiration date.
refresh_token_expire_in Unix timestamp Account TikTok > Refresh Token Expiration Date We should display the date in human readable format into the UI
open_id The unique identity of the tts seller in this app, which is not equal to shop_id. Please use our shop api to obtain your shop id: Shop API string N/A Equal to Shop ID
seller_name The name of the seller who authorize you app string N/A
request_id ID to track the request string N/A

Please note the access will be stored into the cache and the integration will need to check and refresh it when need. refresh token will be stored into the account but not visible in the UI) Once the refresh token is expired we also need to receive some sort of notification or error message (will not receive notifications at this moment). Once we have generated the access and the refresh token, we will need to regenerate the Access Token using the following:

2. Refresh Access Token

API Call: GET auth.tiktok-shops.com/api/v2/token/refresh

TikTok suggests refreshing the access_token  every 7 days using a refresh_token however, we want to refresh the access token on daily basis. Failure to refresh before its expiration will result in authentication failure when attempting to request data through TikTok Shop APIs.

The refresh_token_expire_in is equivalent to the authorization duration provided when the seller initially authorized app access.

The access_token remains valid until the refresh_expire_date, which is returned in the response.

Request Parameters:

TikTok Field Description Type Required Hemi Field Notes
app_key string Yes
app_secret Your private app secret, please keep it as a secret. string Yes
refresh_token The code you obtain in the last step string Yes The refresh token is from the response of "Get AccessToken&RefreshToken" API ( see the step above “1“)
grant_type The way you grant token. only "refresh_token" is accepted. string Yes Fixed value “refresh_token“

Example Response:

{      
"code":0,      
"message":"success",      
"data":{      
        "access_token":"TTP_Fw8rBwAAAAAkW03FYd09DG-9INtpw361hWthei8S3fHX8iPJ5AUv99fLSCYD9-UucaqxTgNRzKZxi5-tfFMtdWqglEt5_iCk",      
        "access_token_expire_in":1660556783,      
        "refresh_token":"TTP_NTUxZTNhYTQ2ZDk2YmRmZWNmYWY2YWY2YzkxNGYwNjQ3YjkzYTllYjA0YmNlMw",      
        "refresh_token_expire_in":1691487031,      
        "open_id":"7010736057180325637",      
        "seller_name":"Jjj test shop",      
        "seller_base_region":"ID",      
        "user_type":0      
    },      
"request_id":"2022080809462301024509910319695C45"      
}

Mapping:

TikTok Field Description Type Hemi Field Notes
code
message
data
access_token Token for access data of tt seller string To be stored in cache
access_token_expire_in Expire date for your at. Initial expire duration is 7 days Unix timestamp N/A
refresh_token Token to refresh your access token string N/A
refresh_token_expire_in After 3.11 : Final Expired date of your authorization. The duration would be extended to 365d. Unix timestamp Account TikTok > Refresh Token Expiration Date
open_id The unique identity of the tts seller in this app, which is not equal to shop_id. Please use our shop api to obtain your shop id: Shop API string N/A
seller_name The name of the seller who authorize you app string N/A
request_id ID to track the request string N/A

Sign generation:

https://partner.tiktokshop.com/docv2/page/6632a7c850b2bd02d91d21b4

When calling a TikTok Shop API, a signature must be included to properly authenticate our request. All requests that do not include a signature, or have an invalid signature, will be denied access.

TikTok Shop APIs use HMAC-SHA256 as the default algorithm for generating signatures.

HS256 (HMAC with SHA-256) is a symmetric algorithm, meaning there is only one private key that is shared between the two parties. Since the same key is used to both generate and validate the signature, care must be taken to ensure that the key is not compromised.

When TikTok Shop receives an authenticated request, it recreates the signature using the authentication information contained in the request. If the signatures match, the service processes the request. Otherwise, it rejects the request.

Get Authorised Shops (new call)

****In cross-border scenarios, sellers may have multiple shops. Not all of these shops may be authorized by the developer for API access (authorized to be managed by apps or solutions in the TikTok Shop App Marketplace). Use this API to check which shops are authorized to be serviced by TikTok Shop APIs. This should be automatically triggered after successfull authorisation (after we have successfully stored access token for the given account)

API Call : GET /authorization/202309/shops Api Docs : https://partner.tiktokshop.com/docv2/page/6507ead7b99d5302be949ba9?external_id=6507ead7b99d5302be949ba9#Back To Top

Request sample :

https://open-api.tiktokglobalshop.com/authorization/202309/shops?app_key=123abc&sign=5361235029d141222525e303d742f9e38aea052d10896d3197ab9d6233730b8c&timestamp=1625484268

Sample Response :

{
  "code": 0,
  "data": {
    "shops": [
      {
        "cipher": "GCP_XF90igAAAABh00qsWgtvOiGFNqyubMt3",
        "code": "CNGBCBA4LLU8",
        "id": "7000714532876273420",
        "name": "Maomao beauty shop",
        "region": "GB",
        "seller_type": "CROSS_BORDER"
      }
    ]
  },
  "message": "Success",
  "request_id": "202203070749000101890810281E8C70B7"
}

Response mapping :

TikTok Field Description Type Hemi Field Comment
code The success or failure status code returned in API response. int N/A
data Specific return information object N/A
shops Seller uses their TikTok Shop seller account to authorize developer. The list of object shows all shops authorized by a TikTok Shop seller to developer. []object N/A
cipher Use this property to pass shop information in requesting the API. Failure in passing the correct value when requesting the API for cross-border shops will return incorrect response.
Required for cross-border shops, and optional for local shops. string We don’t want to display the cipher in the UI. We want to store this in the database (but not visible for the user) as it is only needed for some API calls. We have to make sure we are keeping the correct cipher for the correct region (if more than one regions are available)
code TikTok Shop code. string N/A
id TikTok Shop Id. string N/A
name TikTok Shop name. string N/A
region Region of the shop. string N/AC We want to map this with Account > Country so we know which shop is it for. (if there are more than one regions on the TikTok seller account)
seller_type Indicate the seller is "CROSS_BORDER" or "LOCAL". string N/A
message
request_id

Database Structure

Here is a diagram showing the newly created tables for the integration and their relation to the existing ones.

Integration Credentials - here we store our application ids. Please note this table is not visible in the UI and the details are the same for all instances.

Field Name Type Required Comment Default Value
Integration ID Textbox Yes Id combining all keys for the integration
Secret Key Textbox Yes The actual key
Secret Name Textbox Yes The name of the key (api_key, api_secret_key)

Also we need to create a new record for TikTok in Integration table.

Account TikTok - here we store the required details for the integration. Slave table of Account table used for the account setup:

Field Name Type Required Comment Default Value
Client Email varchar Yes This is mainly required for the authentication process. Where we will receive the link for the Authentication
OAuth Began tinyint/checkbox No This indicates whether the authentication process has started or not. It will be used internally by the integration in order to send the email only once, not every time a cron starts. No
Shop ID varchar Yes The actual key
Integration int Yes Dropdown list of all TikTok integrations. (Integration + Integration Credentials should be saved first in order to have options in the dropdown.)
Start TikTok authorisation button This should be a button that will generate a link and send it to the email so the user can install the app in TikTok. After click on the button we want to have toast notification with the result.
Refresh Token Expiration Date varchar No We will store the date in human readable format
Default Courier dropdown No Enumeration dropdown field with the available couriers

TikTok Delivery Options - Here we store the delivery options and their desription.

Field Name Type Required Comment Default Value
Delivery option ID Textbox No Id of the delivery option
Descriptoin Textbox No The description of the delivery option

Signature algorithm

When calling a TikTok Shop API, a signature must be included to properly authenticate your request. All requests that do not include a signature, or have an invalid signature, will be denied access.

TikTok Shop APIs use HMAC-SHA256 as the default algorithm for generating signatures.

HS256 (HMAC with SHA-256) is a symmetric algorithm, meaning there is only one private key that is shared between the two parties. Since the same key is used to both generate and validate the signature, care must be taken to ensure that the key is not compromised.

When TikTok Shop receives an authenticated request, it recreates the signature using the authentication information contained in the request. If the signatures match, the service processes the request. Otherwise, it rejects the request.

Use the following code to generate your API request signature:

📌 Note: The following code is written in Go, so we need to translate this to php

import (
    "crypto/hmac"
    "crypto/sha256"
    "encoding/hex"
    "io"
    "net/http"
    "sort"
)

// secret: App secret
func CalSign(req *http.Request, secret string) string {
    queries := req.URL.Query()

// extract all query parameters excluding sign and access_token
    keys := make([]string, len(queries))
    idx := 0
    for k := range queries {
// params except 'sign' & 'access_token'
        if k != "sign" && k != "access_token" {
            keys[idx] = k
            idx++
        }
    }

// reorder the parameters' key in alphabetical order
    sort.Slice(keys, func(i, j int) bool {
        return keys[i] < keys[j]
    })

// Concatenate all the parameters in the format of {key}{value}
    input := ""
    for _, key := range keys {
        input = input + key + queries.Get(key)
    }

// append the request path
    input = req.URL.Path + input

// if the request header Content-type is not multipart/form-data, append body to the end
    mediaType, _, _ := mime.ParseMediaType(req.Header.Get("Content-type"))
    if mediaType != "multipart/form-data" {
        body, _ := io.ReadAll(req.Body)
        input = input + string(body)

        req.Body.Close()
// reset body after reading from the original
        req.Body = io.NopCloser(bytes.NewReader(body))
    }

// wrap the string generated in step 5 with the App secret
    input = secret + input + secret

    return generateSHA256(input, secret)
}

func generateSHA256(input, secret string) string {
// encode the digest byte stream in hexadecimal and use sha256 to generate sign with salt(secret)
    h := hmac.New(sha256.New, []byte(secret))

    if _, err := h.Write([]byte(input)); err != nil {
// TODO error log
        return ""
    }

    return hex.EncodeToString(h.Sum(nil))
}

More information & detailed step-by-step sign generation algorithm can be found in the documentation link provided above.

Common mistakes

What is the most common reason for encountering the "signature is invalid" error during an API call?

  • Frequently, this error occurs when developers use incorrect app keys and secrets to generate the signature. It's essential to verify that the app key and secret match precisely.
  • Ensure sign and access_token are not included in the reordered query keys (Step 2).
  • Always ensure that you are using the HMAC-SHA256 signature method (different from regular SHA-256).
  • Ensure that the timestamp is within 5 minutes of the current time when the platform receives the request. The timestamp must be represented as a 10-digit Unix timestamp.

</v1.1>

Is this article helpful?
0 0 0