Skip to content

Add AliExpress Affiliate and Dropshipping connectors with IOP request signing - #1346

Merged
helpcodeai merged 5 commits into
mainfrom
feat/aliexpress-iop-signing
Oct 30, 2026
Merged

helpcodeai merged 5 commits into
mainfrom
feat/aliexpress-iop-signing

Conversation

@helpcodeai

Copy link
Copy Markdown
Contributor

Summary

Adds AliExpress to the catalog as two connectors, AliExpress Affiliate and AliExpress Dropshipping, and extends the REST engine's HMAC signing so it can sign Alibaba "IOP" gateway requests. The two connectors are separate because AliExpress does not allow one Open Platform account to hold both an Affiliate and a Dropshipping app, so their credentials always differ.

The signing extension is opt-in. Kaufland and Shopee are signed exactly as before. Cloud and self-hosted behave the same: nothing here depends on the deployment mode.

Alibaba.com and 1688 are not included. The reasons are under "Not built" below.

Changes

  • REST engine, HMAC query signing (opt-in)
    • New template variable ${sortedParams}: every parameter sent, sorted by name and concatenated as name + value. It covers the query as sent (statics, credential parameters and the timestamp included) and the fields of a form-urlencoded body. Arrays and objects give the same pairs the query serializer sends. The sign parameter and empty values are left out, as in the official SDK.
    • New template variable ${apiPath}: the request path below the connector's baseUrl. It covers IOP /rest system calls, which sign /auth/token/create....
    • signature.encoding: "hex-upper".
    • signature.timestampFormat: "s" | "ms".
    • Rendering stays one pass. The serializer was split into flattenParams plus encoding; it gives the same output.
    • The new options are documented in the JSDoc and in docs/tool-definition.md (new "Query signing" subsection, which also documents the Shopee options).
  • aliexpress-affiliate (12 tools, all read-only): categories, product search, hot products, product details, SKU details, shipping, promotions and coupons, affiliate link generation, featured promotions and their products, affiliate orders (list and by id). Needs app key, app secret and a Portals tracking ID.
  • aliexpress-dropshipping (8 tools):
    • Read tools: member benefits (used as the probe, since it needs the token), categories, product search, product details, freight, order, tracking.
    • aliexpress_dropshipping_create_order (readOnlyHint: false) is installed switched off. It creates unpaid orders; the documented automatic-payment switch is never sent.
    • Uses a pasted access token. When it expires the call fails as an authentication error, and the instructions explain how to get a new one.
  • errorWhen rules for the gateway's HTTP 200 error_response, mapped to 401, 403, 429 and 400.
  • Logo aliexpress.svg (simple-icons 13.21.0, brand color #FF4747), catalog regenerated, quoted counts 572 → 574, llms.txt and llms-full.txt regenerated.
  • rest.engine.shopee.spec.ts: the list of query-signed HMAC adapters now includes the two new ones. Kaufland is still checked to use none of the new fields. rest.engine.hmac-pin.spec.ts is unchanged and still passes.

Verified against

  • Signature algorithm (docId 1386) and HTTP request sample (docId 1385) on openservice.aliexpress.com:
    • Business APIs: https://api-sg.aliexpress.com/sync?method=..., no path prefix, method is signed as a parameter.
    • System APIs: https://api-sg.aliexpress.com/rest{api_path}, API path in front.
    • Signature: HMAC-SHA256 in upper-case hex, millisecond timestamp, sign_method=sha256.
  • Both worked examples in the docs are pinned in tests (secret helloworld):
    • F7F7926B...5BBB for the business call.
    • 35607762...4D81 for /auth/token/create.
    • I recomputed both independently with Python's hmac module.
  • Official Java SDK, downloaded from the console's SDK link (IopUtils.signApiRequest, TopExecutor, GopExecutor):
    • Keys are sorted with Arrays.sort and empty values skipped.
    • TOP calls sign with an empty API name and send method; GOP calls prefix the API name.
    • The timestamp is Date.getTime() (milliseconds).
  • Parameters, types and example values: the API reference of the AE-Affiliate and AE-Dropshipper categories.
  • Error envelope: a real call to the gateway with an invalid app key returned HTTP 200 with {"error_response":{"type":"ISV","code":"InvalidAppKey","msg":...}}.

Access tokens (dropshipping)

I went with a pasted token rather than a token provider. The docs (docId 1590, 1364, 1365) say:

  • Access token lifetime depends on the app category and is shown on the console's Auth Management page. The documented refresh sample shows 30 days; apps in test status get 1 day.
  • A refresh token is valid for 30 days, at most 60.
  • A refresh resets the access token's lifetime but not the refresh token's.

So a refresh flow could stretch one authorization from about 30 days to at most about 60, and a new sign-in would still be needed after that. That gain doesn't justify a Shopee-style provider with its own authorize, callback and dashboard pieces. The user gets the token from the Open Platform API test tool ("Get Token").

Not built

  • Alibaba.com Open Platform (openapi.alibaba.com). The docs are public and the signing is the same IOP scheme (${apiPath}${sortedParams} would sign it), but:
    • App categories are Commercial Developer (ISVs serving Global Gold Suppliers) and Individual Developer (own store). Both need approval.
    • Seller authorization is limited to Global Gold Supplier accounts (docId 51, 52, 55).
    • The buyer sourcing APIs are aimed at sourcing partners (docId 96).
    • So a normal seller or buyer cannot use it self-service.
  • 1688 (open.1688.com):
    • Registration needs a 1688 account bound to a company-verified Alipay account, and the docs are Chinese only.
    • It signs differently (HMAC-SHA1 over URL path + parameters).

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)

Commands and results:

Directory Command Result
repo root node scripts/validate-adapters.mjs --warn 588 adapters, 588 passed, 0 failed; 1442 warnings, all existing, none for aliexpress-*
repo root node scripts/regenerate-catalog.mjs 588 adapters across 15 regions
repo root node scripts/adapter-count.mjs --check OK: every quoted count equals 574 adapters (27 keyless, 8922 tools)
repo root node scripts/generate-llms-txt.mjs llms.txt and llms-full.txt regenerated
packages/backend npx tsc --noEmit -p tsconfig.json no errors
packages/backend npx jest src/connectors/engines/rest.engine 12 suites, 195 tests passed (hmac-pin and shopee specs included)
packages/backend npx jest src/adapters/intl/aliexpress- 2 suites, 19 passed, 2 skipped (the live parts)
packages/backend npm test 814 suites passed, 4 skipped; 24152 tests passed, 1648 skipped. A first run under load had 2 CurlParser "ReDoS regression" timing tests (under 100 ms) fail; that spec passes alone and the full rerun was green, and this PR does not touch the curl parser.
packages/backend npm run lint 0 errors, 11 existing warnings, none in changed files; no unrelated rewrites

The live parts are gated by RUN_ALIEXPRESS_AFFILIATE_LIVE=1 and RUN_ALIEXPRESS_DROPSHIPPING_LIVE=1 and only read. They were not run: no AliExpress affiliate or dropshipping app was available.

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)
  • This PR has a descriptive title

Related Issues

None.

Open points for review

  • Token parameter name. The official HTTP sample sends the token as access_token on /sync, while the Java SDK's TOP executor sends it as session. The adapter follows the HTTP sample, which is not confirmed live.
  • Getting a token. The "Get Token" button of the API test tool exists in the console code (apiConsole.test.getToken), but I could not follow it without an account.
  • errorWhen codes. The status mapping uses patterns (Token|Session|Signature|AppKey → 401 and so on) rather than an official code list. InvalidAppKey and MissingParameter were seen live; the others are inferred.
  • Errors inside a successful result. Business errors inside a successful envelope (resp_code 402 or 405, is_success: false) are passed through to the model, because their path depends on the API name.

Opt-in on the query-signing path: ${sortedParams} and ${apiPath} template
variables, encoding hex-upper and timestampFormat ms. Signatures without
these options are computed as before (Kaufland and Shopee pins unchanged).
Tests pin both worked examples of the AliExpress Open Platform docs.
12 read tools on the AliExpress Open Platform Affiliate API: product
search, hot products, product and SKU details, shipping, coupons,
featured promotions, affiliate links and affiliate orders. Signed with
the app key and secret, IOP style; the tracking ID goes into every link.
8 tools on the AliExpress Dropshipping API: product search, product
details, freight, order, tracking and member benefits, plus order
creation installed switched off (orders are created unpaid). Uses a
pasted access token; an expired token is reported as an auth error.
@helpcodeai
helpcodeai enabled auto-merge (squash) October 30, 2026 18:02
@helpcodeai
helpcodeai merged commit 548f431 into main Oct 30, 2026
14 checks passed
@helpcodeai
helpcodeai deleted the feat/aliexpress-iop-signing branch October 30, 2026 18:12
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 30, 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.

2 participants