Skip to content

Add a TikTok Shop Seller connector with its own shop authorization - #1523

Merged
helpcodeai merged 4 commits into
mainfrom
feat/tiktok-shop
Nov 5, 2026
Merged

helpcodeai merged 4 commits into
mainfrom
feat/tiktok-shop

Conversation

@helpcodeai

Copy link
Copy Markdown
Contributor

Summary

Adds a TikTok Shop Seller catalog connector, as proposed in #1522. TikTok Shop does not use standard OAuth 2. The seller authorizes through a service_id link, TikTok redirects to the one Redirect URL set on the app, and the code is exchanged with a GET that carries the app key and secret. Calls send the token in an x-tts-access-token header and sign the path, the sorted query and the body with the app secret. Shop calls also need a shop_cipher. So this PR adds a token provider like the Shopee one (#1147) and an adapter that uses the existing query-signing options.

Cloud and self-hosted: both work the same way. The connector uses the seller's own TikTok Shop app (App key, App secret, Service ID), whose Redirect URL is <SERVER_URL>/api/tiktok-shop/callback, on Cloud https://cloud.anythingmcp.com/api/tiktok-shop/callback. TikTok only lets sellers with an assigned account manager register as seller developers, and the instructions say so. A public AnythingMCP app for Cloud is not part of this PR; the provider does not preclude it.

Changes

  • TikTokShopTokenService (opt-in through authType: HMAC + authConfig.tokenProvider: "tiktok-shop"):
    • code exchange and refresh on auth.tiktok-shops.com; expiry is read from the Unix timestamps TikTok returns;
    • renewal starts within a day of expiry (tokens last 7 days), one renewal per connector, in process and under a Postgres advisory lock;
    • a refused refresh token, or an authorization period that has ended, marks the connector needs_reauth and sends one owner email;
    • the shop cipher is read from Get Authorized Shops. When several shops are authorized, the optional TIKTOK_SHOP_SHOP_ID (id, code or name) picks one, else the first is used.
  • RestEngine:
    • sends the token header and the signed shop_cipher credential parameter, except on /authorization/, /seller/ and upload paths;
    • renews once and re-signs after 105002 or an invalid-token 36009004;
    • new opt-in signature.excludeMultipartBody signs multipart uploads without their body, as TikTok does. Existing HMAC adapters are unchanged; the Shopee pin spec now lists tiktok-shop among the query-signed adapters.
  • /api/tiktok-shop/connectors/:id/authorize, /callback and /complete, on the same encrypted single-use attempt store. The user who started the flow is checked before it is consumed. US shops (TIKTOK_SHOP_MARKET=US) go to services.us.tiktokshop.com.
  • Setup status needs_authorization, import probe skipped until authorized, egress hint for TikTok's IP allow-list error (36009033).
  • Dashboard: Authorize card on the connector page, completion page and setup page routing; en/de/it strings.
  • Adapter intl/tiktok-shop.json, 35 tools: authorized shops, orders (search, detail, price detail), products (search, detail, inventory), categories, attributes, rules, brands, warehouses, delivery options and carriers, packages, handover slots, shipping documents (label and packing slip), tracking, returns, cancellations, statements, order settlements, and an image upload from a link.
    • Installed switched off: ship package, mark package shipped, update tracking, create, full edit and partial edit of a product, stock update, price update, activate and deactivate.
    • errorWhen maps TikTok's code to 401, 403, 429 and 400.
  • Logo, catalog regeneration, quoted counts (695), docs/tool-definition.md (the TikTok template, excludeMultipartBody, and a section on the two shop token providers).

Paths, versions and fields follow TikTok's API reference (Partner Center docs, API Reference pages). Each tool uses the version the current reference documents: for example Get Order Detail 202507, Search Products 202502, Edit and Partial Edit Product 202509, Search Returns and Cancellations 202602, Mark Package As Shipped 202610. Public SDKs and MCP servers were used only to cross-check paths; no code or text was copied.

Type

  • Bug fix
  • New feature
  • Documentation
  • Refactoring
  • Performance improvement
  • Other (describe below)

Testing

  • Added/updated unit tests
  • Tested manually (describe steps below)
  • No tests needed (explain why)

New specs:

  • tiktok-shop-token.service.spec.ts (18 tests): signature vectors, link building, classifiers, exchange, refresh, refusal, rate limit, expired authorization, lazy shop cipher, burst renewal.
  • rest.engine.tiktok-shop.spec.ts (6 tests): signatures through the real engine against vectors computed independently with Python hmac; multipart upload; error in a 200 answer; renewal and retry.
  • tiktok-shop-auth.controller.spec.ts (7 tests).
  • intl/tiktok-shop.live.spec.ts (48 static tests: every tool's method, path, query, body and signature; the live block is gated by RUN_TIKTOK_SHOP_LIVE=1).

Not tested live: no Partner Center app or development shop was available. The live block is not run.

Commands and results:

Directory Command Result
repo root node scripts/validate-adapters.mjs --warn exit 0. Same warning count as main (1453 lines); the two new optional-variable warnings were resolved with instructionFacts
repo root node scripts/regenerate-catalog.mjs regenerated, 711 adapters across 15 regions
repo root node scripts/adapter-count.mjs --check OK: 695 adapters (35 keyless, 12308 tools)
packages/backend npm run lint 0 errors, 11 warnings, all in untouched files; no unrelated rewrites
packages/backend npx tsc --noEmit -p tsconfig.json clean
packages/backend npx jest --maxWorkers=4 (full suite) 1002 suites passed, 6 skipped. 2 failed: rest.engine.shopee.spec.ts (the opt-in pin listing query-signed adapters, updated in this PR, then 8/8 pass), and auth/jwt-or-management-key.guard.spec.ts (needs a live, migrated database; prisma.organization.create fails in beforeAll; the code it tests is untouched; baseline failure in this environment)
packages/backend targeted: the four TikTok Shop specs + rest.engine.shopee.spec.ts 18 + 6 + 7 + 48 (1 skipped live) + 8 passed
packages/frontend npm run lint 0 errors, 51 warnings, none in the changed code
packages/frontend npx tsc --noEmit -p tsconfig.json clean

Checklist

  • My code follows the existing code style
  • I have tested my changes locally
  • I have updated documentation (if applicable)
  • All existing tests pass (npm test): one DB-backed baseline failure, see above
  • This PR has a descriptive title

Related Issues

Closes #1522

Not verified against TikTok directly:

  • The error codes TikTok returns when it refuses a refresh token. Any non-zero code is treated as a refusal except rate limits, internal errors, timeouts and app key or secret errors.
  • Whether the 202610 Mark Package As Shipped schema (order_line_list + shipping_info_list) is live in every market.
  • The Partner Center scope names quoted in the instructions.

- TikTokShopTokenService: code exchange and renewal on
  auth.tiktok-shops.com (GET, expiry read from the Unix timestamps
  TikTok returns), one renewal per connector under an advisory lock,
  needs_reauth and one email when the refresh token is refused, the
  shop cipher read from Get Authorized Shops. Only connectors with
  authType HMAC and authConfig.tokenProvider "tiktok-shop" reach it.
- The engine sends the access token in x-tts-access-token and the shop
  cipher as a signed credential parameter (not on the authorization,
  seller and upload paths), and renews once after a 105002 rejection.
- signature.excludeMultipartBody (opt-in) leaves a multipart body out
  of the signed string, as TikTok signs image uploads.
- /api/tiktok-shop authorize, callback and complete endpoints on the
  encrypted single-use attempt store; the dashboard card, completion
  page and setup page route TikTok Shop connectors to them.
- TikTok's IP allow-list refusal (36009033) gets the egress IP hint.
35 tools on the TikTok Shop Open API for one authorized shop:
authorized shops, order search, order detail and price detail,
product search, detail and inventory, categories, category
attributes and rules, brands, warehouses, delivery options and
carriers, packages, handover slots, shipping documents, order
tracking, returns, cancellations, statements and order settlements,
and a product image upload from a link.

Shipping (ship package, mark shipped, update tracking), product
create, full and partial edit, stock and price updates, activate and
deactivate install switched off.

Logo, catalog and quoted adapter counts (695).
@helpcodeai
helpcodeai requested a review from D3nisty as a code owner November 5, 2026 07:57
@helpcodeai
helpcodeai merged commit c5bb3db into main Nov 5, 2026
14 checks passed
@helpcodeai
helpcodeai deleted the feat/tiktok-shop branch November 5, 2026 08:19
@github-actions github-actions Bot locked and limited conversation to collaborators Nov 5, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Adapter: TikTok Shop Seller (Open API 202309) with its own shop authorization

2 participants