Alex
Alex
10年跨境老兵(微信:sfgoods),熟悉主流平台(Amazon Ebay 速卖通 Shopee Lazada),欢迎交流~

注册于 1年前

回答
73
文章
5
关注者
2

你图里(领星的吧?)显示的 FBA总库存、可用库存、可售库存,都是通过FBA Inventory API 拿到的。

核心接口只有一个:

GET /fba/inventory/v1/summaries
https://api.sp-api.net/zh/api-308929928
image.png

从这里能直接得到:

totalQuantity → FBA总库存

inStockSupplyQuantity → FBA可用库存(也就是可售库存)

inboundShipmentQuantity → 在途库存

reservedQuantity → 预留库存

第三方平台就是把这些字段整理后展示出来的。

FBA 当前库存报告(GET_FBA_FULFILLMENT_CURRENT_INVENTORY_DATA)
这个报告里也有可售库存(fulfillable_quantity),但它有延迟,不实时。

简单说:商品页面里那个“€1.99 运费”,SP-API 拿不到。
Amazon 没开放这个前台展示的配送费接口。

你唯一能拿到运费的地方,是订单生成之后,通过订单接口查:

  • GET /orders/v0/orders/{orderId}
  • GET /orders/v0/orders/{orderId}/orderItems

在里面能看到:

  • ShippingPrice(买家实际付的运费)
  • ShippingDiscount
  • ShippingTax

也就是:上架时的运费拿不到,只有下单后的运费能查。

或者爬虫

你现在用的 /vendor/directFulfillment/payments/v1/invoices 只是上传发票的接口,本身不提供处理状态。
要查发票有没有通过、有没有被拒,必须用另外一个接口:

查询状态的接口

GET /vendor/directFulfillment/transactions/v1/transactions/{transactionId}

上传发票后,系统会回给你一个 transactionId,用这个去查就行。


状态怎么理解

Amazon 这边对发票目前就两种状态:

状态说明
Processing已接收、正在处理。对发票来说,长期保持 Processing 就表示已经通过了。
Failure处理失败,相当于 Rejected,会给出错误原因。

它不会返回 “Approved” 这种字面状态。


整体上

  1. 上传发票 → 拿到 transactionId
  2. 用 transactionId 调接口:
    GET /vendor/directFulfillment/transactions/v1/transactions/{id}
  3. Processing = 基本通过
  4. Failure = 被拒

你最开始碰到的两个错误:

  • 100632(ERROR):商品不满足《通用商品安全条例》(GPSR),缺合规信息 → 上架会被拦
  • 100528(WARNING):欧盟责任人信息(Responsible Person)没提供,超过 2024-12-13 会被下架

其实就是 Listing 里少了 GPSR 相关的 4 个字段


一、必须补齐的 4 个核心字段(Listing Schema里有,最终以schema为准)

在 SP-API 的 attributes 下,把这些补上即可:

  1. gpsr_manufacturer_reference.gpsr_manufacturer_email_address

    • 制造商邮箱(ASIN 级)
  2. dsa_responsible_party_address

    • 欧盟责任人(Responsible Person)的邮箱或完整地址(SKU 级)
    • 这个字段对应你 100528 报错
  3. gpsr_safety_attestation

    • 是否豁免提供安全文件
    • 大部分商品不是豁免 → 写 false
  4. compliance_media

    • 安全文件、说明书、警告文档等(PDF/图片的直链)
    • 非豁免商品必须至少提供一份

二、可以直接用的 JSON 示例(你只需要替换几项)

如果你用 Listings Items API

{
  "productType": "GENERIC_PRODUCT_TYPE",
  "requirements": "LISTING",
  "attributes": {
    "gpsr_manufacturer_reference": [
      {
        "gpsr_manufacturer_email_address": "manufacturer@example.com",
        "marketplace_id": "A1PA6795UKMFR9"
      }
    ],
    "dsa_responsible_party_address": [
      {
        "value": "responsible.person.eu@example.com",
        "marketplace_id": "A1PA6795UKMFR9"
      }
    ],
    "gpsr_safety_attestation": [
      {
        "value": false,
        "marketplace_id": "A1PA6795UKMFR9"
      }
    ],
    "compliance_media": [
      {
        "content_type": "safety_information",
        "content_language": "de_DE",
        "source_location": "https://your-public-file-url/safety_info.pdf",
        "marketplace_id": "A1PA6795UKMFR9"
      }
    ]
  }
}

你只需要改动这几个点:

  • productType:换成你 SKU 对应的(例如 SHOES、TOYS_AND_GAMES、INK_OR_TONER…)
  • marketplace_id:按你卖的站点替换(DE/FR/IT/ES/PL 等)
  • manufacturer@example.com:真实制造商邮箱
  • responsible.person.eu@example.com:你设定的欧盟责任人邮箱
  • source_location:你自己真正可下载的 PDF 直链
⚠️ 重点:文档链接不能是 Google Drive / Dropbox 的 preview 链接,必须能直接下载,可以和图片的方式差不多。

三、这 4 个字段如何对应你的报错

  • 100632(ERROR):一般是缺

    • manufacturer email
    • safety attestation
    • compliance media
  • 100528(WARNING):就是缺

    • dsa_responsible_party_address

把上面那段 JSON 补齐后,基本可以解决欧洲站的 GPSR 报错,你试试。

目前API里确实没有注意到从AWD调拨到FBA的接口,这个我在帮你开Case了,等待亚马逊回复后我会在这里回复你

问题 1:这个报告会展示哪些 listing/FNSKU?

  • 报告类型是 FBA “Manage Inventory Health Report”(接口 reportType = GET_FBA_INVENTORY_PLANNING_DATA)
  • 报告内容包括库存健康/规划层面的指标:7/30/60/90 天销售、入库状态(working/received/shipped)、预计存储与长期仓储费用、滞销/超量库存、系统建议动作等。
  • 覆盖范围主要是 FBA 要约(不是 MFN),按市场(marketplaceId)生成。
  • 实操理解:报告里的每一行基本对应某市场下一条 FBA 要约(MSKU/FNSKU/ASIN 组合),只要这个要约在亚马逊的“库存健康/规划”体系里有产出指标,就会出现在报告里;纯 MFN或已归档的老要约一般不在该报告里。

问题 2:数据变更有没有规律?逻辑大概怎样?

  • 官方并没明确说明报告是“实时”或“每日整点刷新”,所以你观察到“上午有、晚上消失、第二天又回来”的情况是可能的。
  • 指标来源于多个子模块(销售窗口、入库状态、费用估算、超龄/超量等),这些模块可能异步重算、先后完成,从而导致中间时段行或字段暂时缺失。
  • 市场维度影响较大:一些用户反馈,如果同时请求多个 marketplaceId,可能只返回其中一个市场的数据;因此建议按单一市场拉取并比对。
  • 本报告不同于“实时库存”报告——你若想确认“此 FNSKU 现在是否还在库”,应当交叉查询实时库存报告;该规划报告里的“缺行”并不必然意味着库存为零。
这份报告是“周期性汇总 + 异步重算”,报告的行集(哪些 FNSKU)会随着要约状态(在售/抑制/归档)、市场维度、以及内部重算完成状况而波动;不要将它当做“当前库存存在性”的权威来源。

问题 3:报告的建议使用方式

原则:把它当“运营/规划层”的快照,用于判断健康状况,而非当作底账。

  1. 固定时间点拉取,做好日常快照
    每日固定在某个时刻(如每日 08:05)请求并入库,避免因为当天不同时间点数据波动造成误判。
  2. 与实时库存/入库报告交叉验证

    • 使用实时库存报告验证该 FNSKU 是否在库/数量近实时。
    • 将该规划报告中的销售窗口、费用预估、超龄/超量指标,作为“优先级或动作建议”的输入。
    • 如果规划报告提示滞销风险、仓储费上涨、超量,就可以触发价格调整、广告集中、移除或补货策略。
  3. 按市场分别生成与比对
    建议每个 marketplace 单独请求并落库,避免多市场合并导致的数据行缺失或覆盖问题。
  4. 做好“缺行容错”和“延迟回填”机制
    如果某条 FNSKU 在报告中一度缺失,且实时库存显示仍在库/在售,可将该条数据从昨天继承到今天,并标记“待重算”。次日若恢复,则覆盖更新。这样既不会误判,也能保证运营报表稳定。
  5. 结合费用周期做运营动作
    因为报告中含预计存储费/长期仓储费等指标,可以结合库龄、销售窗口,将“超龄/超量”与“次月仓储费暴涨风险”关联,用于驱动调价、促销、移除或补货等运营动作。

对你所观察现象的解释

你看到的情形(T-1 天有 → T+0 8:00 有 → T+0 20:00 无 → T+1 又有):

  • 很可能是报告在当天内部重算过程中,某个模块(比如入库状态、销售窗口、费用预估)尚未完全就绪,导致该条 FNSKU 暂被过滤或延迟更新。
  • 若实时库存报告仍显示该 FNSKU 在库/在售,则可判断为“规划报告暂时缺失”而非真正下架或销毁。
  • 建议你不要将“晚上缺失”视为“库存问题”或“列表消失”,而是视为 “报告侧数据刷新延迟”,按照上述方法做好容错即可。

并非所有字段都在前端展示,也并非所有属性都是必填的。 要按照json schema语法来解析

部分字段是联动的

建议做刊登可以参考赛狐的刊登界面来设计

接口查到发票状态是 PROCESSING,但 VC 里显示 Non-submitted,大概率是发票还没真正进入 AP 系统。

简单说下关键点:

  1. 跟 AP 团队的“连接”
    不需要额外去打通接口。只要账号是 Direct Fulfillment Vendor,并且 SP-API 应用授权了 Direct to Consumer Shipping (Restricted) 权限,就算接通了。
    真要跟 AP 沟通问题,走 Vendor Central → Support → Payments/Invoices 提交工单就行。
  2. PROCESSING 卡住的常见原因

    • 对应订单还没确认发货(必须“已发货”才能开发票)。
    • 发票里的 Bill-to 信息(partyId、公司名、税号、地址)跟亚马逊系统不一致。
    • 发票字段错误,比如 PO 号、金额、币种、付款条款有问题。
    • 调错区域接口或应用权限不对。
  3. 建议的排查顺序

    • GET /vendor/directFulfillment/transactions/.../{transactionId} 查每笔详细状态。
    • 确认订单都已发货。
    • 对照 Bill-to 信息和发票关键字段。
    • 重新提交一张最标准的发票测试。
    • 仍卡住就带上 transactionId 和截图,在 VC 开工单给 AP 团队处理。

json schema里找的
具体,通过getDefinitionsProductType获取schema,然后找到里面的varint_theme(这里拼写可能错误,你搜theme) 就能看到枚举
https://api.sp-api.net/zh/api-308929921
image.png

官方 SDK 并不强制你用 refresh_token 去换 token——如果你手里已经有一个仍然有效的 LWA access_token,只要把它放进请求头 x-amz-access-token 即可;这是官方文档现在推荐的做法(最近文档里甚至给了“不带签名、只带 header”的示例)

下面给你两条常见路径,按需选:

方案 A:直接用 HTTP(最省事)

curl "https://sellingpartnerapi-na.amazon.com/sellers/v1/marketplaceParticipations" \
  -H "x-amz-access-token: Atza|<你的token>" \
  -H "user-agent: MyApp/1.0 (Language=CLI)" \
  -H "x-amz-date: 20250101T120000Z"
官方“Connect to the SP-API”页面明确列出要加的头,示例也展示了不带签名、只带 x-amz-access-token 的请求。注意 token 有效期约 1 小时。

方案 B:仍然用官方 SDK,但给底层 HTTP 客户端统一加默认头

不同语言的官方 SDK 都是基于 OpenAPI 生成的客户端,底层一般都有“默认请求头/拦截器”的注入点。思路是:x-amz-access-token 当成普通自定义头塞进去即可。

Java(OkHttp 拦截器)

import okhttp3.*;
import com.amazon.spapi.client.*;   // 你的生成包名可能不同
import com.amazon.spapi.api.SellersApi;

String accessToken = "Atza|...";
ApiClient client = new ApiClient();
OkHttpClient http = client.getHttpClient().newBuilder()
  .addInterceptor(chain -> {
    Request req = chain.request().newBuilder()
      .header("x-amz-access-token", accessToken)
      .header("user-agent", "MyApp/1.0 (Language=Java)")
      .build();
    return chain.proceed(req);
  }).build();
client.setHttpClient(http);
client.setBasePath("https://sellingpartnerapi-na.amazon.com");

SellersApi api = new SellersApi(client);
var res = api.getMarketplaceParticipations();
官方 Java 教程默认演示用 refresh_token 让 SDK 自己换 token;但如果你已持有 access_token,也可以像上面这样直接注入 header 使用。(developer-docs.amazon.com)

C#(RestSharp/Configuration 默认头)

using Amazon.SellingPartnerAPIAA.Client; // 你的命名空间可能不同
using Amazon.SellingPartnerAPIAA.Api;

var cfg = new Configuration { BasePath = "https://sellingpartnerapi-na.amazon.com" };
cfg.AddDefaultHeader("x-amz-access-token", "Atza|...");
cfg.UserAgent = "MyApp/1.0 (Language=C#)";

var api = new SellersApi(cfg);
var res = api.GetMarketplaceParticipations();
C# 的生成客户端通常支持在 Configuration/RestClient 上添加默认头;把 token 放进 x-amz-access-token 即可。官方“生产调用”页面也列出必需的几个头部。

Python(ApiClient 默认头)

from spapi_client import Configuration, ApiClient, SellersApi  # 你的包名/类名可能不同

cfg = Configuration()
cfg.host = "https://sellingpartnerapi-na.amazon.com"
api_client = ApiClient(cfg)
api_client.set_default_header("x-amz-access-token", "Atza|...")
api_client.set_default_header("user-agent", "MyApp/1.0 (Language=Python)")

api = SellersApi(api_client)
res = api.get_marketplace_participations()
Python 的生成客户端一般提供 set_default_header 或可直接修改 default_headers 添加自定义头。

Node/JS(直接 fetch;或在 SDK 的请求钩子里加头)

const r = await fetch(
  "https://sellingpartnerapi-na.amazon.com/sellers/v1/marketplaceParticipations",
  {
    headers: {
      "x-amz-access-token": "Atza|...",
      "user-agent": "MyApp/1.0 (Language=Node)",
      "x-amz-date": "20250101T120000Z",
    },
  }
);
const data = await r.json();
官方文档与 Postman 教程都明确需要把 access_tokenx-amz-access-token 传入(有时文档里也能看到旧写法 x-amzn-access-token,本质一致)。

重要注意

  • RDT 场景:访问带 PII 的“受限接口”时,不用 LWA access_token,而是先用 Tokens API 换 RDT,然后仍然把 RDT 放在 x-amz-access-token 头里。
  • 有效期:LWA access_token 通常有效 1 小时,过期会 401;如果你有 refresh_token,让 SDK 代换会更省心。

使用SP-API刊登的,主要关注商品前台链接是否正常。以及 issue里是否有错误即可

如果前台链接可以购买,可以搜索,拿这些就可以忽略

使用getListingItem接口看看
https://api.sp-api.net/zh/api-308930030
image.png

技术可以实现的,大概涉及到下面的相关接口
Amazon Shipping API v2
Fulfillment Outbound API v2020-07-01
Orders API v0
Notifications API

发布
问题

公众
平台

最新资讯发布