本指南說明如何從 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 使用者介面中的功能相同。
- Accounts 子 API 中的新資源。
OmnichannelSettings管理全通路服務的帳戶設定,例如免費區域產品資訊 (FLL) 和店面商品目錄廣告 (LIA)。LfpProviders連結至店面動態饋給合作夥伴 (LFP) 合作夥伴,取得商品目錄資料。GbpAccounts連結至 Google 商家檔案帳戶,取得本地商店資料。OnlineReturnPolicy可讓您建立、刪除及更新線上政策。
- 商品目錄、產品資料和其他 API 的新方法,包括:
- Products 子 API 中的新方法。
ProductsUpdate可讓您更新個別產品,不必提供ProductInput的所有必要欄位。
- 除了主要資料來源,還能建立多種資料來源,例如:
- 介紹如何上傳產品評論和商家評論
- 你可以透過 Merchant API,啟用帳戶資料異動通知
異動情形
pageSize的上限從每次 API 呼叫 250 列增加到 1000 列。- 修正了建立
DataSources後,產品插入、促銷活動、產品評論和商家評論延遲的問題。 - Reporting 子 API 下
productView表格中clickPotentialRank的更新定義:- 系統會根據
clickPotential將產品排名正規化為 1 到 1000 之間的值。
- 系統會根據
AccountRelationship資源中的AccountIdAlias可讓您更妥善管理複雜的帳戶結構。舉例來說,市集會使用使用者定義的別名,而非商家的內部 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 功能搭配使用。
舉例來說,您可以搭配現有的 Content API for Shopping v2.1 products 實作,使用 Merchant Inventories API。您可以使用 Content API for Shopping 上傳新的店面產品 (在本地商店銷售),然後使用 Merchant Inventories API LocalInventory 資源管理該產品的店內資訊。
Content API 結構改善
Merchant API 在下列方面優於 Content API:
- 子 API 具備新功能,可滿足獨特的整合需求
- 商品目錄、產品資料和其他 API 的新方法
- 除了主要資料來源,還能建立多個資料來源,例如:
- 介紹如何上傳產品評論和商家評論
- 你可以透過 Merchant API,啟用帳戶資料異動通知。
- 為帳戶資源導入篩選功能
請仔細考量這些異動。
版本管理和子 API
Merchant API 導入了版本管理和子 API 的概念。模組化設計可讓您專注於所需的子 API,並在日後更輕鬆地遷移至新版本,進而提升易用性。版本管理會套用至要求網址。這項策略與 Google Ads API 體驗類似。
更強大的要求
Merchant API 網址要求需要更多參數,才能呼叫 Merchant API。包括資源、版本、名稱 (識別項) 和方法 (非標準方法)。詳情請參閱「帳戶和產品 ID」和範例。
ID 的 AIP 原則
Content API for Shopping 使用 ID 識別資源 (例如 merchantId、productId),Merchant API 則使用 name 識別碼,與 AIP 保持一致 (請參閱 API 改善原則)。
{name} 識別碼包含資源識別碼及其父項 (或可能有多個父項),因此 {name} 等於 accounts/{account}/products/{product}
所有讀取和寫入呼叫都會傳回 name 欄位做為資源 ID。
{name} 也包含集合 ID accounts/ 和 products/。
Merchant API 使用 {account} 參照 Merchant Center ID,並使用 {product} 參照產品 ID。
舉例來說,您可以實作 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}
|
詳情請參閱「ID 異動」。
另一個例子是,使用 Merchant API 從 Merchant Center ID 4321 擷取 ID 為 en~US~1234 的產品,如下所示:
GET
https://merchantapi.googleapis.com/products/v1/accounts/4321/products/en~US~1234
其中 {name} 等於 accounts/4321/products/en~US~1234。這個新名稱欄位會做為資源 ID 傳回,用於 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},而不必傳遞整個父項資源。您也可以搭配 list 使用 parent 欄位
舉例來說,如要列出特定產品的店面商品目錄資料,請在 list 方法的 parent 欄位中指定產品的 name。在這種情況下,指定的 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/en~US~1234/localInventories
父項為 accounts/{account}/products/{product}。請注意,在這種情況下,localInventories 資源的名稱 ID 包含兩個父項 (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.ChannelPoolSettings;
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()
.setChannelPoolSettings(ChannelPoolSettings.staticallySized(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);
}
}
如果您在 Content API 中使用 customBatch,且需要 Merchant API 的這項功能,請在意見回饋中說明原因。
專屬功能
未來的新功能只會出現在 Merchant API。(2025 年年度動態饋給規格等少數情況除外)。
Merchant API 專屬功能包括:
價格
Merchant Common 套件中 Price 的異動如下:
| Content API for Shopping | Merchant API | |
|---|---|---|
| 金額欄位 | value:string |
amountMicros:int64 |
| 貨幣欄位 | currency:string
|
currencyCode:string |
金額現在以百萬分之一為單位記錄,100 萬個百萬分之一等於貨幣的標準單位。Price
在 Content API for Shopping 中,Price 是字串形式的小數。
金額欄位名稱已從 value 變更為 amountMicros
貨幣欄位名稱已從 currency 變更為 currencyCode。格式仍為 ISO 4217。
最新消息和公告
如需更詳細的更新資訊,請參閱各子 API 的版本資訊。如要查看 Merchant API 的定期匯總更新,請參閱最新更新。
如要進一步瞭解 Merchant API,請參閱開發人員網站總覽和整體遷移指南。
如要進一步瞭解 Merchant API 及其子 API,請參閱「Merchant API 設計」。