本页介绍了如何以编程方式上传和管理商品。借助 Merchant Products API,您可以在数据源中插入或更新商品、从账号中检索商品,以及从数据源中删除商品。
Merchant Products API 包含两个资源。
productInputs
表示产品的输入部分。products
表示根据输入部分构建的处理产品。
productInputs
可以是主要 Feed 也可以是补充 Feed,具体取决于其是上传到主要数据源还是补充数据源。每个 product
都将由一个主要 productInput
和任意数量的补充 productInputs
构建而成。
您可以使用 Merchant Products API 创建网店或本地实体店目录,这些商品可以在多个购物目标平台上展示。创建 Merchant Center 账号、设置第一个数据源,并准备好通过 API 上传第一组商品后,您就可以使用 productInputs
资源了。
虽然商家可以使用名为 PrimaryProductDataSource 的文件上传商品,但使用 Merchant API 创建和删除商品有诸多优势。这些优势包括响应时间更短,以及能够实时更新商品,而无需管理大型文件。对于通过 API 调用所做的商品更改,可能需要几个小时之后才能在购物数据库中显示。
前提条件
如果您没有数据源,请使用 Merchant Data Sources API 或 Merchant Center 创建数据源。
如果您已经使用 Merchant Center 界面或 API 创建了数据源,则可以使用 Merchant Products API 添加商品。如果您使用 Content API for Shopping 添加商品,请参阅迁移指南,了解如何开始使用 Merchant Products API。
您有责任遵守购物广告和非付费商品详情政策。如果我们发现违反这些政策的内容或行为,Google 购物广告保留强制执行这些政策的权利,并会做出适当的回应。
资源
借助 products
资源,您可以从 Shopping 数据库检索商品信息。
productInput
资源表示您为商品提交的输入数据。它还提供一些方法,允许您一次更新或删除一件商品的信息,或以批处理模式一次更新或删除多件商品的信息。productInput
资源必须包含以下字段:
channel
:商品的渠道。offerId
:商品的唯一标识符。contentLanguage
:商品的双字母 ISO 639-1 语言代码。feedLabel
:用于对商品进行分类和标识的标签。允许的字符数上限为 20 个,支持的字符包括A-Z
、0-9
、连字符和下划线。Feed 标签不得包含任何空格。如需了解详情,请参阅使用 Feed 标签。
将商品信息上传到您的账号
如需将商品输入内容上传到您的账号,请使用 accounts.productInputs.insert
方法。您必须传递主要数据源或补充数据源的唯一标识符。
以下示例请求展示了如何使用 accounts.productInputs.insert
方法将商品输入内容上传到商家账号。该请求会设置运费和地区,以及制造日期和尺寸等自定义属性。
POST https://merchantapi.googleapis.com/products/v1beta/accounts/{ACCOUNT_ID}/productInputs:insert?dataSource={DATASOURCE}
{
"name": "{PRODUCT_TITLE}",
"versionNumber": {VERSION_NUMBER},
"contentLanguage": "{CONTENT_LANGUAGE}",
"feedLabel": "{FEED_LABEL}",
"offerId": "{OFFER_ID}",
"channel": "ONLINE",
"attributes": {
"availability": "in stock",
"imageLink": "{IMAGE_LINK}",
"link": "{PRODUCT_LINK}",
"brand": "{BRAND_NAME}",
"price": {
"currencyCode": "{CURRENCY_CODE}",
"amountMicros": {PRICE}
},
"color": "red",
"productWeight": {
"value": 320,
"unit": "g"
},
"adult": false,
"shipping": [
{
"country": "GB",
"price": {
"amountMicros": {SHIPPING_COST},
"currencyCode": "{CURRENCY_CODE_SHIPPING}"
},
"postalCode": "{SHIPPING_POSTALCODE}",
"service": "",
"region": "{SHIPPING_REGION}",
"maxHandlingTime": "{MAX_HANDLING_TIME}",
"minHandlingTime": "{MIN_HANDLING_TIME}",
"maxTransitTime": "{MAX_TRANSIT_TIME}",
"minTransitTime": "{MIN_TRANSIT_TIME}"
}
],
"gender": "Female"
},
"customAttributes": [
{
"name": "size",
"value": "Large"
},
{
"name": "Date of Manufacturing",
"value": "2024-05-05"
}
]
}
替换以下内容:
- {ACCOUNT_ID}:您的 Merchant Center 账号的唯一标识符。
- {DATASOURCE}:数据源的唯一标识符。其格式应为
accounts/
{ACCOUNT_ID}/dataSources/
{DATASOURCE_ID}。 - {PRODUCT_TITLE}:商品的名称。
- {VERSION_NUMBER}:商品的版本号。可选。
- {CONTENT_LANGUAGE}:商品的双字母 ISO 639-1 语言代码。必填。
- {FEED_LABEL}:用于对商品进行分类和标识的标签。允许的字符数不得超过 20 个,支持的字符包括
A-Z
、0-9
、连字符和下划线。Feed 标签不得包含任何空格。 - {OFFER_ID}:商品的唯一标识符。必填。
- {IMAGE_LINK}:指向您网站上商品图片的链接。可选。
- {PRODUCT_LINK}:指向您网站上相应商品的链接。可选。
- {CURRENCY_CODE}:价格所用币种,采用由三个字母表示的 ISO 4217 格式。可选。
- {PRICE}:商品的价格,以微秒数表示。可选。
- {SHIPPING_COST}:固定配送费用,以数字表示。可选。
- {SHIPPING_POSTALCODE}:适用配送费率的邮政编码范围。可选。
- {MAX_HANDLING_TIME}:从收到订单到发货所需的最长工作日处理时间。可选。
- {MIN_HANDLING_TIME}:从收到订单到发货所需的最短工作日处理时间。值 0 表示订单在收到当天送达。可选。
- {MAX_TRANSIT_TIME}:从订单发货到送达所需的最长工作日天数。可选。
- {MIN_TRANSIT_TIME}:从订单发货到送达所需的最短工作日天数。值 0 表示订单在发货当天送达。可选。
请求成功运行后,您会看到以下响应:
{
"name": "{PRODUCT_NAME}",
"product": "{PRODUCT_ID}",
"channel": "ONLINE",
"offerId": "{OFFER_ID}",
"contentLanguage": "{CONTENT_LANGUAGE}",
"feedLabel": "{FEED_LABEL}",
"versionNumber": "{VERSION_NUMBER}",
"attributes": {
"link": "{PRODUCT_LINK}",
"imageLink": "{IMAGE_LINK}",
"adult": false,
"availability": "in stock",
"brand": "{BRAND_NAME}",
"color": "red",
"gender": "Female",
"price": {
"amountMicros": "{PRICE}",
"currencyCode": "{CURRENCY_CODE}"
},
"shipping": [
{
"price": {
"amountMicros": "{SHIPPING_COST}",
"currencyCode": "{CURRENCY_CODE}"
},
"country": "{SHIPPING_COUNTRY}",
"region": "{SHIPPING_REGION}",
"postalCode": "{SHIPPING_POSTALCODE}",
"minHandlingTime": "{MIN_HANDLING_TIME}",
"maxHandlingTime": "{MAX_HANDLING_TIME}",
"minTransitTime": "{MIN_TRANSIT_TIME}",
"maxTransitTime": "{MAX_TRANSIT_TIME}"
}
],
"productWeight": {
"value": 320,
"unit": "g"
}
},
"customAttributes": [
{
"name": "Size",
"value": "Large"
},
{
"name": "Date of Manufacturing",
"value": "2024-05-05"
}
]
}
如需向 Merchant Center 账号添加商品,您可以使用 google.shopping.merchant.accounts.v1beta.InsertProductInputSample
方法,如下例所示。
Java
public static void insertProductInput(Config config, String dataSource) throws Exception {
// Obtains OAuth token based on the user's configuration.
GoogleCredentials credential = new Authenticator().authenticate();
// Creates service settings using the credentials retrieved above.
ProductInputsServiceSettings productInputsServiceSettings =
ProductInputsServiceSettings.newBuilder()
.setCredentialsProvider(FixedCredentialsProvider.create(credential))
.build();
// Creates parent to identify where to insert the product.
String parent = getParent(config.getAccountId().toString());
// Calls the API and catches and prints any network failures/errors.
try (ProductInputsServiceClient productInputsServiceClient =
ProductInputsServiceClient.create(productInputsServiceSettings)) {
// Price to be used for shipping ($33.45).
Price price = Price.newBuilder().setAmountMicros(33_450_000).setCurrencyCode("USD").build();
Shipping shipping =
Shipping.newBuilder()
.setPrice(price)
.setCountry("GB")
.setService("1st class post")
.build();
Shipping shipping2 =
Shipping.newBuilder()
.setPrice(price)
.setCountry("FR")
.setService("1st class post")
.build();
Attributes attributes =
Attributes.newBuilder()
.setTitle("A Tale of Two Cities")
.setDescription("A classic novel about the French Revolution")
.setLink("https://exampleWebsite.com/tale-of-two-cities.html")
.setImageLink("https://exampleWebsite.com/tale-of-two-cities.jpg")
.setAvailability("in stock")
.setCondition("new")
.setGoogleProductCategory("Media > Books")
.setGtin(0, "9780007350896")
.addShipping(shipping)
.addShipping(shipping2)
.build();
// The datasource can be either a primary or supplemental datasource.
InsertProductInputRequest request =
InsertProductInputRequest.newBuilder()
.setParent(parent)
// You can only insert products into datasource types of Input "API" and "FILE", and
// of Type "Primary" or "Supplemental."
// This field takes the `name` field of the datasource.
.setDataSource(dataSource)
// If this product is already owned by another datasource, when re-inserting, the
// new datasource will take ownership of the product.
.setProductInput(
ProductInput.newBuilder()
.setChannel(ChannelEnum.ONLINE)
.setContentLanguage("en")
.setFeedLabel("label")
.setOfferId("sku123")
.setAttributes(attributes)
.build())
.build();
System.out.println("Sending insert ProductInput request");
ProductInput response = productInputsServiceClient.insertProductInput(request);
System.out.println("Inserted ProductInput Name below");
// The last part of the product name will be the product ID assigned to a product by Google.
// Product ID has the format `channel~contentLanguage~feedLabel~offerId`
System.out.println(response.getName());
System.out.println("Inserted Product Name below");
System.out.println(response.getProduct());
} catch (Exception e) {
System.out.println(e);
}
}
从您的账号中检索已处理的商品
如需从您的账号中检索已处理的商品,请使用 accounts.products.get
方法。添加后,处理好的商品可能需要几分钟才能显示。
GET https://merchantapi.googleapis.com/products/v1beta/accounts/{ACCOUNT_ID}/products/{PRODUCT_NAME}
将 {PRODUCT_NAME} 替换为您要删除的商品输入资源的名称。例如 online~en~US~sku123
。
您可以从 accounts.productInputs.insert
的响应中的 product
字段获取已处理商品的资源名称。
如需检索指定 Merchant Center 账号中的单个商品,您可以使用 google.shopping.merchant.accounts.v1beta.GetProductRequest
方法,如以下示例所示。
Java
public static void getProduct(Config config, String product) throws Exception {
// Obtains OAuth token based on the user's configuration.
GoogleCredentials credential = new Authenticator().authenticate();
// Creates service settings using the credentials retrieved above.
ProductsServiceSettings productsServiceSettings =
ProductsServiceSettings.newBuilder()
.setCredentialsProvider(FixedCredentialsProvider.create(credential))
.build();
// Calls the API and catches and prints any network failures/errors.
try (ProductsServiceClient productsServiceClient =
ProductsServiceClient.create(productsServiceSettings)) {
// The name has the format: accounts/{account}/products/{productId}
GetProductRequest request = GetProductRequest.newBuilder().setName(product).build();
System.out.println("Sending get product request:");
Product response = productsServiceClient.getProduct(request);
System.out.println("Retrieved Product below");
System.out.println(response);
} catch (Exception e) {
System.out.println(e);
}
}
从您的账号中删除商品信息
如需从您的账号中删除商品输入信息,请使用 accounts.productInputs.delete
方法。若要使用 Merchant Products API 删除商品,您必须传递商品所属的主要数据源或补充数据源的唯一标识符。
以下请求展示了如何使用 accounts.productInputs.delete
方法删除商品输入:
DELETE https://merchantapi.googleapis.com/products/v1beta/accounts/{ACCOUNT_ID}/productInputs/{PRODUCT_NAME}?dataSource=accounts/{ACCOUNT_ID}/dataSources/{DATASOURCE_ID}
将 {PRODUCT_NAME} 替换为您要删除的商品输入资源的名称。例如 online~en~US~sku123
。
如需删除给定 Merchant Center 账号的商品,您可以使用 google.shopping.merchant.accounts.v1beta.DeleteProductInputRequest
方法,如以下示例所示。
Java
public static void deleteProductInput(Config config, String productId, String dataSource)
throws Exception {
// Obtains OAuth token based on the user's configuration.
GoogleCredentials credential = new Authenticator().authenticate();
// Creates service settings using the credentials retrieved above.
ProductInputsServiceSettings productInputsServiceSettings =
ProductInputsServiceSettings.newBuilder()
.setCredentialsProvider(FixedCredentialsProvider.create(credential))
.build();
// Creates product name to identify product.
String name =
ProductInputName.newBuilder()
.setAccount(config.getAccountId().toString())
.setProductinput(productId)
.build()
.toString();
// Calls the API and catches and prints any network failures/errors.
try (ProductInputsServiceClient productInputsServiceClient =
ProductInputsServiceClient.create(productInputsServiceSettings)) {
DeleteProductInputRequest request =
DeleteProductInputRequest.newBuilder().setName(name).setDataSource(dataSource).build();
System.out.println("Sending deleteProductInput request");
productInputsServiceClient.deleteProductInput(request); // no response returned on success
System.out.println(
"Delete successful, note that it may take a few minutes for the delete to update in"
+ " the system. If you make a products.get or products.list request before a few"
+ " minutes have passed, the old product data may be returned.");
} catch (Exception e) {
System.out.println(e);
}
}
列出账号中的商品
如需列出您账号中已处理的商品,请使用 accounts.products.list
方法,如以下请求所示。
GET https://merchantapi.googleapis.com/products/v1beta/accounts/{ACCOUNT_ID}/products
如需为指定的 Merchant Center 账号列出商品,您可以使用 google.shopping.merchant.accounts.v1beta.ListProductsRequest
方法,如下例所示。
Java
public static void listProducts(Config config) throws Exception {
// Obtains OAuth token based on the user's configuration.
GoogleCredentials credential = new Authenticator().authenticate();
// Creates service settings using the credentials retrieved above.
ProductsServiceSettings productsServiceSettings =
ProductsServiceSettings.newBuilder()
.setCredentialsProvider(FixedCredentialsProvider.create(credential))
.build();
// Creates parent to identify the account from which to list all products.
String parent = getParent(config.getAccountId().toString());
// Calls the API and catches and prints any network failures/errors.
try (ProductsServiceClient productsServiceClient =
ProductsServiceClient.create(productsServiceSettings)) {
// The parent has the format: accounts/{account}
ListProductsRequest request = ListProductsRequest.newBuilder().setParent(parent).build();
System.out.println("Sending list products request:");
ListProductsPagedResponse response = productsServiceClient.listProducts(request);
int count = 0;
// Iterates over all rows in all pages and prints the datasource in each row.
// Automatically uses the `nextPageToken` if returned to fetch all pages of data.
for (Product product : response.iterateAll()) {
System.out.println(product); // The product includes the `productStatus` field
// That shows approval and disapproval information.
count++;
}
System.out.print("The following count of products were returned: ");
System.out.println(count);
} catch (Exception e) {
System.out.println("An error has occured: ");
System.out.println(e);
}
}