01-跨境电商平台对接
对应代码: 下所有 服务 + 关键代码: 集团跨境电商业务横跨 **Amazon、eBay、Shopee、Temu、TikTok Shop、Walmart 等 18+ 平台**,每个平台存在以下差异: 1. **API 规范差异**:Ama
所属领域:平台数据同步 / 多平台授权 / 架构设计 / 数据标准化
对应代码:E:\WorkSpace\codo\esync下所有esync-{平台}服务 +E:\WorkSpace\codo\creeks\creekson-mall
关键代码:
- Amazon Report 封装:
esync-amazon/.../job/report/mws/handler/+.../job/report/sp/- 多平台授权:
creekson-mall/creekson-mall-server/src/.../service/impl/*AuthServiceImpl.java
一、背景与痛点
集团跨境电商业务横跨 Amazon、eBay、Shopee、Temu、TikTok Shop、Walmart 等 18+ 平台,每个平台存在以下差异:
- API 规范差异:Amazon 有 MWS → SP API 两代体系;Temu/TikTok Shop 走开放平台 OAuth + 签名;eBay 有 SOAP + REST 两套接口;Wish 存在 v1 → v3 双版本迁移
- 授权与认证差异:OAuth2 流程、Token 刷新频率、API Key 签名方式各不同;同一平台可存在多套授权来源(如 Amazon 既有 SP-API 官方授权,也有 Creekshub 内部中台、SellFox 第三方聚合器)
- 数据拉取机制差异:Amazon 采用"创建报告任务 → 轮询状态 → 完成后下载"的异步机制;Temu/TikTok 支持同步拉取 + 增量标识;eBay 支持 Webhook 推送
- 限流策略差异:各平台 QPS 限制、时间窗口限制(SHEIN 48 小时、TikTok 10 天、eBay 订单 30 分钟)各不相同
- 数据结构差异:同一概念(如 SKU、Order Item、Inventory)在不同平台的字段名、枚举值、层级嵌套完全不同
如果直接在业务系统内对接:
- 核心系统被平台逻辑污染,一个平台的异常会波及全局
- 扩展新平台需改核心代码,耦合度高、测试成本高
- 授权与数据同步耦合,Token 管理混乱,故障难以隔离
需要一套统一的授权体系 + 可复制的平台接入架构。
二、技术方案
2.1 整体架构
前端/浏览器
|
OAuth 授权跳转
|
┌──────────────────────────────┐
│ creekson-mall │ ← 统一授权中心
│ *AuthService (各平台实现) │
│ MySQL: mall_account/store │
│ Redis: state/token 缓存 │
│ AccountTokenSyncService │ ← Token 同步 REST API
└──────────┬───────────────────┘
│ AccountToken (REST)
▼
┌──────────────────────────────┐
│ esync-amazon / esync-ebay │
│ esync-shopee / esync-temu │ ← 一平台一服务
│ esync-wish / ... │
│ │
│ Fetch Task (HTTP Scheduler) │ ← 外部触发,非 cron
│ MongoDB: 源数据持久化 │
│ Converter: 平台→ERP 模型 │
│ Kafka Producer: 双 topic │
└──────────┬───────────────────┘
│ Kafka (平台 topic + 订单池 topic)
▼
┌──────────────────────────────┐
│ creeks-fulfillment (履约) │
│ creeks-order-center (订单池)│
│ creeks-inventory (库存) │
│ creeks-sales (商品) │
│ creeks-finance (财务) │
└──────────────────────────────┘
2.2 统一授权中心(creekson-mall)
定位:Creeks ERP 系统中统一的第三方电商平台授权与店铺管理微服务,为所有 esync-* 数据同步服务提供 Token。
支持平台(15+):
| 平台 | 授权实现 | OAuth/认证方式 | Token 管理特点 |
|---|---|---|---|
| Amazon | AmazonAuthServiceImpl |
LWA (Login with Amazon) | ~1h access / refresh 长期有效,通过 LWA /auth/o2/token 刷新 |
| eBay | EBayAuthServiceImpl |
OAuth2 Authorization Code | 2h access / 1.5y refresh,支持 ecpp 中转 + creeks 自有双路径 |
| Shopee | ShopeeAuthServiceImpl |
HMAC-SHA256 签名(非标准 OAuth2) | 4h access / 30d refresh,Redis 缓存 + 分布式锁防并发刷新 |
| Temu | TemuAuthServiceImpl |
API Key | 手动录入 token,无 refresh_token |
| TikTok Shop | TiktokShopServiceImpl |
Access Token | Mall 统一管理 |
| AliExpress | AliExpressAuthServiceImpl |
淘宝 Top API | OAuth2 + TaobaoClient SDK |
| ... | 其他 10+ 平台 | 各自 OAuth/OAuth2/签名 | 统一数据模型 |
授权架构 — "每平台独立实现 + 统一数据模型":
- 独立授权实现:每个平台独立编写 OAuth/签名逻辑,适配各自的授权流程
- 统一数据模型:所有平台共用
mall_account+mall_account_authorization+mall_store模型,通过platform_id+api_type+auth_developer区分 - 多授权来源:同一平台可同时存在多套授权(如 Amazon 有 SP-API 官方授权 + Creekshub 内部中台 + SellFox 第三方 + Captain 船长BI + 广告授权等)
Token 同步服务(AccountTokenSyncService):
esync-* 服务通过 REST API 从 mall 获取店铺 Token,再由各平台 *ApiContextFactory 注入开发者凭据,创建对应平台 SDK 上下文。整个链路是:
esync-amazon → GET /remote/mall/.../getAmazonToken → AccountToken → AmazonApiContextFactory → Amazon SP-API Call
OAuth 标准四步流程(各平台通用,实现细节不同):
getAuthUrl()→ 构造平台 OAuth URL(Amazon 按站点路由、Shopee 用 HMAC 签名)- 用户跳转平台授权页同意
- 平台回调返回
code + state(state 存 Redis 5 分钟过期,防 CSRF) - 用 code 换取 token(Amazon 走 LWA、AliExpress 走 Top API、eBay 走 OAuth2)
2.3 平台数据同步(esync-*)
架构设计:一平台一服务
每个平台独立为 esync-{平台} 微服务,独立部署、独立 MongoDB 库、独立限流、独立 Kafka topic:
| 平台 | 服务名 | 模块模式 | 特殊说明 |
|---|---|---|---|
| Amazon | esync-amazon |
3 模块 (client + common + server) | 最复杂:100+ 定时任务、6 线程池、5 种数据源 |
| eBay | esync-ebay |
4 模块 (base + common + service + service-client) | SOAP + REST 双 SDK + Webhook |
| TikTok Shop | esync-tiktokshop |
独立 client + server 仓库 | 支持 FBT 库存 + i18n |
| Temu | esync-temu |
单模块 + 独立 client | Spring Cloud Sleuth 追踪 |
| Wish | esync-wish |
3 模块 (base + core + service) | v1 → v3 双管线并行迁移 |
| Shopify | esync-shopify |
client + server + Go 网关 | codo-shopify-gateway 182 行 Go 反代 |
| ... | esync-{平台} |
三种模块模式可选 | 18+ 平台均按此规范接入 |
数据流(Pull → Process → Push 统一管线):
1. 外部调度 → HTTP REST 端点触发(非 @Scheduled cron)
2. Fetch Task:
├── Redisson 分布式锁(防多实例并发执行)
├── 时间窗口切分(按平台 API 限制拆分小窗口)
├── @Async @Retry 异步拉取 + 自动重试
└── 分页拉取平台数据
3. Converter: 平台模型 → ERP 标准模型
4. MongoDB 持久化 + sended 标记(幂等控制)
5. Kafka 双 topic 推送:
├── 平台专属 topic(履约服务消费)
└── order_center_collect(订单池统一消费)
三、实现细节
3.1 多平台授权核心设计
Redis Token 缓存 + 分布式锁
Shopee 平台是典型示例(ShopeeAuthServiceImpl.java):
// Access Token 缓存: TTL = 14000 秒 (~3.9 小时,略小于 4 小时有效期)
String tokenKey = "shopee:shop:token:" + storeName + ":" + region;
String cachedToken = redisTemplate.opsForValue().get(tokenKey);
if (cachedToken != null) return cachedToken;
// 未命中缓存 → 分布式锁防并发刷新
lockService.lockAndExecute("shopee:token:refresh:" + storeName, () -> {
// 双重检查
cachedToken = redisTemplate.opsForValue().get(tokenKey);
if (cachedToken != null) return cachedToken;
// 调用平台 API 刷新 → 写入 Redis
});
这套设计解决的核心问题:多实例并发刷新导致 Token 失效 — 同一时刻只有一个实例在刷新 Token,其余实例等待后复用。
授权来源枚举扩展
同一平台可存在多套授权来源(AuthDeveloper 枚举):
| 来源 | 说明 | 典型平台 |
|---|---|---|
| ECPP | 早期自有系统 | 全平台 |
| CREEKS | 当前自有系统 | 全平台 |
| CREEKSHUB | 内部数据中台代理 | Amazon |
| CAPTAIN | 船长BI 第三方中转 | Amazon |
| SELLFOX | 赛狐第三方中转 | Amazon |
esync-* 服务根据 auth_developer 字段选择对应的数据拉取链路。
账号/店铺变更事件驱动
账号/店铺状态变更时,通过 Kafka 发送事件通知下游(MallStoreEventProducer):
fba.queue.warehouse.register— FBA 仓库注册事件account.warehouse.register— 账号仓库注册事件
下游库存服务消费后自动创建对应仓库,无需人工配置。
3.2 Amazon Report 封装 — 模板方法 + 策略 + 零配置路由
Amazon 的报告体系是最复杂的对接场景之一:需要"创建报告请求 → 轮询状态 → 下载文件 → 解析 → 持久化"。为了支持几十种不同类型的报告(商品、库存、订单、退货、库龄等),设计了一套高扩展性的封装方案。
MWS 时代:模板方法模式
核心文件:
esync-amazon/.../job/report/mws/handler/ReportHandler.javaesync-amazon/.../handler/BaseReportHandler.javaesync-amazon/.../handler/ReportHandlerFactor.java
// ReportHandler 接口定义契约
public interface ReportHandler {
String getReportType();
void reportSuccess(ReportRequestInfo info, AmazonSeller seller, NationInfo nation);
void reportFail(ReportRequestInfo info, AmazonSeller seller, NationInfo nation);
}
// BaseReportHandler 实现模板方法骨架
public abstract class BaseReportHandler implements ReportHandler {
@Override
public final void reportSuccess(...) {
// 1. 前置校验
boolean isValid = beforeDownloadReport(...);
if (!isValid) return;
// 2. 下载报告
InputStream stream = downloadReport(...);
// 3. 解析内容
List<String> content = parseReport(stream);
// 4. 后置处理(子类实现具体持久化逻辑)
afterDownloadReport(content, ...);
}
// 抽象钩子,子类只需关注这两步
protected abstract boolean beforeDownloadReport(...);
protected abstract void afterDownloadReport(List<String> content, ...);
}
SP API 时代(当前主流):零配置动态路由
核心文件:
esync-amazon/.../job/report/sp/FetchSpReportStatusHighFrequencyJob.javaesync-amazon/.../job/report/sp/service/ISpReportService.java
最大亮点 — "Spring Bean 名称 = 报告类型":
// 实现类直接用 @Service 注解绑定报告类型
@Service("GET_FBA_MYI_UNSUPPRESSED_INVENTORY_DATA")
public class InventorySpReportService implements ISpReportService {
@Override
public void spReportSuccess(...) {
// 1. 流式下载报告(SpApiDownloadHelper,逐行回调,内存恒定)
SpApiDownloadHelper.downloadReport(call, report.getReportDocumentId(), null,
(reportRow) -> parseAndPersistInventoryReport(reportRow));
// 2. 更新报告状态
amazonStoreRepository.updateInventoryReportStatus(...);
}
}
// 轮询任务中动态路由:Bean 名称 = API 返回的报告类型
ISpReportService handler = SpringContextUtils.getBean(report.getReportType());
handler.spReportSuccess(reportStatus, requestReportId, amazonStore, info, call, report, parameter);
这套设计的优势:
- 新增一种报告类型 = 新增一个
@Service("GET_XXX")的类,轮询/工厂逻辑零改动 - 充分利用 Spring 容器特性,省去硬编码的工厂映射
- 报告处理逻辑完全隔离,一个报告类型出问题不影响其他类型
3.3 MWS → SP API 桥接迁移
两套 API 认证方式、数据结构、调用流程完全不同,采用桥接设计:
- MWS 轮询任务 → 走
ReportHandler工厂 - SP 轮询任务 → 走
SpringContextUtils.getBean(reportType)动态路由 - 两套接口并存,各自独立调度,数据落库后走相同的下游消费链路
- 保留 MWS 兼容,确保历史数据不受影响
3.4 Amazon 5 种数据源适配
Amazon 服务支持 5 种数据源,每种有独立的同步链路:
1. SP-API 直连(官方 Selling Partner API)
2. MWS 直连(旧版 Merchant Web Service)
3. Creekshub(内部数据中台代理)
4. SellFox(第三方数据聚合器)
5. Captain(第三方数据聚合器)
采用模板方法模式:CreekshubBaseSyncTask<T> 为抽象基类,各子类实现 doSync() / doQuery()。配合 AuthDeveloper 枚举,系统根据店铺配置的授权来源自动选择对应数据源。
3.5 Amazon 财务事件 — 策略模式处理 13 种事件
财务结算报告采用策略模式分发 13 种事件处理器,每种事件发送到独立 Kafka topic + DLT 兜底:
| 事件处理器 | 业务含义 |
|---|---|
ShipmentEventHandler |
发货 |
RefundEventHandler |
退款 |
AdjustmentEventHandler |
调整 |
ChargebackEventHandler |
拒付 |
DebtRecoveryEventHandler |
债务恢复 |
RetrochargeEventHandler |
追溯收费 |
ServiceFeeEventHandler |
服务费 |
RemovalShipmentEventHandler |
移除发货 |
RemovalShipmentAdjustmentEventHandler |
移除发货调整 |
ProductAdsPaymentEventHandler |
广告费 |
GuaranteeClaimEventHandler |
保障索赔 |
SellerDealPaymentEventHandler |
卖家交易费 |
CouponPaymentEventHandler |
优惠券 |
3.6 HTTP Scheduler 模式(替代 @Scheduled cron)
所有服务的同步任务都暴露为 REST 端点,由外部调度器(如 K8s CronJob、XXL-JOB)调用:
@RestController
@RequestMapping("/remote/sync/order")
public class SyncOrderScheduler {
@GetMapping("/start")
public void startSyncOrders() {
// 触发分布式锁 → 异步执行任务
}
}
优势:支持外部编排、动态调度、运行时开关控制(如 eBay 的 esync-ebay-task-switch 配置可随时关闭/开启任务)。
3.7 时间窗口切分(防 API 超时)
各平台 API 对时间跨度有硬性限制,需切分为小窗口:
| 平台 | 窗口大小 | 原因 |
|---|---|---|
| SHEIN | 48 小时 | 平台硬性限制 |
| TikTok Shop | 10 天 | API 限制 |
| Temu | 按月 | 数据量大 |
| eBay (订单) | 30 分钟 | SOAP API 响应慢 |
| Wish v3 | 1 小时 | 防超时 |
| Amazon | 按报告类型 | SP-API 报告生命周期 |
3.8 五层重试与补偿机制
| 层级 | 机制 | 实现 |
|---|---|---|
| API 调用层 | @Retryable(maxAttempts=3, backoff=@Backoff(delay=2000)) |
Spring Retry |
| 消息发送层 | 查询 sended=false 记录重发 |
MongoDB 游标分页 |
| 数据补偿层 | 独立补偿任务重新扫描最近 N 天数据 | 独立 Compensation Scheduler |
| 手动重试层 | /remote/.../retry HTTP 端点 |
MessageFailController |
| DLT 兜底层 | Kafka Dead Letter Topic | Amazon finance/inventory 等 |
3.9 限流策略
| 服务 | 限流方式 | 详情 |
|---|---|---|
| Amazon (MWS) | Token Bucket 内存限流 | CallThrottling 信号量 + CallCountRecovery 后台线程 |
| Amazon (Captain) | Redis 分布式限流 | RedisCallThrottling 500次/min |
| Amazon (SellFox) | Redisson 原子计数器 | @RateLimit 注解 |
| eBay | Thread.sleep | API 调用间隔 1 秒 |
| Wish v3 | Thread.sleep(2000) | 商品详情请求间隔 |
3.10 各平台特色亮点
| 平台 | 亮点 |
|---|---|
| Amazon | 100+ 定时任务、6 线程池、5 种数据源并行、13 种财务事件策略分发、SyncTimeMonitorTask 每日巡检 + 飞书告警 |
| eBay | SOAP + REST 双 SDK + Webhook 推送管线、JAXB XML 循环引用修复、Python Token 种子脚本 + SMTP 过期告警、运行时开关控制 |
| Wish | v1 → v3 双管线并行迁移(渐进式升级,互不影响)、滑动窗口分页、OAuth2 Token 异常检测自动刷新 |
| TikTok Shop | FBT 库存同步、i18n 国际化消息、独立补偿任务重扫最近 2 天数据 |
| Temu | Spring Cloud Sleuth 分布式追踪、全托管/半托管双模式 SKU 差异化处理、Testcontainers 集成测试 |
| Shopify | 182 行 Go 网关(codo-shopify-gateway)基于 X-Shop header 反代,Caddy + nerdctl 轻量部署 |
四、成果与数据
| 指标 | 数据 |
|---|---|
| 已对接平台数 | 18+(Amazon、eBay、Temu、TikTok Shop、Shopee、Walmart 等) |
| 统一授权中心支持平台 | 15+(含多授权来源:ECPP / Creekshub / SellFox / Captain) |
| 管理商品数据量 | 1 亿+ |
| 订单总数(含平台仓履约) | 3000W+ |
| 需履约订单累计 | 700W+ |
| 日均订单增量(全平台) | 2W+ |
| 日均履约订单 | ~4000 单 |
| esync 子项目数 | 18 个(16 平台对接 + 1 Go 网关 + 1 物流对接) |
| Maven 模块数 | 46 个(client / server / common / base 等) |
| Amazon 定时任务数 | 100+,6 专用线程池 |
| 新报告类型上线时间 | ≤ 1 天(零改动轮询/工厂逻辑) |
| 平台故障隔离 | 任一平台异常不影响其他平台与核心业务 |
| 数据回溯能力 | MongoDB 保留全量原始数据,支持按需重放 |
五、简历提炼版
以下三版可直接用于简历,根据简历空间和面试场景选择:
版本A:精简版(1 行,适合放项目概述)
设计并落地 "一平台一服务" 的多平台接入架构,支撑 Amazon、eBay、Temu、TikTok Shop 、Shopify等 18+ 跨境电商平台稳定对接;配套统一授权中心管理 15+ 平台 OAuth 与 Token 生命周期;原始数据沉淀至 MongoDB,标准化 DTO 经 Kafka 分发至业务侧,管理亿级商品 / 3000W+ 订单。
版本B:完整版(3 段,适合独立模块)
一平台一服务接入架构:设计并落地 18+ 跨境电商平台的独立微服务接入体系(esync-{平台}),每个平台独立部署、独立 MongoDB 库、独立限流。采用 HTTP Scheduler(替代 cron)+ Redisson 分布式锁 + 时间窗口切分 + 五层重试补偿机制,保障数据不丢不漏。原始数据沉淀至 MongoDB 保留平台 schema,标准化 DTO 经 Kafka 双 topic(平台专属 + 订单池)分发,管理亿级商品 / 3000W+ 订单。
统一多平台授权中心:主导设计 creekson-mall 授权微服务,支持 Amazon、eBay、Shopee 等 15+ 平台的 OAuth/签名授权,同一平台可存在多套授权来源(官方 / 中台代理 / 第三方聚合器)。通过 AccountTokenSyncService REST API 为所有数据同步服务提供 Token,结合 Redis 缓存 + 分布式锁防止并发刷新,账号变更自动通过 Kafka 事件驱动下游服务。
Amazon 报告封装亮点:针对 Amazon 复杂的报告体系设计模板方法 + 策略 + "Spring Bean 名称 = 业务标识"的零配置路由,新增报告类型只需新增一个
@Service类,轮询与工厂逻辑零改动、一天内可上线;配合 MWS → SP API 的桥接迁移、高频/低频双轮询与流式下载(逐行回调、内存恒定),保障报告处理的高效性与平滑升级。
版本C:面试口述要点(备忘,不写进简历)
用于面试时展开讲解,记住以下关键词:
- 18+ 平台、18 个子项目、46 个 Maven 模块
- 授权中心:15+ 平台、多授权来源、Redis 缓存 + 分布式锁
- Amazon:100+ 定时任务、5 种数据源、13 种财务事件
- 数据流:HTTP Scheduler → 分布式锁 → 时间窗口 → 拉取 → MongoDB(sended) → Kafka 双 topic
- 重试:Spring Retry @Retryable → MongoDB sended 重发 → 补偿任务 → 手动重试 → DLT 兜底
- 亮点:"Spring Bean 名称 = 业务标识"零配置路由