Wayfair API Documentation 说明文档
欢迎使用我们的 API 说明文档。利用 Wayfair API 中提供的一系列操作,供应商、货运伙伴以及诸多其他用户和应用程序均能与 Wayfair 无缝对接。我们希望通过此说明文档帮助您实现与 Wayfair 系统的对接。
如果您有兴趣通过 API 连接 Wayfair 系统,请联系 Wayfair 负责 API 对接的同事。如果您的帐户目前没有指定的负责 API 对接的同事,请填写此表格,以便加入到我们的等待名单。由于资源有限且需求量大,我们目前无法满足所有的 API 对接请求,敬请谅解。一旦有可用资源,我们的团队成员就会与您联系。
潜在的技术合作伙伴可以访问 Wayfair 开发者网络,了解与 Wayfair 系统对接的优势、获取开发 Wayfair 系统对接所需的信息,并启动用户入驻流程。
Wayfair API 利用 OAuth 客户端凭证,通过非用户界面交互的方式进行身份验证和授权。大多数 API 功能都是通过 GraphQL query 和 mutation 实现的。
Tooling 工具
目前,我们的所有工具都位于 Wayfair Partner Home 上。如果您无法访问 Partner Home,但又想通过 API 与 Wayfair 系统对接,请联系您的 API 联系人。
应用程序管理
在此页面上,您可以设置和编辑 Wayfair 客户端应用程序。如果您想获得新的 Client ID 或想要更换密匙,也可以在这里进行。GraphiQL
这是用于与 GraphQL 端点进行交互的浏览器内置 IDE。GraphiQL 页面提供完整的 GraphQL schema(结构)文档,并对每种您可以进行的操作都提供了 query 和 mutation 样本的自动生成、语法标注,和自动补全功能。Sandbox测试
Sandbox(沙盒)测试环境是正式环境的副本,其中包含正式环境数据库内容的子集。用户能够在 Sandbox 测试环境中更改数据、评估结果和进行任何必要操作,而且不存在影响正式环境的数据的风险。Sandbox 测试环境目前可用于库存、订单管理和发货 API。
Authentication 身份验证
使用以下代码获取 token (JWT):
using Newtonsoft.Json;
using RestSharp;
var authClient = new RestClient("https://sso.auth.wayfair.com/oauth/token");
var requestBody = new {
grant_type = "client_credentials",
client_id = clientId,
client_secret = clientSecret,
audience = "https://sandbox.api.wayfair.com/"
};
var response = authClient.Execute(
new RestRequest(Method.POST)
.AddHeader("content-type", "application/json")
.AddParameter("application/json", JsonConvert.SerializeObject(requestBody), ParameterType.RequestBody)
);
import java.io.IOException;
import javax.json.*;
import org.apache.http.HttpClient;
import org.apache.http.HttpPost;
import org.apache.http.HttpResponse;
public class Wayfair_Auth_Client {
public static void main(String[] args) throws IOException {
HttpClient client = HttpClient.creadeDefault();
HttpPost authRequest = new HttpPost("https://sso.auth.wayfair.com/oauth/token");
authRequest.setHeader("Content-Type", "application/json");
JsonObject authRequestBody = Json.createObjectBuilder()
.add("client_id", InventoryMutator.clientId)
.add("client_secret", InventoryMutator.clientSecret)
.add("audience", "https://sandbox.api.wayfair.com/")
.add("grant_type", "client_credentials")
.build();
authRequest.setEntity(new StringEntity(authRequestBody.toString()));
HttpResponse response = client.execute(authRequest);
}
}
var settings = {
'async': true,
'crossDomain': true,
'url': 'https://sso.auth.wayfair.com/oauth/token',
'method': 'POST',
'headers': {
'content-type': 'application/json',
'cache-control': 'no-cache',
},
'data': {
'grant_type':'client_credentials',
'client_id': client_id,
'client_secret': client_secret,
'audience': 'https://sandbox.api.wayfair.com/'
}
}
$.ajax(settings).done(function (response) {
console.log(response);
});
$client = new \GuzzleHttp\Client();
$response = $client->post(
'https://sso.auth.wayfair.com/oauth/token',
[
'headers' => ['Content-Type' => 'application/json'],
'body' => json_encode([
'client_id' => $clientId,
'client_secret' => $clientSecret,
'audience' => 'https://sandbox.api.wayfair.com/',
'grant_type' => 'client_credentials'
])
]
);
#! /bin/python
import json
import requests
url = "https://sso.auth.wayfair.com/oauth/token"
payload = '''
{
"grant_type":"client_credentials",
"client_id": client_id,
"client_secret": client_secret,
"audience": "https://sandbox.api.wayfair.com/"
}
'''
headers = {
'content-type': "application/json",
'cache-control': "no-cache",
}
response = requests.request("POST", url, data=payload, headers=headers)
require "http"
require "json"
response = HTTP.headers({
"Content-Type" => "application/json",
}).post(
"https://sso.auth.wayfair.com/oauth/token",
:json => {
"client_id" => client_id,
"client_secret" => client_secret,
"audience" => "https://sandbox.api.wayfair.com/",
"grant_type" => "client_credentials"
}
)
curl -X POST https://sso.auth.wayfair.com/oauth/token \
-H 'content-type: application/json' \
-d '
{
"grant_type":"client_credentials",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"audience": "https://sandbox.api.wayfair.com/"
}
'
响应示例:
{
"access_token":"eyJ0eXAiOiJKV1Qi...X1rNJFNVGBwmFQ5tepKwno7DEIjDg",
"expires_in":43200,
"scope":"read:inventory write:inventory",
"token_type":"Bearer"
}
身份验证环节遵循的是 OAuth 的客户端凭证流程。您通过 POST 操作将 Client ID 和密钥发送到 Token 检索端,以获得新的访问 Token。该经过身份验证的访问 Token 必须包含在未来所有的 API 调用中。
Token 的有效期为 12 小时,因此请检查 Token 内 exp
字段中的有效日期/时间(以秒为单位),以了解何时需要重新进行身份验证并获取新的访问 Token。我们建议您在当前时间和 Token 的到期时间之间留有缓冲的余地。例如,假设每 6 小时获取一次访问 Token,那么在身份验证服务意外下线时,您现有的访问 Token 仍将有一定的可用余时。
要想使用 Wayfair API,您需要注册一个应用程序,以此获取 Client ID 和密钥。在获取访问 Token 时,您需要将此 Client ID 和密钥传递给身份验证端点。
身份验证端点响应将包括您的访问 Token (access_token
)、以秒为单位的 Token 有效期限 (expires_in
)、当前分配给 Token 的权限 (scope
) 和 Token 的类型 (token_type
)。发出 API 请求时,您需要利用身份认证端点的响应内容,将 HTTP 请求的 Authorization
标头设置为 {token_type} {access_token}
,类似于 Authorization: Bearer eyJ0eXAiOiJKV1Qi...X1rNJFNVGBwmFQ5tepKwno7DEIjDg
。
请注意,测试用 Sandbox 应用程序和正式的应用程序有着不同的目标 URL。Sandbox 程序需使用 https://sandbox.api.wayfair.com/,而正式应用程序应使用 https://api.wayfair.com/。
Test Endpoint 测试端点
发送请求到测试端点:
using Newtonsoft.Json;
using RestSharp;
using System;
using System.IO;
using System.Linq;
using System.Net;
var client = new RestClient("https://sandbox.api.wayfair.com/v1/demo/clock");
var response = client.Get(
new RestRequest(Method.GET)
.AddHeader("accept", "application/json")
.AddHeader("content-type", "application/json")
.AddHeader("authorization", string.Format("Bearer {0}", token))
);
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import java.io.IOException;
public class ApiClient {
public static void main(String[] args) throws IOException {
HttpGet request = new HttpGet("https://sandbox.api.wayfair.com/v1/demo/clock");
clockRequest.setHeader("Accept", "application/json");
clockRequest.setHeader("Authorization", "Bearer " + token);
clockRequest.setHeader("Content-Type", "application/json");
HttpClient client = HttpClients.createDefault();
HttpResponse response = client.execute(request);
}
}
var clockRequestSettings = {
'async': true,
'crossDomain': true,
'url': 'https://sandbox.api.wayfair.com/v1/demo/clock',
'method': 'GET',
'headers': {
'authorization': 'Bearer ' + token,
'cache-control': 'no-cache',
'content-type': 'application/json'
}
};
$.ajax(clockRequestSettings).done(function (response) {
console.log(response);
});
$client = new \GuzzleHttp\Client();
$response = $client->get(
'https://sandbox.api.wayfair.com/v1/demo/clock',
[
'headers' => [
'Authorization' => 'Bearer ' + token,
'Content-Type' => 'application/json',
]
]
);
#! /bin/python
import json
import requests
url = "https://sandbox.api.wayfair.com/v1/demo/clock"
headers = {
'Authorization': 'Bearer ' + token
'Content-Type': 'application/json',
}
response = requests.request('GET', url, headers=headers)
require "http"
require "json"
response = HTTP.headers({
"Authorization" => "Bearer " + token
"Content-Type" => "application/json",
}).get("https://sandbox.api.wayfair.com/v1/demo/clock")
curl -X GET https://sandbox.api.wayfair.com/v1/demo/clock \
-H 'Authorization: Bearer ${token}' \
-H 'Content-Type: application/json'
响应示例:
{
"errors": [],
"data": {
"datetime": "2018-10-17T15:53:08-04:00",
"username": "1aphQ6YCp7MXrQDiy4ftv2lU5FQriktUw"
}
}
为了帮助您顺利开展测试,我们开放了一个测试端点,您可以用它来测试自己的凭证是否有效,并且是否能顺利地向 API 发出请求。我们的测试端点位于 https://sandbox.api.wayfair.com/v1/demo/clock ,向它发送请求便能收到当前时间!
请注意,调用此端点需要进行身份验证,请将此处的代码示例与身份验证示例结合起来使用。
GraphQL
Query 示例
query {
identity {
username,
email,
applications {
name
}
}
}
响应示例
{
"identity": {
"username": "john.doe",
"email": "john.doe@gmail.com",
"applications": [
{
"name": "John's First WayPI client"
},
{
"name": "John's inventory client"
}
]
}
}
GraphQL 是一种 API 查询语言,它让客户端能够向服务器请求 仅其所需 的数据。您可以在 graphql.org 上找到 GraphQL 的入门手册。GraphQL 请求仍然通过 HTTP POST 进行,query
字段必须是 POST 主体的一部分,variables
字段也可以是 POST 主体的一部分。如果您指向的是GraphQL端点, 则需要将v1/graphql/添加到用于连接到Wayfair的URL
请注意,由于 GraphQL 类型系统的递归特性,并非所有类型都将包含在此份文档中。您应该访问 GraphiQL,进行进一步的 GraphQL 结构探索。
Why GraphQL 为何使用 GraphQL
我们之所以使用 GraphQL,是因为它让您可以自行决定用 API 获得哪些信息。GraphQL 巧妙地解决了获取信息过多和过少的问题。您告诉服务器自己需要哪些数据,便能仅收到这些数据。
Retrieving Data 检索数据
Query #1:
{
identity {
username
email
applications {
clientId
name
}
}
}
Query #2: 简化版
{
identity {
username
email
}
}
Query #3: 复杂版
{
identity {
username
email
applications {
clientId
name
description
permissions {
scope {
name
description
}
}
}
}
}
Query 是读取信息的请求。您可以将它视为正常的 REST GET 请求。如右侧示例中所展示的,Query 描述了您想要获得的数据的形状。
根据您的需要,您可以进一步细化 Query。例如,如果您对应用程序信息不感兴趣,便可以将 applications
字段从 Query 中删除。右侧的 Query #2 凸显了这一点:由于我们不再需要从响应中获取应用程序信息,我们从 Query 中删除了 applications
字段。至此,Query 只包含我们真正需要的信息,而服务器返回的响应也将与之匹配。
您也可以反过来,例如,如果您需要更多的应用程序信息,则可以在 Query 中添加所需的字段。例如,让我们来检索应用程序的权限。在 Query #3 中,我们扩展了 Query 的 applications
字段以加载一些之前没有的信息。不同的客户端需要不同的数据,GraphQL 的灵活性使您的客户端能够仅检索所需的数据,而无需更改端点或执行其他类型的请求。
Updating Data 更新数据
Mutation 示例
mutation {
applications {
update(
application: {
clientId: "my client id",
name: "A better name than before",
description: "An even better description!"
}
) {
clientId
name
description
}
}
}
Mutation 是您在 GraphQL 中更新数据的方式。Mutation 看起来和 Query 非常相似,但需要稍微多一点信息。Mutation 在开头总会有 mutation
的标记,并且通常有一个名称。请参考右侧的示例,该 Mutation 示例更新了应用程序的 name
和 description
字段。
该示例 Mutation 会更新并返回一个 application
对象。如果您不需要 Mutation 返回某些字段,则可以像用 Query 一样将它们移除。
Variables 变量
GraphQL 请求的完整负载示例
{
"query":"
mutation updateApplication($myApplication: ApplicationInput!) {
applications {
update(
application: $myApplication
) {
clientId
name
description
}
}
}
",
"variables": {
"myApplication": {
"clientId": "my client id",
"name": "My variable application",
"description": "A variable description!"
}
}
}
上述示例展示了如何通过 “将变量值直接插入请求主体 query
字段中” 的方式来向服务器发送编辑好的 Mutation。虽然这在技术上没有问题,但更好的方法是使用请求主体的 variables
字段来发送您的变量值。在这种方式下,请求主体看起来会有些不同,负载将与右侧示例相似。
这种请求方式有助于重复利用 query
字段的文本,而服务器将能使用请求主体 variables
字段中的变量值来运行 Mutation。
Inventory 库存
库存 API 用于向我们更新您的库存。
Save Inventory Mutation 保存库存
{
"query": "
mutation inventory($inventory: [inventoryInput]!) {
inventory {
save(
inventory: $inventory,
feed_kind: DIFFERENTIAL
) {
handle,
submittedAt,
errors {
key,
message
}
}
}
}
",
"variables": {
"inventory": [
{
"supplierId": 5000,
"supplierPartNumber": "XXXXXXXX",
"quantityOnHand": 5,
"quantityBackordered": 10,
"quantityOnOrder": 2,
"itemNextAvailabilityDate": "05-31-2021 00:00:00",
"discontinued": false,
"productNameAndOptions": "My Awesome Product"
},
{
"supplierId": 5000,
"supplierPartNumber": "YYYYYYYY",
"quantityOnHand": 5,
"quantityBackordered": 10,
"quantityOnOrder": 2,
"itemNextAvailabilityDate": "05-31-2021 00:00:00",
"discontinued": false,
"productNameAndOptions": "My Awesome Product"
}
]
}
}
您能够利用 保存库存 Mutation 更新库存。Mutation 需要一列 InventoryInput
类型的输入参数,该参数列表长度可随意设置(但如果太长的话,服务器会报错)。出于带宽的考虑,我们建议您将库存更新排入发送队列中,并以每分钟不超过一次的频率发送。
Input 输入
名称 | 类型 | 描述 |
---|---|---|
inventory | [InventoryInput]! | 库存数据列表, 每行一个部件 |
feed_kind | inventoryFeedKind = DIFFERENTIAL | 如果上传列表只包含供应商部分库存则用DIFFERENTIAL ,否则用TRUE_UP |
Output 输出
类型 | 描述 |
---|---|
TransactionStatus! | 库存更新是一项异步操作, 最多需要15分钟才能完成。客户端可用上传后返回的交互数据跟踪更新的进度。 |
InventoryInput Type
名称 | 类型 | 描述 |
---|---|---|
supplierId | Int! | 包含此产品的供应商/仓库的识别号 |
supplierPartNumber | String! | 产品部件号 |
quantityOnHand | Int! | 商品的可售库存 |
quantityBackorder | Int | 缺货商品的数量 |
quantityOnOrder | Int | 分配给未结订单的商品数量 |
itemNextAvailabilityDate | String | 产品未来可供应的时间点 |
discontinued | Boolean = false | 产品是否已停产 |
productNameAndOptions | String | 产品名称以及要为其提交的其他信息 |
Orders 订单
订单管理 API 允许供应商从 Wayfair 检索 DropShip(直接发货)和 CastleGate 的采购订单,并发送订单履行过程中标志性事件的更新。您可以根据日期或是否已被接受等筛选条件来检索订单。
DropShip Order Query 直接发货订单查询
query getDropshipPurchaseOrders {
getDropshipPurchaseOrders(
limit: 10,
hasResponse: false,
sortOrder: DESC
) {
poNumber,
poDate,
estimatedShipDate,
customerName,
customerAddress1,
customerAddress2,
customerCity,
customerState,
customerPostalCode,
orderType,
shippingInfo {
shipSpeed,
carrierCode
},
packingSlipUrl,
warehouse {
id,
name
},
products {
partNumber,
quantity,
price,
event {
startDate,
endDate
}
},
}
}
直接发货订单查询 Query 用于拉取 DropShip(直接发货)采购订单。您可以根据需要定义 Query 的筛选参数。例如,示例部分中的 Query 由于定义了 hasResponse: false
参数,因此将仅加载未结订单(即没有回复的订单),但您也可以使用 hasResponse
筛选参数来仅拉取已结订单,或者不做任何筛选以拉取所有订单。
注意:默认情况下,我们希望供应商使用 getDropshipPurchaseOrders Query 来查看他们的采购订单。如果您使用的是早期开发的 purchaseOrders Query,请就任何疑问联系您的 Wayfair 系统对接代表。
Input 输入
名称 | 类型 | 描述 |
---|---|---|
limit | Int = 10 | 要返回的最大结果数。如果未设置限制,则默认为10 |
hasResponse | Boolean | 订单是否收到回复(通常是对订单的接受)。如果采购订单没有响应(hasResponse = false), 则对应于 OPEN 状态 |
fromDate | IsoDateTime | 订单开始日期时间。指定获取采购订单的起始日期 |
poNumbers | [String] = [] | 要过滤(包含在结果中的)的订单编号列表 |
sortOrder | SortOrder = ASC | 按订单日期升序或降序对结果进行排序 |
Output 输出
类型 | 描述 |
---|---|
[PurchaseOrder] | 订单列表。结果将遵守输入参数 |
以下的 接受订单 Mutation 与 发货通知 Mutation 允许您接受直接发货订单,并在发货后通知 Wayfair(直接发货订单的“补货”或“拒绝”回复仍需通过 Partner Home 页面进行操作)。
Accept Order Mutation 接受订单
{
"query": "
mutation acceptOrder($poNumber: String!, $shipSpeed: ShipSpeed!, $lineItems: [AcceptedLineItemInput!]!) {
purchaseOrders {
accept(
poNumber: $poNumber,
shipSpeed: $shipSpeed,
lineItems: $lineItems
) {
handle,
submittedAt,
errors {
key,
message
}
}
}
}
",
"variables": {
"poNumber": "CS12345678",
"shipSpeed": "GROUND",
"lineItems": [
{
"partNumber": "ABC123456",
"quantity": 1,
"unitPrice": 17.07,
"estimatedShipDate": "2020-04-27 10:16:44.000000 -04:00"
},
{
"partNumber": "CBA654321",
"quantity": 1,
"unitPrice": 15.05,
"estimatedShipDate": "2020-04-27 10:16:44.000000 -04:00"
}
]
}
}
接受订单 Mutation 让 Wayfair 知道您已经接受了一组订单商品。我们希望您将把此订单商品添加到需要从仓库提货和发货的商品列表中,也希望您在短时间内使用库存 API 中的 保存库存 Mutation(或其他方法)更新您的库存,以便让我们知道您还有多少产品库存。
Input 输入
名称 | 类型 | 描述 |
---|---|---|
poNumber | String! | 您从 Wayfair 收到的订单编号 |
shipSpeed | ShipSpeed! | 订单的配送方式 |
lineItems | [AcceptedLineItemInput!] | 订单上需要被接受的产品清单 |
Output 输出
类型 | 描述 |
---|---|
TransactionStatus! | 接受订单是一个异步操作。返回给您的交易数据可用于追踪您的变动 |
AcceptedLineItemInput Type
名称 | 类型 | 描述 |
---|---|---|
partNumber | String! | 订单中被接受的产品部件号 |
quantity | Int! | 被接受的产品数量 |
unitPrice | Float! | 产品的单价 |
estimatedShipDate | IsoDateTime! | 产品的预计发货日期 |
Ship Notification Mutation 发货通知
{
"query": "
mutation shipment($notice: ShipNoticeInput!) {
purchaseOrders {
shipment(notice: $notice) {
handle,
submittedAt,
errors {
key,
message
}
}
}
}
",
"variables": {
"notice": {
"poNumber": "AB123456789",
"supplierId": 5000,
"packageCount": 2,
"weight": 184,
"volume": 22986.958176,
"carrierCode": "FDEG",
"shipSpeed": "SECOND_DAY_AIR",
"trackingNumber": "210123456789",
"shipDate": "2020-04-10 12:16:19.000000 -06:00",
"sourceAddress": {
"name": "Wayfair",
"streetAddress1": "4 Copley Place",
"city": "Boston",
"state": "MA",
"postalCode": "02120",
"country": "USA"
},
"destinationAddress": {
"name": "Jane Doe",
"streetAddress1": "123 Main St.",
"city": "Boston",
"state": "MA",
"postalCode": "02122",
"country": "USA"
},
"largeParcelShipments": [
{
"partNumber":"ABA1012GAB",
"packages":[
{
"code":{
"type":"TRACKING_NUMBER",
"value":"210123456781"
},
"weight": 150
}
]
},
{
"partNumber":"ABA1012GAC",
"packages":[
{
"code":{
"type":"TRACKING_NUMBER",
"value":"210123456782"
},
"weight": 150
}
]
}
],
"smallParcelShipments": [
{
"package": {
"code": {
"type": "TRACKING_NUMBER",
"value": "210123456783"
},
"weight": 92
},
"items": [
{
"partNumber": "ABA1012GAD",
"quantity": 1
}
]
},
{
"package": {
"code": {
"type": "TRACKING_NUMBER",
"value": "210123456784"
},
"weight": 92
},
"items": [
{
"partNumber": "ABA1012GAB",
"quantity": 1
}
]
}
]
}
}
}
发货通知 Mutation 用于在您发货时告知 Wayfair。
Input 输入
名称 | 类型 | 描述 |
---|---|---|
notice | ShipNoticeInput! | 此输入类型包含 Wayfair 所需关于货件的所有信息,如包裹追踪号,以及需要传递给客户的信息 |
Output 输出
类型 | 描述 |
---|---|
TransactionStatus | 发货通知是一个异步操作,返回给您的交互数据可用于追踪您的变更记录 |
ShipNoticeInput Type
名称 | 类型 | 描述 |
---|---|---|
poNumber | String! | 通知已发货的订单号 |
supplierId | ID! | 发送此订单的供应商/仓库标识符 |
packageCount | Int! | 订单需要发货的总包裹数 |
weight | Float | 订单中所有包裹的总重,以磅为单位 |
volume | Float | 订单中所有包裹的总体积,以立方英尺为单位 |
carrierCode | String! | 承运商标准码(SCAC) |
shipSpeed | ShipSpeed! | 订单的发货速度 |
trackingNumber | String! | 订单包裹追踪码 |
shipDate | IsoDateTime! | 订单发货日期。该日期必须在过去十天之内,及未来一天之内 |
sourceAddress | AddressInput! | 订单发货地址 |
destinationAddress | AddressInput! | 订单送货目的地地址 |
smallParcelShipments | [SmallParcelShipmentInput!] | 已发货的小包裹清单 |
largeParcelShipments | [LargeParcelShipmentInput!] | 已发货的大包裹清单 |
ShipSpeed Type
名称 | 描述 |
---|---|
SECOND_DAY_AIR | 次日空运运达 |
SECOND_DAY_AIR_FREE | 次日免费空运 |
FIVE_DAY_DIRECT | 全球5天直达 |
THREE_DAY | 3天运达 |
CONTAINER | 集装箱 |
运达邮件通知 | |
FEDEX_HOME | 联邦快递送货上门 |
GROUND | 小包裹快递 |
PAKETVERSAND | 小包裹快递 |
IMPERIAL_POOL_FREIGHT | Imperial Pool Freight |
NEXT_DAY | 次日空运 |
NEXT_DAY_OVERSEAS | 次日空运(阿拉斯加,夏威夷,波多黎各) |
NEXT_MORNING | 英国次日上午午前送达 |
NEXT_DAY_BEFORE_NINE | 英国次日上午9点前送达 |
WILL_CALL | 电话通知 |
SATURDAY_DELIVERY | 英国周六送达 |
TRUCK_FREIGHT_CASKETS_ONE_DAY | 棺椁运送 - 1天 |
TRUCK_FREIGHT_CASKETS_TWO_DAY | 棺椁运送 - 2天 |
CURBSIDE_WITH_UNLOAD | 路边取货,包含卸货服务 |
TRUCK_LOAD | 卡车装载 |
CURBSIDE | 路边取货,不包含卸货服务 |
WHITE_GLOVE_BRONZE | 路边卸货 |
WHITE_GLOVE_GOLD | 送至房间和拆除包装 |
WHITE_GLOVE_TWO_MAN | 优选两人递送 |
WHITE_GLOVE_PLATINUM | 送至房间及安装 |
WHITE_GLOVE_SILVER | 房间选择 |
TRUCK_FREIGHT_THRESHOLD | 卡车运货-阈值 |
STANDARD_VERSAND_SPERRGUT | 大件货物标准运输 |
ALMO | ALMO - 送至房间和旧物拆除 |
LARGE_PARCEL_COURIER | 大包裹快递 |
EUROPEAN_LINE_HAUL | 欧洲航线运输 |
ECONOMY | 经济舱 |
WHITE_GLOVE_ROOM_OF_CHOICE | 搬送至指定房间 |
TINY_PARCEL | 小包裹 |
GROUND_OVERSEA | 海外包裹陆地运输(阿拉斯加,夏威夷,波多黎哥) |
LOW_COST_CARRIER | 低成本承运商 |
AddressInput Type
名称 | 类型 | 描述 |
---|---|---|
name | String! | 住所名称 |
streetAddress1 | String! | 主要街道地址信息 |
streetAddress2 | String! | 次要地址信息 |
city | String! | 城市 |
state | String! | 州或省 |
postalCode | String! | 邮编 |
country | String! | 国家代码 |
SmallParcelShipmentInput Type
名称 | 类型 | 描述 |
---|---|---|
package | PurchaseOrderPackageInput! | 小件商品包裹 |
items | [SmallParcelItemInput!] | 小件商品包裹中包含物品清单 |
LargeParcelShipmentInput Type
名称 | 类型 | 描述 |
---|---|---|
partNumber | String! | 大件商品包裹中的部件号 |
packages | [PurchaseOrderPackageInput!] | 大件商品被分装成的多个包裹 |
PurchaseOrderPackageInput Type
名称 | 类型 | 描述 |
---|---|---|
code | PackageTrackingCode! | 包裹追踪码 |
weight | Float | 包裹总重 |
SmallParcelItemInput Type
名称 | 类型 | 描述 |
---|---|---|
partNumber | String! | 产品部件号 |
quantity | Int! | 此产品在小包裹中的数量 |
PackageTrackingCode Type
名称 | 类型 | 描述 |
---|---|---|
packageTrackingCodeTypeEnum | PackageTrackingCodeTypeEnum! | 追踪码类型 |
value | String! | 追踪码 |
PackageTrackingCodeTypeEnum Type
名称 | 描述 |
---|---|
TRACKING_NUMBER | 一个简单的包裹追踪码 |
UCC_128 | UCC-128 码 |
CastleGate Order Query CastleGate 订单查询
query getCastleGatePurchaseOrders {
getCastleGatePurchaseOrders(
limit: 10,
hasResponse: false,
sortOrder: DESC
) {
poNumber,
poDate,
estimatedShipDate,
customerName,
customerAddress1,
customerAddress2,
customerCity,
customerState,
customerPostalCode,
orderType,
shippingInfo {
shipSpeed,
carrierCode
},
packingSlipUrl,
warehouse {
id,
name
},
products {
partNumber,
quantity,
price,
event {
startDate,
endDate
}
}
}
}
CastleGate 订单查询 Query 用于拉取 CastleGate 采购订单。您可以根据需要定义 Query 的筛选参数。例如,示例部分中的 Query 由于定义了 hasResponse: false
参数,因此将仅加载未结订单(即没有回复的订单),但您也可以使用 hasResponse
筛选参数来仅拉取已结订单,或者不做任何筛选以拉取所有订单。
Input 输入
名称 | 类型 | 描述 |
---|---|---|
limit | Int = 10 | 要返回的最大结果数。如果未设置限制,则默认为10 |
hasResponse | Boolean | CastleGate 订单是否通过 API 收到回复 |
fromDate | IsoDateTime | CastleGate 订单开始日期。 指定获取订单的起始日期 |
poNumbers | [String] = [] | 要过滤(包含在结果中)的订单编号列表 |
sortOrder | SortOrder = ASC | 按订单日期升序或降序对结果进行排序 |
Output 输出
类型 | 描述 |
---|---|
[PurchaseOrder] | 订单列表,结果集将遵守输入参数 |
Acknowledge CastleGate Order Mutation 确认 CastleGate 订单
{
"query": "
mutation acknowledgeCastleGate($poNumber: String!) {
purchaseOrders {
acknowledgeCastleGate(
poNumber: $poNumber
) {
handle,
submittedAt,
errors {
key,
message
}
}
}
}
",
"variables": {
"poNumber": "CS12345678"
}
}
确认 CastleGate 订单 Mutation 让 Wayfair 知道您确认了某 CastleGate 采购订单。
Input 输入
名称 | 类型 | 描述 |
---|---|---|
poNumber | String! | 您从 Wayfair 收到的要确认的订单编号 |
Output 输出
类型 | 描述 |
---|---|
TransactionStatus! | 确认 CastleGate 订单是一个异步操作。 返回给您的数据可用于追踪您的变更进度 |
CastleGate Warehouse Shipping Advice CastleGate 仓库发货通知
当 Wayfair 配送 CastleGate(Wayfair 自有仓库)采购订单时,我们会创建一个 Warehouse Shipping Advice(仓库发货通知,简称 WSA),其中包含该发货通知的唯一标识符,即 wsaID
。供应商可以查询和确认 WSA,并相应地更新其当前产品数量。
Get CastleGate Warehouse Shipping Advice Query CastleGate 仓库发货通知查询
{
"query": "
query getCastleGateWarehouseShippingAdvice($limit: Int32!, $hasResponse: Boolean!, $fromDate: IsoDateTime!, $wsaIds: [String]!) {
purchaseOrders {
getCastleGateWarehouseShippingAdvice(
limit: $limit,
hasResponse: $hasResponse,
wsaIds: $wsaId,
fromDate: $fromDate
) {
'wsaId',
'supplierId',
'retailerOrderNumber',
'fulfillmentPurchaseOrderNumber',
'creationDate',
'shipDate',
'shipSpeed',
'carrierCode',
'totalShipmentWeight',
'totalQuantity',
'clientNumber',
'warehouseId',
'packages' => [
'packageWeight',
'trackingNumber',
],
'shipTo' => [
'name',
'address1',
'address2',
'city',
'state',
'country',
'postalCode',
],
'shipFrom' => [
'name',
'address1',
'address2',
'city',
'state',
'country',
'postalCode',
],
'products' => [
'quantityOrdered',
'partNumber',
'name',
'quantityShipped',
'upc',
'sku',
'forceQuantityMultiplier',
],
}
}
}
",
"variables": {
"limit": 10,
"hasResponse": false,
"wsaIds": "6F96C5C4-C3C-4D29-84CA-0B050F7E961A",
"fromDate": "2020-04-05 00:05:00"
}
}
CastleGate 仓库发货通知查询 Query 用于获取一组 CastleGate 订单的仓库发货通知。
Input 输入
名称 | 类型 | 描述 |
---|---|---|
limit | Int32 = 10! | 要返回的最大结果数。如果未设置限制,则默认为10 |
hasResponse | Boolean | CastleGate 订单是否通过 API 收到回复 |
WSAIds | [String] | 您从 Wayfair 收到的 WSA 识别码 |
fromDate | IsoDateTime | WSA 开始日期时间。 指定获取 WSA 的起始日期 |
sortOrder | SortOrder = ASC | 根据创建日期以升序或者降序排列结果 |
Output 输出
类型 | 描述 |
---|---|
WarehouseShippingAdvice | 有关请求的 CastleGate WSA 的详细信息。 此结果还将包含与 WSA 相关产品的包裹列表 |
Acknowledge CastleGate Warehouse Shipping Advice Mutation 确认 CastleGate 仓库发货通知
{
"query": "
mutation acknowledgeCastleGateWarehouseShippingAdvice($WSAIds: [String]!) {
purchaseOrders {
acknowledgeCastleGateWarehouseShippingAdvice(
WSAIds: $WSAIds
) {
handle,
submittedAt,
errors {
key,
message
}
}
}
}
",
"variables": {
"WSAIds": ["6F96C5C4-C3C7-4D29-84CA-0B050F7E961A"]
}
}
确认 CastleGate 仓库发货通知 Mutation 让 Wayfair 知道您已确认收到某 CastleGate 仓库发货通知。
Input 输入
名称 | 类型 | 描述 |
---|---|---|
WSAIds | List[String]! | 您从Wayfair收到的需要确认的WSA识别码 |
Output 输出
类型 | 描述 |
---|---|
TransactionStatus! | 确认CastleGate是一个同步操作。 返回给您的数据可用于跟踪变更状态 |
Shipping 发货
Wayfair 拥有全套 API 来助您开发自动发货解决方案。从总体上看,各 API 端点通过互相协调执行以下流程:
- 订单发货登记
- 为供应商计划发货的每个 Wayfair 采购订单调用 发货登记 Mutation
- 下载已登记订单的发货文件。对于每个 已登记 的订单,用户可以:
- 调用装箱单检索 API 来下载相应的装箱单
- 调用运单检索 API 来下载必要的运单
- 调用提单检索 API 来下载相应的提单
- 调用运单生成事件 Query 来获得运单的货运信息
Register Mutation 发货登记
{
"query": "
mutation register($params: RegistrationInput!) {
purchaseOrders {
register(
registrationInput: $params
) {
eventDate,
pickupDate,
consolidatedShippingLabel {
url,
},
shippingLabelInfo {
carrier,
},
purchaseOrder {
poNumber,
shippingInfo {
carrierCode
}
}
}
}
}
",
"variables": {
"params":
{
"poNumber": "CS1234567",
"warehouseId": "5000",
"requestForPickupDate": "2019-03-26 15:30:00"
}
}
}
发货登记 Mutation 是配送 Wayfair 订单所需的几乎所有对接的先决条件。通过登记一份订单,供应商告知 Wayfair 该订单已准备好从其仓库或存储地点发货,Wayfair 便能够启动对即将进行的发货的规划流程。
Consolidated Items Registration 整合发货登记
除了能够在 发货登记 Mutation 响应中获取货运文件的下载 URL 外,您还可以通过 发货登记 Mutation 来更改订单的打包数据,以将订单中的不同商品整合到同一个运输包裹中。在右侧的示例中,请只关注名为 params
的 RegistrationInput
类型的变量参数:在 variables
字段的 params.packageUnits.containedParts
中,示例通过将 ABC123
和 DEF456
两个不同的商品放在同一个包裹中,来进行整合发货。
{
"query": "
mutation register($params: RegistrationInput!) {
purchaseOrders {
register(
registrationInput: $params
) {
eventDate,
pickupDate,
poNumber
consolidatedShippingLabel {
url
}
billOfLading {
url
}
generatedShippingLabels {
poNumber
fullPoNumber
carrier
carrierCode
trackingNumber
}
customsDocument {
required
url
}
}
}
}
",
"variables": {
"params":{
"poNumber": "CS1234567",
"warehouseId": "5000",
"requestForPickupDate": "2019-03-26 15:30:00",
"packageUnits": [
{
"unitType": "CARTON",
"weight":{
"value": 10,
"unit": "KILOGRAMS"
},
"dimensions":{
"width":{
"value": 10,
"unit": "CENTIMETERS"
},
"length":{
"value": 10,
"unit": "CENTIMETERS"
},
"height":{
"value": 10,
"unit": "CENTIMETERS"
}
},
"containedParts":[
{
"partNumber": "ABC123",
"groupIdentifier": 1
},
{
"partNumber": "DEF456",
"groupIdentifier": 1
}
]
}
]
}
}
}
Input 输入
名称 | 类型 | 描述 |
---|---|---|
registrationInput | RegistrationInput! | 注册订单发货所需的输入对象 |
Output 输出
类型 | 描述 |
---|---|
LabelGenerationEvent! | 代表生成货运单据请求的数据对象 |
RegistrationInput Type
用于登记货运包裹的输入参数。
名称 | 类型 | 描述 | 默认值 |
---|---|---|---|
poNumber | String! | 输入订单ID | |
warehouseId | ID | 发货仓库ID | Wayfair 系统已指定的发货仓库ID |
requestForPickupDate | IsoDateTime | 订单要求提货的日期 | 发送发货登记请求的时间 |
packageUnits | [PackageUnit!] | 与订单关联的包裹件列表 | 默认为Wayfair目录中的运输数据 |
PackageUnit Type
用于表示货运包裹的输入参数。
名称 | 类型 | 描述 |
---|---|---|
unitType | PackageUnitTypeEnum! | 包裹种类 |
weight | WeightInput! | 包裹重量 |
dimensions | DimensionInput! | 包裹长度尺寸 |
freightClass | FreightClassEnum | 包裹件的货运级别, 按重量大致分类 |
containedParts | [ContainedPart!]! | 包裹中包括的商品部件 |
PackageUnitTypeEnum Type
用于表示可被配送的货运包裹类型。
取值 | 描述 |
---|---|
CARTON | 纸箱 |
BAG | 密封包装袋 |
ROLL | 卷筒 |
OTHER | 任何不能被定义为纸箱、卷筒、或包装袋的运输单位 |
WeightInput Type
用于表示重量的参数。
名称 | 类型 | 描述 |
---|---|---|
value | float! | 重量的测量值 |
unit | WeightUnitEnum! | 测量值的单位。单位值可以是 1 代表磅数,或者 2 代表公斤 |
WeightUnitEnum Type
用于表示受支持的重量单位。
取值 | 描述 |
---|---|
1 | 磅 (lbs) |
2 | 公斤 (kg) |
DimensionInput Type
用于表示三维(长 x 宽 x 高)的体积输入参数。
名称 | 类型 | 描述 |
---|---|---|
length | MeasurementInput | 包裹的长度 |
width | MeasurementInput | 包裹的宽度 |
height | MeasurementInput | 包裹的高度 |
MeasurementInput Type
用于表示一维长度的输入参数。
名称 | 类型 | 描述 | 默认值 |
---|---|---|---|
value | Float! | 测量值 | |
unit | LengthUnitEnum | 测量单位 | 1 (代表英寸) |
LengthUnitEnum Type
用于表示长度单位。
取值 | 描述 |
---|---|
1 | 英寸 |
2 | 厘米 |
FreightClassEnum Type
货物运输等级,按照每立方英尺所容纳的重量(类似密度)进行分类。例如:500 代表此货物的密度为 0-1 磅每立方英尺。
取值 | 描述 |
---|---|
500 | 小于1磅 - 一袋金粉,乒乓球 |
400 | 1-2磅 - 鹿角 |
300 | 2-3磅 - 木柜,桌子,椅子套件,模型船 |
250 | 3-4磅 - 竹制家具,床垫和发条盒,等离子电视 |
200 | 4-5磅 - 汽车钣金件,飞机零件,铝制桌子,包装床垫 |
175 | 5-6磅 - 服装,沙发,填充家具 |
150 | 6-7磅 - 汽车钣金件,书柜 |
125 | 7-8磅 - 小家电 |
110 | 8-9磅 - 橱柜,框架艺术品,台锯 |
100 | 9-10.5磅 - 船罩,汽车罩,帆布,红酒盒,匣子 |
92.5 | 10.5-12磅 - 电脑,显示屏,冰箱 |
85 | 12-13.5 磅 - 装箱机械,铸铁壁炉 |
77.5 | 13.5-15磅 - 轮胎,浴室装置 |
70 | 15-22.5磅 - 汽车配件和汽车零件,食品,汽车发动机 |
65 | 22.5-30磅 - 汽车配件和汽车零件,瓶装饮料,盒子里的书 |
60 | 30-35磅 - 汽车配件和汽车零件 |
55 | 35-50磅 - 砖头,水泥,砂浆和硬木地板 |
50 | 大于50磅 - 需要放置于标准 4x4 托盘上 |
ContainedPart Type
用于表示一个产品部件的输入参数。
名称 | 类型 | 描述 |
---|---|---|
partNumber | string! | 订购的产品标识 |
groupIdentifier | integer! | 一个整数, 指示具有这个部件号的商品被放入哪个箱子 |
LabelGenerationEvent Type
名称 | 类型 | 描述 |
---|---|---|
id | ID! | 事件标识符 |
eventDate | IsoDateTime! | 提交订单登记的日期和时间 |
pickupDate | IsoDateTime! | 取件日期和时间 |
billOfLading | BillOfLading! | 一份描述完整购买内容的文件 |
consolidatedShippingLabel | ShippingLabel! | 一份包含订单中所有包裹的运单的文件 |
generatedShippingLabels | [GeneratedShippingLabels]! | 一份已生成运单的信息列表 |
customsDocument | CustomsDocument! | 有关特定海关文件的信息 |
GeneratedShippingLabels Type
名称 | 类型 | 描述 |
---|---|---|
poNumber | Int! | 无前缀的订单号 |
fullPoNumber | String! | 有前缀的订单号 |
numberOfLabels | Int! | 运单号 |
carrier | String! | 运单的承运商 |
carrierCode | String! | 运单承运商代码 |
trackingNumber | String! | 运单追踪号 |
CustomsDocument Type
报关文件相关信息。
名称 | 类型 | 描述 |
---|---|---|
required | boolean! | 是否需要报关相关文件的布尔值 |
url | string | 下载报关文件URL链接 |
Packing Slip Retrieval 装箱单检索
using Newtonsoft.Json;
using RestSharp;
using System;
using System.IO;
using System.Linq;
using System.Net;
var client = new RestClient(string.Fromat("https://api.wayfair.com/v1/packing_slip/{0}", purchaseOrderNumber));
var response = client.Get(
new RestRequest(Method.GET)
.AddHeader("accept", "application/json")
.AddHeader("content-type", "application/json")
.AddHeader("authorization", string.Format("Bearer {0}", token))
);
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import java.io.IOException;
public class ApiClient {
public static void main(String[] args) throws IOException {
HttpGet request = new HttpGet("https://api.wayfair.com/v1/packing_slip/" + purchaseOrderNumber);
clockRequest.setHeader("Accept", "application/json");
clockRequest.setHeader("Authorization", "Bearer " + token);
clockRequest.setHeader("Content-Type", "application/json");
HttpClient client = HttpClients.createDefault();
HttpResponse response = client.execute(request);
}
}
var packingSlipRequestSettings = {
'async': true,
'crossDomain': true,
'url': 'https://api.wayfair.com/v1/packing_slip/' + purchaseOrderNumber,
'method': 'GET',
'headers': {
'authorization': 'Bearer ' + token,
'cache-control': 'no-cache',
'content-type': 'application/json'
}
};
$.ajax(packingSlipRequestSettings).done(function (response) {
console.log(response);
});
$client = new \GuzzleHttp\Client();
$response = $client->get(
'https://api.wayfair.com/v1/packing_slip/' + purchaseOrderNumber,
[
'headers' => [
'Authorization' => 'Bearer ' + token,
'Content-Type' => 'application/json',
]
]
);
#! /bin/python
import json
import requests
url = "https://api.wayfair.com/v1/packing_slip/" + purchaseOrderNumber
headers = {
'Authorization': 'Bearer ' + token
'Content-Type': 'application/json',
}
response = requests.request('GET', url, headers=headers)
require "http"
require "json"
response = HTTP.headers({
"Authorization" => "Bearer " + token
"Content-Type" => "application/json",
}).get("https://api.wayfair.com/v1/packing_slip" + purchaseOrderNumber)
curl -X GET 'https://api.wayfair.com/v1/packing_slip/${purchaseOrderNumber}' \
-H 'Authorization: Bearer ${token}' \
-H 'Content-Type: application/json'
响应示例:一份经下载的 PDF 装箱单。
装箱单检索 API 提供了一种简单的方式来下载各个采购订单的装箱单。
Input 输入
名称 | 类型 | 描述 |
---|---|---|
purchaseOrderNumber | string | 装箱单对应的订单号(例如:”CS12345678“) |
Output 输出
类型 | 描述 |
---|---|
PDF / octetstream | 对应订单的装箱单文件 |
Shipping Label Retrieval 运单检索
using Newtonsoft.Json;
using RestSharp;
using System;
using System.IO;
using System.Linq;
using System.Net;
var client = new RestClient(string.Fromat("https://api.wayfair.com/v1/shipping_label/{0}", purchaseOrderNumber));
var response = client.Get(
new RestRequest(Method.GET)
.AddHeader("accept", "application/json")
.AddHeader("content-type", "application/json")
.AddHeader("authorization", string.Format("Bearer {0}", token))
);
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import java.io.IOException;
public class ApiClient {
public static void main(String[] args) throws IOException {
HttpGet request = new HttpGet("https://api.wayfair.com/v1/shipping_label/" + purchaseOrderNumber);
clockRequest.setHeader("Accept", "application/json");
clockRequest.setHeader("Authorization", "Bearer " + token);
clockRequest.setHeader("Content-Type", "application/json");
HttpClient client = HttpClients.createDefault();
HttpResponse response = client.execute(request);
}
}
var shippingLabelRequestSettings = {
'async': true,
'crossDomain': true,
'url': 'https://api.wayfair.com/v1/shipping_label/' + purchaseOrderNumber,
'method': 'GET',
'headers': {
'authorization': 'Bearer ' + token,
'cache-control': 'no-cache',
'content-type': 'application/json'
}
};
$.ajax(shippingLabelRequestSettings).done(function (response) {
console.log(response);
});
$client = new \GuzzleHttp\Client();
$response = $client->get(
'https://api.wayfair.com/v1/shipping_label/' + purchaseOrderNumber,
[
'headers' => [
'Authorization' => 'Bearer ' + token,
'Content-Type' => 'application/json',
]
]
);
#! /bin/python
import json
import requests
url = "https://api.wayfair.com/v1/shipping_label/" + purchaseOrderNumber
headers = {
'Authorization': 'Bearer ' + token
'Content-Type': 'application/json',
}
response = requests.request('GET', url, headers=headers)
require "http"
require "json"
response = HTTP.headers({
"Authorization" => "Bearer " + token
"Content-Type" => "application/json",
}).get("https://api.wayfair.com/v1/shipping_label" + purchaseOrderNumber)
curl -X GET 'https://api.wayfair.com/v1/shipping_label/${purchaseOrderNumber}' \
-H 'Authorization: Bearer ${token}' \
-H 'Content-Type: application/json'
响应示例:一份经下载的 PDF 或 ZPL 运单。
运单检索 API 提供了一种简单的方式来下载各个采购订单的所有运单。
Intput 输入
名称 | 类型 | 描述 |
---|---|---|
purchaseOrderNumber | string | 运单对应的订单号(例如:“CS12345678”) |
Output 输出
类型 | 描述 |
---|---|
PDF / ZPL / octetstream | 对应订单的运单文件 |
Bill of Lading Retrieval 提单检索
using Newtonsoft.Json;
using RestSharp;
using System;
using System.IO;
using System.Linq;
using System.Net;
var client = new RestClient(string.Fromat("https://api.wayfair.com/v1/bill_of_lading/{0}", purchaseOrderNumber));
var response = client.Get(
new RestRequest(Method.GET)
.AddHeader("accept", "application/json")
.AddHeader("content-type", "application/json")
.AddHeader("authorization", string.Format("Bearer {0}", token))
);
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClients;
import java.io.IOException;
public class ApiClient {
public static void main(String[] args) throws IOException {
HttpGet request = new HttpGet("https://api.wayfair.com/v1/bill_of_lading/" + purchaseOrderNumber);
clockRequest.setHeader("Accept", "application/json");
clockRequest.setHeader("Authorization", "Bearer " + token);
clockRequest.setHeader("Content-Type", "application/json");
HttpClient client = HttpClients.createDefault();
HttpResponse response = client.execute(request);
}
}
var shippingLabelRequestSettings = {
'async': true,
'crossDomain': true,
'url': 'https://api.wayfair.com/v1/bill_of_lading/' + purchaseOrderNumber,
'method': 'GET',
'headers': {
'authorization': 'Bearer ' + token,
'cache-control': 'no-cache',
'content-type': 'application/json'
}
};
$.ajax(shippingLabelRequestSettings).done(function (response) {
console.log(response);
});
$client = new \GuzzleHttp\Client();
$response = $client->get(
'https://api.wayfair.com/v1/bill_of_lading/' + purchaseOrderNumber,
[
'headers' => [
'Authorization' => 'Bearer ' + token,
'Content-Type' => 'application/json',
]
]
);
#! /bin/python
import json
import requests
url = "https://api.wayfair.com/v1/bill_of_lading/" + purchaseOrderNumber
headers = {
'Authorization': 'Bearer ' + token
'Content-Type': 'application/json',
}
response = requests.request('GET', url, headers=headers)
require "http"
require "json"
response = HTTP.headers({
"Authorization" => "Bearer " + token
"Content-Type" => "application/json",
}).get("https://api.wayfair.com/v1/bill_of_lading" + purchaseOrderNumber)
curl -X GET 'https://api.wayfair.com/v1/bill_of_lading/${purchaseOrderNumber}' \
-H 'Authorization: Bearer ${token}' \
-H 'Content-Type: application/json'
响应示例:一份经下载的 PDF 提单。
提单检索 API 提供了一种简单的方式来下载各个采购订单的的提单。
Input 输入
名称 | 类型 | 描述 |
---|---|---|
purchaseOrderNumber | string | 提单对应的订单号(例如:“CS12345678”) |
Output 输出
类型 | 描述 |
---|---|
PDF / octetstream | 对应订单的提单文件 |
Label Generation Events Query 运单生成事件查询
query labelGenerationEvents {
labelGenerationEvents (
limit: 1,
filters: [
{
field: id
equals: "XXXXX"
},
{
field: eventDate
equals: "2022-02-01 11:00:000.000000 -05:00"
},
{
field: poNumber
equals: "XXXXX"
},
{
field: pickupDate
equals: "2022-02-01 00:00:00.000000 -05:00"
}
]
)
{
id,
eventDate,
pickupDate,
poNumber,
shippingLabelInfo {
carrier,
carrierCode,
trackingNumber
}
}
}
运单生成事件查询 Query 返回与先前提交的发货登记相关的数据。该 Query 可用于检索特定货运文件的 URL 端点,以及已提交的提货日期和相关采购订单的所有信息。在检索运单后,它还包含有关已生成运单的信息。
Input 输入
名称 | 类型 | 描述 |
---|---|---|
filters | LabelGenerationEventFilterInput = [] | 一组用于限制结果集的过滤器 |
ordering | [orderingInput] = [{asc: "id"}] | 确定结果集显示顺序的排序类型列表 |
limit | Int = 10 | 返回记录的最大数量 |
offset | Int = 0 | 结果集中第一项的索引, 即返回结果的第一项在总结果集中的索引 |
Output 输出
类型 | 描述 |
---|---|
[LabelGenerationEvent!] | 运单生成活动列表, 每一项代表一个变更请求 |
Errors 报错
由于我们使用 GraphQL 框架,您会在响应主体中 JSON 格式对象的额外 errors
字段内收到报错。即使服务发生错误,您仍然会收到 HTTP 200 状态代码,因此需要检查响应对象中是否存在 errors
字段。以下是开发人员在调用 GraphQL API 时可能遇到的一些业务和验证错误:
Inventory Errors 库存报错
Fatal Errors 严重错误
如果您收到以下错误之一,则表示您的请求 未得到处理。请解决导致错误的问题,然后重新提交请求。
错误消息 | 描述 |
---|---|
Your application has not been verified to upload inventory via this API. Please complete the steps in the testing section of this article https://partners.wayfair.com/help/3/article/16. | 未经验证的应用程序试图通过API在生产环境中提交库存数据 |
You do not have access to inventory for any suppliers. | 客户端没有为任何供应商提交库存的权限 |
The "inventory" argument cannot be empty. | 收到没有库存数据的库存变更请求 |
Required inputs are missing: {Field Names} | 输入对象缺少一个或多个必要字符段,{Field Names} 是请求中未找到的应输入字符段 |
Validation Errors 数据验证错误
如果您收到以下错误之一,则表示 请求中的有效数据部分已成功处理。请更正无效的数据部分,然后使用更新后的数据提交另一项请求。
编号 | 错误消息 | 描述 |
---|---|---|
4001 | Quantity on hand cannot be less than -1. Supplier Part Number: {Part Number} | 指定部件现有库存数量无效。有效库存为大于或等于 -1 的整数。-1 仅用于从制造商处订货时补货时间会极大延长的分销商。如果生产商和经销商都没有库存,产品应将被视为缺货。如果您认为这种情况可能适用于您,请联系您的 Wayfair 对接经理 |
4002 | Invalid supplier id given: {supp_id}. Supplier Part Number: {part_num} | 与请求中指定的部件号一起提供的供应商ID无效或不正确,请确保该供应商的部件号存在 |
4003 | Invalid 'quantity_on_hand' or 'item_next_availability_date' for discontinued product for supplier id: {supp_id}. Supplier Part Number: {part_num} | 对供应商已停产产品的无效输入。 这是为了防止对库存中已确认停产/刚刚停产的产品进行任何操作。 |
Order Errors 订单报错
General Errors 一般错误
错误消息 | 描述 |
---|---|
Your application has not been verified to accept purchase orders via this API. Please complete the steps in the testing section of this article {Article Name} | 未经授权的客户端试图通过 API 接受订单 |
Invalid purchase order number provided. | 客户端提交的订单号无效 |
Invalid quantity provided for one or more parts. | 至少一个产品的接受数量是无效的 |
Accept Order Errors 订单接受错误
错误消息 | 描述 |
---|---|
Cannot accept a purchase order without any line items. | 订单接受变更无对应产品 |
Ship speed provided does not match previously provided ship speeds | 供应商试图改变之前提供的订单响应中的货运速度 |
Purchase Order {PO Number} does not contain part {PO Part Number} | 供应商试图用一个不属于订单的部件来响应订单 |
Registration Errors 订单登记错误
错误消息 | 描述 |
---|---|
Failed Label Generation | 运单生成失败 |
Invalid pickup date provided | 提供的的取件日期无效。如果取件日期的请求格式无效,或不符合地区(EU)特定的限制条件,则会遇到该错误 |
Invalid warehouse ID provided. | 提供的仓库ID无效 |
Failed Registration: {Reason(s)} | 订单登记错误 |
Shipment Errors 订单发货错误
错误消息 | 描述 |
---|---|
At least one small parcel or large parcel shipment must be provided | 试图的发货通知中没有任何小包裹或大包裹 |
Supplier provided is not assigned to the given purchase order | 试图的发货通知中包含错误的供应商/仓库 |
Ship date cannot be in the future | 试图提交的发货通知中包含未来发货日期 |
A package cannot be empty | 试图提交的发货通知中包裹是空的 |
At least one part number is not part of this purchase order | 试图提交的发货通知中包含了一个或多个不属于订单的产品 |
Ship notice has products with higher quantity than the purchase order | 试图提交的发货通知中,某产品数量比订单中数量更多 |
如果您收到以下错误之一,则表示 请求中的有效数据部分已成功处理。请更正无效的数据部分,然后使用更新后的数据提交另一项请求。
编码 | 错误消息 | 描述 |
---|---|---|
7001 | The supplied value '{sourceAddress.country}' for sourceAddress.country should be a 2 or 3 character country code. | 国家/地区字段的限制为三个字符, 超出部分将被截断 |
7002 | The supplied value '{destinationAddress.country}' for destinationAddress.country should be a 2 or 3 character country code. | 国家/地区字段的限制为三个字符, 超出部分将被截断 |