您可以參考本指南,將現有的 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 參考資料。
相較於 Content API 的改良項目
Merchant API 可讓你自動化及簡化 Merchant Center 中的工作流程,並提供比 Content API 更強大的功能。
主要用途:
- 自動管理帳戶
- 自動化產品管理
- 自動化商品目錄管理
- 自訂報表
主要改善項目:
- 提供新功能的子 API,可用於您的獨特整合
- 針對商品目錄、產品資料和其他 API 新增方法
- 不僅可以建立主要資料來源,還可以建立多個資料來源,例如:
- 推出產品評論和商家評論上傳功能
- 透過 Merchant API,您可以啟用帳戶資料變更通知
gRPC 支援
Merchant API 支援 gRPC 和 REST。你可以同時使用 gRPC 和 REST 來呼叫 Merchant API 和 Content API for Shopping。
Merchant API 用戶端程式庫需要 gRPC。
詳情請參閱 gRPC 總覽。
相容性
本指南說明瞭整個 Merchant API 適用的一般變更。
Merchant API 可與現有的 Content API for Shopping 2.1 版功能搭配使用。
舉例來說,您可以將 Merchant Inventories API 與現有的 Content API for Shopping 2.1 版 products
實作項目搭配使用。你可以使用 Content API for Shopping 上傳新的店面產品 (在店面銷售的產品),然後使用 Merchant Inventories API LocalInventory
資源管理該產品的店內資訊。
批次要求
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.auth.oauth2.GoogleCredentials;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.shopping.merchant.products.v1beta.Attributes;
import com.google.shopping.merchant.products.v1beta.InsertProductInputRequest;
import com.google.shopping.merchant.products.v1beta.ProductInput;
import com.google.shopping.merchant.products.v1beta.ProductInputsServiceClient;
import com.google.shopping.merchant.products.v1beta.ProductInputsServiceSettings;
import com.google.shopping.merchant.products.v1beta.Shipping;
import com.google.shopping.type.Channel.ChannelEnum;
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();
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")
.addGtin("9780007350896")
.addShipping(shipping)
.addShipping(shipping2)
.build();
return ProductInput.newBuilder()
.setChannel(ChannelEnum.ONLINE)
.setContentLanguage("en")
.setFeedLabel("CH")
.setOfferId(generateRandomString())
.setAttributes(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 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)) {
// 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 支援這項功能,請透過意見回饋告訴我們原因。
ID
為配合 Google 的 API 改善原則,我們對 Merchant API 資源的 ID 進行了一些變更。
使用 IDENTIFIER
表示資源訊息中的欄位用於識別資源。它會附加至名稱欄位,請參閱「代表資源名稱的欄位」。
IDENTIFIER
值表示在建立方法的情況下,系統不會將該欄位做為輸入內容 (即 OUTPUT_ONLY
) 接受,但會將其視為 IMMUTABLE
,並將其做為輸入內容接受,這類方法會將資源做為主要輸入內容,例如:標準更新。
名稱取代 ID
所有 Merchant API 資源都會使用 name
欄位做為專屬 ID。
以下是如何在呼叫中使用 name
欄位的範例:
GET https://merchantapi.googleapis.com/products/v1beta/accounts/4321/products/online~en~US~1234
其中 name
等於 accounts/4321/products/online~en~US~1234
。
這個新的 name
欄位會傳回做為 Merchant API 中所有讀取和寫入呼叫的資源 ID。
舉例來說,您可以實作 getName()
方法,從資源擷取 name
,並將輸出內容儲存為變數,而非自行從業務和資源 ID 建構 name
。
分隔符號
Merchant API 會使用波浪號,而非冒號做為分隔符號。
下表比較 Content API 和 Merchant API 的產品 ID:
Content API | Merchant API |
---|---|
channel:contentLanguage:feedLabel:offerId 。例如:online:en:US:sku123 |
channel~contentLanguage~feedLabel~offerId 。例如:online~en~US~sku123 |
子項資源的父項欄位
在 Merchant API 中,所有子資源都有 parent
欄位。您可以使用 parent
欄位指定要插入子項的資源 name
,而非傳遞整個父項資源。您也可以使用 parent
欄位搭配 list
方法,列出該 parent
的子項資源。
舉例來說,如要列出特定產品的店面商品目錄,請在 list
方法的 parent
欄位中指定產品的 name
。在這種情況下,指定的 product
是傳回的 LocalInventory
資源的 parent
。
GET https://merchantapi.googleapis.com/inventories/v1beta/{parent}/localInventories
如要擷取產品 online~en~US~1234
和帳戶 4321
的所有店面商品目錄,請使用以下要求:
GET https://merchantapi.googleapis.com/inventories/v1beta/accounts/4321/products/online~en~US~1234/localInventories
其中 parent 等於 accounts/{account}/products/{product}。請注意,在這種情況下,localInventories 的名稱 ID 中包含兩個父項 (accounts/ 和 products/),因為帳戶是產品資源的父項。
常見類型
以下是 Merchant API 子 API 共用的幾種常見類型。
Destination.DestinationEnum
使用 Destination.DestinationEnum 欄位,控管資源應顯示在哪些介面上。DestinationEnum
欄位會列出所有可用的指定目的地值。這些 API 會在多個子 API 中統一 DestinationEnum
,例如促銷活動屬性。
ReportingContext.ReportingContextEnum
ReportingContext.ReportingContextEnum 欄位代表帳戶和產品問題適用的情境。這個欄位會用於多種報表方法 (例如 IssueSeverityPerReportingContext)。
價格
以下是 Merchant Common 套件中 Price
的異動內容:
Content API | Merchant API | |
---|---|---|
金額欄位 | value:string |
amountMicros:int64 |
貨幣欄位 | currency:string
|
currencyCode:string |
Price
金額現在以微量單位記錄,其中 100 萬微量單位等於貨幣的標準單位。
在 Content API for Shopping 中,Price
是字串格式的小數。
金額欄位名稱已從 value
變更為 amountMicros
貨幣欄位名稱已從 currency
變更為 currencyCode
。格式仍為 ISO 4217。