Di chuyển từ Content API for Shopping sang Merchant API

Hướng dẫn này giải thích quy trình di chuyển từ Content API for Shopping sang Merchant API để quản lý dữ liệu doanh nghiệp.

Bạn có thể sử dụng hướng dẫn này để di chuyển quá trình triển khai Content API for Shopping hiện có sang Merchant API. Để biết thêm thông tin về các chi tiết của Merchant API và các API phụ của API này, hãy xem bài viết Thiết kế Merchant API.

Bắt đầu

Để bắt đầu sử dụng Merchant API, hãy thay đổi URL yêu cầu thành định dạng sau:

https://merchantapi.googleapis.com/{SUB_API}/{VERSION}/{RESOURCE_NAME}:{METHOD}

Để sử dụng Merchant API, bạn phải liên kết tài khoản Merchant Center và dự án Google Cloud bằng phương thức Đăng ký nhà phát triển như sau:

POST https://merchantapi.googleapis.com/accounts/v1/accounts/{ACCOUNT_ID}/developerRegistration:registerGcp

{
  developer_email:"example-email@example.com"
}

Để biết thêm thông tin, hãy xem hướng dẫn bắt đầu nhanh và tài liệu tham khảo về Merchant API .

Những điểm cải thiện so với Content API for Shopping

Merchant API cho phép bạn tự động hoá và đơn giản hoá quy trình làm việc trong Merchant Center, đồng thời cung cấp các tính năng nâng cao so với Content API for Shopping.

Các trường hợp sử dụng chính:

  • Tự động quản lý tài khoản
  • Tự động quản lý sản phẩm
  • Quản lý khoảng không quảng cáo tự động
  • Báo cáo tuỳ chỉnh

Các khía cạnh cần cải thiện chính:

Những điều đã thay đổi:

  • Số lượng pageSize tối đa đã tăng từ 250 lên 1000 hàng cho mỗi lệnh gọi API.
  • Đã khắc phục tình trạng chậm trễ khi chèn sản phẩm, chương trình khuyến mãi, bài đánh giá sản phẩm và bài đánh giá người bán sau khi DataSources tạo đã được khắc phục.
  • Ra mắt định nghĩa cập nhật cho clickPotentialRank trong bảng productView thuộc API phụ Báo cáo:
    • Thứ hạng của sản phẩm dựa trên clickPotential được chuẩn hoá thành các giá trị từ 1 đến 1000.
  • AccountIdAlias trong tài nguyên AccountRelationship giúp quản lý tốt hơn các cấu trúc tài khoản phức tạp. Ví dụ: các trang web thương mại điện tử sử dụng một bí danh do người dùng xác định thay vì mã nhận dạng nội bộ của người bán, chẳng hạn như mã tài khoản.

Hỗ trợ gRPC

Merchant API hỗ trợ gRPC và REST. Bạn có thể sử dụng gRPC cho Merchant API và REST cho Content API for Shopping cùng một lúc.

Thư viện ứng dụng Merchant API client libraries yêu cầu gRPC.

Để biết thêm thông tin, hãy xem bài viết Tổng quan về gRPC.

Khả năng tương thích

Hướng dẫn này mô tả những thay đổi chung áp dụng cho toàn bộ Merchant API.

Merchant API được thiết kế để hoạt động cùng với các tính năng hiện có của Content API for Shopping.

Ví dụ: bạn có thể sử dụng Merchant Inventories API cùng với quá trình triển khai hiện có Content API for Shopping phiên bản 2.1 products. Bạn có thể sử dụng Content API for Shopping để tải một sản phẩm địa phương mới lên (sản phẩm mà bạn bán trong một cửa hàng địa phương), sau đó sử dụng tài nguyên LocalInventory của Merchant Inventories API để quản lý thông tin trong cửa hàng cho sản phẩm đó.

Những điểm cải thiện so với Content API

Merchant API cải thiện Content API ở những khía cạnh sau:

Hãy xem xét kỹ hơn những thay đổi này.

Phiên bản và API phụ

Merchant API giới thiệu các khái niệm về phiên bảnAPI phụ. Thiết kế mô-đun của API này giúp cải thiện khả năng sử dụng bằng cách cho phép bạn tập trung vào các API phụ mà bạn cần và giúp việc di chuyển trong tương lai sang các phiên bản mới hơn trở nên dễ dàng hơn. Tính năng phiên bản sẽ được áp dụng cho URL yêu cầu của bạn. Chiến lược này tương tự như trải nghiệm API Google Ads.

Yêu cầu mạnh mẽ hơn

Yêu cầu URL Merchant API cần có nhiều tham số hơn để gọi Merchant API. Điều này bao gồm tài nguyên, phiên bản, tên (mã nhận dạng) và phương thức (phương thức không chuẩn). Để biết thêm thông tin về vấn đề này, hãy xem bài viết Mã nhận dạng tài khoản và sản phẩm và các ví dụ.

Nguyên tắc AIP cho mã nhận dạng

Mặc dù Content API for Shopping sử dụng mã nhận dạng để xác định tài nguyên (ví dụ: merchantId, productId), nhưng Merchant API sử dụng mã nhận dạng name để phù hợp với AIP (xem nguyên tắc cải thiện API).

Mã nhận dạng {name} bao gồm mã nhận dạng tài nguyên và thành phần mẹ của mã nhận dạng đó (hoặc có thể là nhiều thành phần mẹ), sao cho {name} bằng accounts/{account}/products/{product}

Tất cả các lệnh gọi đọc và ghi đều trả về trường name dưới dạng mã nhận dạng tài nguyên.

{name} cũng bao gồm các mã nhận dạng bộ sưu tập accounts/products/.

Merchant API sử dụng {account} để tham chiếu đến Mã truy cập Merchant Center và {product} để tham chiếu đến mã nhận dạng sản phẩm.

Ví dụ: hãy triển khai phương thức getName() để truy xuất name từ một tài nguyên và lưu trữ kết quả đầu ra dưới dạng một biến thay vì tự tạo name từ mã nhận dạng người bán và tài nguyên.

Dưới đây là ví dụ về cách sử dụng trường name trong các lệnh gọi:

   POST https://merchantapi.googleapis.com/inventories/v1/{PARENT}/regionalInventories:insert

Bảng này cho biết cách thay đổi yêu cầu products.get của Content API for Shopping:

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}

Để biết thêm thông tin, hãy xem bài viết Thay đổi mã nhận dạng.

Ví dụ khác: việc truy xuất một sản phẩm có mã nhận dạng en~US~1234 từ Mã truy cập Merchant Center 4321 bằng Merchant API sẽ có dạng như sau:

    GET
    https://merchantapi.googleapis.com/products/v1/accounts/4321/products/online~en~US~1234

trong đó {name} bằng accounts/4321/products/en~US~1234. Trường tên mới này được trả về dưới dạng mã nhận dạng tài nguyên cho tất cả các lệnh gọi đọc và ghi trong Merchant API.

Trong Content API for Shopping, dấu hai chấm (:) biểu thị dấu phân cách trong tên sản phẩm, trong khi trong Merchant API, dấu ngã (~) thực hiện chức năng này. Mã nhận dạng Merchant API không chứa phần channel.

Ví dụ: mã nhận dạng sản phẩm trong Content API for Shopping:

channel:contentLanguage:feedLabel:offerId.

trong Merchant API sẽ trở thành:

contentLanguage~feedLabel~offerId.

Trường mẹ cho tài nguyên con

Trong Merchant API, tất cả các tài nguyên con đều có trường parent. Bạn có thể sử dụng trường parent để chỉ định {name} của tài nguyên nhằm chèn tài nguyên con vào, thay vì truyền toàn bộ tài nguyên mẹ. Bạn cũng có thể sử dụng trường parent với list

Ví dụ: để liệt kê kho hàng tại địa phương cho một sản phẩm nhất định, hãy chỉ định của sản phẩm name trong trường parent cho phương thức list. Trong trường hợp này, product đã cho là parent của các tài nguyên LocalInventory được trả về.

    GET
    https://merchantapi.googleapis.com/inventories/v1/{parent}/localInventories

Để truy xuất tất cả kho hàng tại địa phương cho sản phẩm en~US~1234' và tài khoản 4321 yêu cầu sẽ có dạng

    GET
    https://merchantapi.googleapis.com/inventories/v1/accounts/4321/products/online~en~US~1234/localInventories</code>

Thành phần mẹ là accounts/{account}/products/{product}. Xin lưu ý rằng trong trường hợp này tài nguyên localInventories có 2 thành phần mẹ được đưa vào mã nhận dạng tên (accounts/products/), vì tài khoản là thành phần mẹ của tài nguyên sản phẩm.

Enum phổ biến

Việc sử dụng enum phổ biến giúp mang lại tính nhất quán hơn.

Trường Destination.DestinationEnum chỉ định các nền tảng mà bạn muốn hiển thị tài nguyên. DestinationEnum liệt kê tất cả các giá trị có sẵn cho tính năng nhắm mục tiêu theo đích đến và được hợp nhất trên các API phụ, ví dụ: cho các thuộc tínhkhuyến mãi.

Trường ReportingContext.ReportingContextEnum đại diện cho ngữ cảnh mà các vấn đề về tài khoản và sản phẩm của bạn áp dụng. Trường này được sử dụng trên các phương thức báo cáo (ví dụ: cho IssueSeverityPerReportingContext).

Khả năng tương thích ngược

Khi bạn bắt đầu sử dụng Merchant API, quá trình tích hợp Content API for Shopping hiện có sẽ tiếp tục hoạt động mà không bị gián đoạn. Để biết thêm thông tin, hãy xem Khả năng tương thích.

Sau khi di chuyển các API phụ sang Merchant API, bạn chỉ nên sử dụng Merchant API cho các API phụ đã di chuyển.

Tính năng có sẵn của lệnh gọi quy trình từ xa (gRPC)

gRPC là cách mới được đề xuất để tích hợp với Merchant API.

Các ưu điểm của phương thức này bao gồm:

Tính năng phân lô tuỳ chỉnh trở thành tính năng phân lô tích hợp

Tính năng phân lô hoạt động hiệu quả hơn khi bạn sử dụng các lệnh gọi không đồng bộ. Tìm hiểu thêm về cách sử dụng các lệnh gọi song song để đạt được tính năng phân lô trong Merchant API và cách để Tái cấu trúc mã cho các yêu cầu đồng thời.

Để giúp đẩy nhanh quá trình di chuyển, bạn nên sử dụng thư viện ứng dụng.

Merchant API không hỗ trợ phương thức customBatch có trong Content API for Shopping. Thay vào đó, hãy xem bài viết Gửi nhiều yêu cầu cùng một lúc hoặc thực thi các lệnh gọi của bạn một cách không đồng bộ.

Mẫu Java sau đây minh hoạ cách chèn dữ liệu đầu vào sản phẩm:

   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);
  }
}

Nếu bạn sử dụng customBatch trong Content API và cần tính năng này cho Merchant API, hãy cho chúng tôi biết lý do trong ý kiến phản hồi của bạn.

Các tính năng độc quyền

Các tính năng trong tương lai sẽ chỉ xuất hiện trong Merchant API. (Sẽ có một vài trường hợp ngoại lệ, chẳng hạn như đặc tả nguồn cấp dữ liệu hằng năm năm 2025.)

Các tính năng dành riêng cho Merchant API bao gồm

  • API bài đánh giá. Sử dụng API bài đánh giá để triển khai và quản lý điểm xếp hạng sản phẩm và cửa hàng. Để biết thêm thông tin, hãy xem bài viết Bài đánh giá người bánBài đánh giá sản phẩm.
  • Thông báo: Đăng ký để nhận thông báo đẩy về những thay đổi đối với dữ liệu sản phẩm của tài khoản.

Giá

Sau đây là những thay đổi đối với Price trong gói Merchant Common:

Content API for Shopping Merchant API
Trường số tiền value:string amountMicros:int64
Trường đơn vị tiền tệ currency:string currencyCode:string

Số tiền Price hiện được ghi lại theo đơn vị một phần triệu, trong đó 1 triệu đơn vị một phần triệu tương đương với đơn vị tiêu chuẩn của đơn vị tiền tệ.

Trong Content API for Shopping, Price là một số thập phân ở dạng chuỗi.

Tên trường số tiền đã thay đổi từ value thành amountMicros

Tên trường đơn vị tiền tệ đã thay đổi từ currency thành currencyCode. Định dạng này vẫn là ISO 4217.

Thông báo và thông tin cập nhật mới nhất

Để biết thông tin cập nhật chi tiết hơn, hãy xem ghi chú phát hành dành riêng cho từng API phụ. Để biết thông tin cập nhật thường xuyên hơn về Merchant API, hãy xem thông tin cập nhật mới nhất của chúng tôi.

Để biết thêm thông tin cụ thể và tìm hiểu thêm về Merchant API, hãy xem bài viết Tổng quan về trang web dành cho nhà phát triển và hướng dẫn di chuyển tổng thể để biết thêm thông tin.

Xem bài viết Thiết kế Merchant API để biết thông tin chi tiết về Merchant API và các API phụ của API này.