Repository navigation
Add a TikTok Shop Seller connector with its own shop authorization - #1523
Merged
Merged
Conversation
- 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).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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_idlink, 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 anx-tts-access-tokenheader and sign the path, the sorted query and the body with the app secret. Shop calls also need ashop_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 Cloudhttps://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 throughauthType: HMAC+authConfig.tokenProvider: "tiktok-shop"):auth.tiktok-shops.com; expiry is read from the Unix timestamps TikTok returns;needs_reauthand sends one owner email;TIKTOK_SHOP_SHOP_ID(id, code or name) picks one, else the first is used.RestEngine:shop_ciphercredential parameter, except on/authorization/,/seller/and upload paths;105002or an invalid-token36009004;signature.excludeMultipartBodysigns multipart uploads without their body, as TikTok does. Existing HMAC adapters are unchanged; the Shopee pin spec now liststiktok-shopamong the query-signed adapters./api/tiktok-shop/connectors/:id/authorize,/callbackand/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 toservices.us.tiktokshop.com.needs_authorization, import probe skipped until authorized, egress hint for TikTok's IP allow-list error (36009033).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.errorWhenmaps TikTok'scodeto 401, 403, 429 and 400.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 Products202502, Edit and Partial Edit Product202509, Search Returns and Cancellations202602, Mark Package As Shipped202610. Public SDKs and MCP servers were used only to cross-check paths; no code or text was copied.Type
Testing
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 Pythonhmac; 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 byRUN_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:
node scripts/validate-adapters.mjs --warninstructionFactsnode scripts/regenerate-catalog.mjsnode scripts/adapter-count.mjs --checkpackages/backendnpm run lintpackages/backendnpx tsc --noEmit -p tsconfig.jsonpackages/backendnpx jest --maxWorkers=4(full suite)rest.engine.shopee.spec.ts(the opt-in pin listing query-signed adapters, updated in this PR, then 8/8 pass), andauth/jwt-or-management-key.guard.spec.ts(needs a live, migrated database;prisma.organization.createfails inbeforeAll; the code it tests is untouched; baseline failure in this environment)packages/backendrest.engine.shopee.spec.tspackages/frontendnpm run lintpackages/frontendnpx tsc --noEmit -p tsconfig.jsonChecklist
npm test): one DB-backed baseline failure, see aboveRelated Issues
Closes #1522
Not verified against TikTok directly:
202610Mark Package As Shipped schema (order_line_list+shipping_info_list) is live in every market.