本指南介绍了如何从 Content API for Shopping 迁移到 Merchant API,以管理商家数据。
您可以使用本指南将现有的 Content API for Shopping 实现迁移到 Merchant API。如需详细了解 Merchant API 及其子 API,请参阅 Merchant API 设计。
开始使用
如需开始使用 Merchant API,请将请求网址更改为以下格式:
https://merchantapi.googleapis.com/{SUB_API}/{VERSION}/{RESOURCE_NAME}:{METHOD}…
如需使用 Merchant API,您必须使用开发者注册方法将 Merchant Center 账号与 Google Cloud 项目相关联,具体方法如下:
POST https://merchantapi.googleapis.com/accounts/v1/accounts/{ACCOUNT_ID}/developerRegistration:registerGcp
{
developer_email:"example-email@example.com"
}
如需了解详情,请参阅快速入门 指南和 Merchant API 参考文档。
相对于 Content API for Shopping 的改进
Merchant API 可让您在 Merchant Center 中自动执行工作流并简化工作流,并且相对于 Content API for Shopping 提供了增强的功能。
关键应用场景:
- 自动账号管理
- 自动商品管理
- 自动产品目录管理系统
- 自定义报告
主要改进领域:
- 具有新功能的子 API,包括:
- 订单跟踪 支持业务订单跟踪记录,以便为客户提供准确的 预计送达时间。其信号还支持提供免费送货和快速送货 的增强型 商品详情。
- 问题解决 提供对诊断内容和支持操作的访问权限,与 Merchant Center 界面中提供的访问权限相同。
- Product Studio (ALPHA) 利用生成式 AI 生成和优化商品名和商品描述。 您需要签署此表单才能申请 访问权限。
- Accounts 子 API 中的新资源。
OmnichannelSettings管理全渠道投放的账号配置,例如非付费 本地商品详情 (FLL) 和本地商品目录广告 (LIA)。LfpProviders连接到本地 Feed 合作伙伴计划 (LFP) 合作伙伴以获取商品目录数据。GbpAccounts连接到 Google 商家资料账号以获取本地商店数据。OnlineReturnPolicy提供创建、删除和更新在线政策的功能。
- 适用于商品目录、商品数据和其他 API 的新方法,包括:
- Products 子 API 中的新方法。
ProductsUpdate可让您更新单个商品,而无需 提供ProductInput所需的所有字段。
- 不仅能够创建主要数据源,还能创建多个数据源,例如:
- 引入了商品评价和商家评价的上传功能
- 借助 Merchant API,您可以针对账号数据的更改启用通知
具体变化:
- 每次 API 调用的
pageSize上限从 250 行增加到 1000 行。 - 修复了创建
DataSources后,商品插入、促销活动、商品评价和商家评价存在的延迟问题。 - 在
productViewReporting 子 API下的 表中推出了clickPotentialRank的更新定义:- 根据
clickPotential对商品进行排名,并将其标准化为介于 1 到 1000 之间的值。
- 根据
AccountIdAlias资源中的AccountRelationship可让您更好地管理复杂的账号结构。例如,市场会使用用户定义的别名,而不是商家的内部 ID(例如账号 ID)。
gRPC 支持
Merchant API 支持 gRPC 和 REST。您可以同时将 gRPC 用于 Merchant API,并将 REST 用于 Content API for Shopping。
Merchant API 客户端库需要 gRPC。
如需了解详情,请参阅 gRPC 概览。
兼容性
本指南介绍了适用于整个 Merchant API 的一般更改。
Merchant API 旨在与现有的 Content API for Shopping 功能协同工作。
例如,您可以将 Merchant Inventories API 与现有的
Content API for Shopping v2.1
products 实现搭配使用。您可以先使用 Content API for Shopping 上传新的本地商品(您在本地商店销售的商品),然后使用 Merchant Inventories API LocalInventory 资源来管理该商品的店内信息。
相对于 Content API 的改进
Merchant API 在以下方面相对于 Content API 有所改进:
- 具有新功能的子 API,可用于您的独特集成
- 适用于商品目录、商品数据和其他 API 的新方法
- 不仅能够创建主要数据源,还能创建多个数据源,例如:
- 引入了商品评价和商家评价的上传功能
- 借助 Merchant API,您可以针对账号数据的更改启用通知。
- 引入了 过滤功能,适用于 Accounts 资源
下面详细介绍这些更改。
版本控制和子 API
Merchant API 引入了 版本控制和 子 API的概念。其模块化设计提高了易用性,让您可以专注于所需的子 API,并更轻松地在未来迁移到更新的版本。版本控制将应用于您的 请求网址。该策略与 Google Ads API 体验类似。
更强大的请求
Merchant API 网址请求需要更多参数才能调用 Merchant API。这包括资源、版本、名称(标识符)和方法(非标准方法)。如需了解详情,请参阅账号和商品 标识符及 示例。
标识符的 AIP 原则
Content API for Shopping 使用 ID 来标识资源(例如
merchantId, productId),而 Merchant API 使用
name
标识符,以符合 AIP(请参阅
API 改进原则)。
{name} 标识符包含资源标识符及其父级(或可能是多个父级),因此 {name} 等于 accounts/{account}/products/{product}
所有读取和写入调用都会返回 name 字段作为资源标识符。
{name} 还包括集合标识符 accounts/ 和 products/。
Merchant API 使用 {account} 来引用 Merchant Center ID,并使用 {product} 来引用商品标识符。
例如,实现 getName() 方法以从资源检索 name,并将输出存储为变量,而不是自行从商家和资源 ID 构建 name。
以下示例展示了如何在调用中使用 name 字段:
POST https://merchantapi.googleapis.com/inventories/v1/{PARENT}/regionalInventories:insert
下表展示了 Content API for Shopping products.get 请求的变化:
| Content API for Shopping | Merchant API |
|---|---|
GET https://shoppingcontent.googleapis.com/content/v2.1/{merchantId}/products/{productId}
|
GET https://merchantapi.googleapis.com/products/v1/{name}
|
如需了解详情,请参阅标识符 更改。
再举一个示例,使用 Merchant API 从 Merchant Center ID 4321 检索标识符为 en~US~1234 的商品,如下所示:
GET
https://merchantapi.googleapis.com/products/v1/accounts/4321/products/online~en~US~1234
其中 {name} 等于 accounts/4321/products/en~US~1234。对于 Merchant API 中的所有读取和写入调用,此新名称字段都会作为资源标识符返回。
在 Content API for Shopping 中,冒号 (:) 表示商品名称中的分隔符,而在 Merchant API 中,波浪号 (~) 执行此功能。Merchant API 标识符不包含 channel 部分。
例如,Content API for Shopping 中的商品 ID:
channel:contentLanguage:feedLabel:offerId。
在 Merchant API 中变为以下内容:
contentLanguage~feedLabel~offerId。
子资源的父字段
在 Merchant API 中,所有子资源都有
parent
字段。您可以使用 parent 字段来指定要将子资源插入到的资源的 {name},而不是传递整个父资源。您还可以将
parent 字段与
list 搭配使用
例如,如需列出给定商品的本地商品目录,请在
商品的 name 的
parent
字段中指定
list
方法。在这种情况下,给定的 product 是返回的
LocalInventory
资源的 parent。
GET
https://merchantapi.googleapis.com/inventories/v1/{parent}/localInventories
如需检索商品 en~US~1234' 和账号 4321
的所有本地商品目录,请求如下所示
GET
https://merchantapi.googleapis.com/inventories/v1/accounts/4321/products/online~en~US~1234/localInventories</code>
父级为 accounts/{account}/products/{product}。请注意,在这种情况下
the
localInventories
资源有两个父级包含在名称标识符中(accounts/ 和
products/),因为账号是商品资源的父级。
常用枚举
使用常用枚举可提供更高的一致性。
Destination.DestinationEnum
字段用于指定要在哪些平台上显示资源。
DestinationEnum 列出了目标平台定位的所有可用值,并且在各个子 API 中是
统一的,例如 促销活动
属性。
ReportingContext.ReportingContextEnum
字段表示账号和商品问题适用的情境。
此字段用于各种报告方法(例如,用于
IssueSeverityPerReportingContext)。
向后兼容性
开始使用 Merchant API 后,您现有的 Content API for Shopping 集成将继续正常运行,不会中断。如需了解详情, 请参阅 兼容性。
将子 API 迁移到 Merchant API 后,我们建议您仅将 Merchant API 用于已迁移的子 API。
远程过程调用 (gRPC) 可用性
gRPC 是与 Merchant API 集成的新推荐方式 。
它具有以下优势:
- 与语言无关
- 依赖于协议缓冲区
使用 HTTP/2 提供高性能的可扩缩解决方案 (RPC 参考)
如果您使用我们的 客户端库 或 代码 示例,gRPC 将是默认传输机制。
如需详细了解 gRPC,请参阅以下内容:
自定义批处理变为内置批处理
当您使用异步调用时,批处理的执行效率更高。详细了解如何在 Merchant API 中使用并行调用来实现批处理,以及如何重构代码以处理并发请求。
为帮助您加快迁移速度,我们建议您使用客户端 库。
Merchant API 不支持 Content API for Shopping 中的
customBatch
方法。请改为参阅一次发送多个
请求或以异步方式执行调用
。
以下 Java 示例演示了如何插入商品输入:
import com.google.api.core.ApiFuture;
import com.google.api.core.ApiFutureCallback;
import com.google.api.core.ApiFutures;
import com.google.api.gax.core.FixedCredentialsProvider;
import com.google.api.gax.grpc.InstantiatingGrpcChannelProvider;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.shopping.merchant.products.v1.Availability;
import com.google.shopping.merchant.products.v1.Condition;
import com.google.shopping.merchant.products.v1.InsertProductInputRequest;
import com.google.shopping.merchant.products.v1.ProductAttributes;
import com.google.shopping.merchant.products.v1.ProductInput;
import com.google.shopping.merchant.products.v1.ProductInputsServiceClient;
import com.google.shopping.merchant.products.v1.ProductInputsServiceSettings;
import com.google.shopping.merchant.products.v1.Shipping;
import com.google.shopping.type.Price;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import shopping.merchant.samples.utils.Authenticator;
import shopping.merchant.samples.utils.Config;
/** This class demonstrates how to insert a product input */
public class InsertProductInputAsyncSample {
private static String getParent(String accountId) {
return String.format("accounts/%s", accountId);
}
private static String generateRandomString() {
String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random();
StringBuilder sb = new StringBuilder(8);
for (int i = 0; i < 8; i++) {
sb.append(characters.charAt(random.nextInt(characters.length())));
}
return sb.toString();
}
private static ProductInput createRandomProduct() {
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();
ProductAttributes attributes =
ProductAttributes.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(Availability.IN_STOCK)
.setCondition(Condition.NEW)
.setGoogleProductCategory("Media > Books")
.addGtins("9780007350896")
.addShipping(shipping)
.addShipping(shipping2)
.build();
return ProductInput.newBuilder()
.setContentLanguage("en")
.setFeedLabel("CH")
.setOfferId(generateRandomString())
.setProductAttributes(attributes)
.build();
}
public static void asyncInsertProductInput(Config config, String dataSource) throws Exception {
// Obtains OAuth token based on the user's configuration.
GoogleCredentials credential = new Authenticator().authenticate();
// Creates a channel provider. This provider manages a pool of gRPC channels
// to enhance throughput for bulk operations. Each individual channel in the pool
// can handle up to approximately 100 concurrent requests.
//
// Channel: A single connection pathway to the service.
// Pool: A collection of multiple channels managed by this provider.
// Requests are distributed across the channels in the pool.
//
// We recommend estimating the number of concurrent requests you'll make, divide by 50 (50%
// utilization of channel capacity), and set the pool size to that number.
InstantiatingGrpcChannelProvider channelProvider =
InstantiatingGrpcChannelProvider.newBuilder().setPoolSize(30).build();
// Creates service settings using the credentials retrieved above.
ProductInputsServiceSettings productInputsServiceSettings =
ProductInputsServiceSettings.newBuilder()
.setCredentialsProvider(FixedCredentialsProvider.create(credential))
.setTransportChannelProvider(channelProvider)
.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)) {
// Creates five insert product input requests with random product IDs.
List<InsertProductInputRequest> requests = new ArrayList<>(5);
for (int i = 0; i < 5; i++) {
InsertProductInputRequest request =
InsertProductInputRequest.newBuilder()
.setParent(parent)
// You can only insert products into datasource types of Input "API", 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(createRandomProduct())
.build();
requests.add(request);
}
System.out.println("Sending insert product input requests");
List<ApiFuture<ProductInput>> futures =
requests.stream()
.map(
request ->
productInputsServiceClient.insertProductInputCallable().futureCall(request))
.collect(Collectors.toList());
// Creates callback to handle the responses when all are ready.
ApiFuture<List<ProductInput>> responses = ApiFutures.allAsList(futures);
ApiFutures.addCallback(
responses,
new ApiFutureCallback<List<ProductInput>>() {
@Override
public void onSuccess(List<ProductInput> results) {
System.out.println("Inserted products below");
System.out.println(results);
}
@Override
public void onFailure(Throwable throwable) {
System.out.println(throwable);
}
},
MoreExecutors.directExecutor());
} catch (Exception e) {
System.out.println(e);
}
}
public static void main(String[] args) throws Exception {
Config config = Config.load();
// Identifies the data source that will own the product input.
String dataSource = "accounts/" + config.getAccountId() + "/dataSources/{datasourceId}";
asyncInsertProductInput(config, dataSource);
}
}
如果您在
customBatch中
Content API 中使用,并且需要 Merchant API 提供此功能,请在您的
反馈中告知我们原因。
专有功能
未来的功能将仅在 Merchant API 中提供。(会有一些 例外情况,例如 2025 年年度 Feed 规范。)
Merchant API 专有的功能包括
价格
以下是 Merchant Common 软件包中 Price 的变化:
| Content API for Shopping | Merchant API | |
|---|---|---|
| 金额字段 | value:string |
amountMicros:int64 |
| 币种字段 | currency:string
|
currencyCode:string |
现在,Price 金额以微单位记录,其中 100 万微单位相当于您币种的标准单位。
在 Content API for Shopping 中,Price 是字符串形式的小数。
金额字段名称已从 value 更改为 amountMicros
币种字段名称已从 currency 更改为 currencyCode。格式仍为
ISO 4217。
最新动态和公告
如需了解更精细的更新,请参阅每个子 API 的专用版本说明。如需了解更常规的 Merchant API 汇总更新,请查看我们的 最新动态。
如需了解更具体的详情,并详细了解 Merchant API,请查看我们的 开发者网站 概览和整体迁移 指南。
如需详细了解 Merchant API 及其 子 API,请参阅 Merchant API 设计。