Content API for Shopping에서 Merchant API로 이전

이 가이드에서는 Content API for Shopping에서 비즈니스 데이터 관리를 위한 Merchant API로 이전하는 과정을 설명합니다.

이 가이드를 사용하여 기존 Content API for Shopping 구현을 Merchant API로 이전할 수 있습니다. Merchant API 및 하위 API의 세부정보에 대한 자세한 내용은 Merchant API 설계를 참고하세요.

시작하기

Merchant API를 사용하려면 요청 URL을 다음 형식으로 변경하세요.

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

Merchant API를 사용하려면 다음과 같이 개발자 등록 방법을 사용하여 판매자 센터 계정과 Google Cloud 프로젝트를 연결해야 합니다.

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

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

자세한 내용은 빠른 시작 가이드 및 Merchant API 참조를 확인하세요.

Merchant API (베타)의 최신 업데이트를 참고하세요.

Content API for Shopping에 비해 개선된 점

Merchant API를 사용하면 판매자 센터의 워크플로를 자동화하고 간소화할 수 있으며 Content API for Shopping보다 향상된 기능을 제공합니다.

주요 사용 사례

  • 자동 계정 관리
  • 자동 제품 관리
  • 자동 인벤토리 관리
  • 맞춤 보고서

주요 개선 영역:

변경사항

  • 최대 pageSize이 API 호출당 250개 행에서 1,000개 행으로 증가했습니다.
  • DataSources 생성 후 제품 삽입, 프로모션, 제품 리뷰, 판매자 리뷰에 발생했던 지연이 수정되었습니다.

예정된 사항:

  • DataSources 및 제품의 채널 필드 지원 중단 및 향후 삭제
  • Reporting 하위 APIproductView 표에서 clickPotentialRank의 업데이트된 정의가 출시됩니다. * clickPotential에 기반한 제품 순위가 1~1000 사이의 값으로 정규화됩니다.
    • clickPotentialRank가 낮은 제품은 검색어 조건을 충족하는 판매자의 제품 중 클릭 가능성이 가장 높습니다. 이는 2025년 7월 1일에 출시될 수 있는 호환성이 깨지지 않는 변경사항입니다.
  • AccountRelationship 리소스의 AccountIdAlias를 사용하면 복잡한 계정 구조를 더 잘 관리할 수 있습니다. 예를 들어 마켓에서는 계정 ID와 같은 판매자의 내부 ID 대신 사용자 정의 별칭을 사용합니다.

gRPC 지원

Merchant API는 gRPC 및 REST를 지원합니다. 판매자 API에는 gRPC를 사용하고 Content API for Shopping에는 REST를 동시에 사용할 수 있습니다.

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에는 버전 관리하위 API의 개념이 도입되었습니다. 모듈식 설계로 필요한 하위 API에 집중할 수 있고 향후 최신 버전으로 더 쉽게 이전할 수 있어 사용 편의성이 향상됩니다. 버전 관리는 요청 URL에 적용됩니다.이 전략은 Google Ads API 환경과 유사합니다.

더 강력한 요청

판매자 API URL 요청에는 판매자 API를 호출하기 위한 매개변수가 더 필요합니다. 여기에는 리소스, 버전, 이름 (식별자) 및 메서드 (비표준 메서드)가 포함됩니다. 자세한 내용은 계정 및 제품 식별자예시를 참고하세요.

식별자용 AIP 원칙

Content API for Shopping은 ID를 사용하여 리소스를 식별하지만 (예: merchantId, productId) Merchant API는 AIP에 맞추기 위해 name 식별자를 사용합니다 (API 개선 원칙 참고).

{name} 식별자에는 리소스 식별자와 상위 요소 (또는 여러 상위 요소)가 포함되므로 {name}accounts/{account}/products/{product}와 같습니다.

모든 읽기 및 쓰기 호출은 name 필드를 리소스 식별자로 반환합니다.

{name}에는 컬렉션 식별자 accounts/products/도 포함됩니다.

Merchant API는 {account}를 사용하여 판매자 센터 ID를 참조하고 {product}를 사용하여 제품 식별자를 참조합니다.

예를 들어 getName() 메서드를 구현하여 리소스에서 name을 가져오고 판매자 및 리소스 ID에서 직접 name을 구성하는 대신 출력을 변수로 저장합니다.

다음은 호출에서 name 필드를 사용하는 방법의 예입니다.

   POST https://merchantapi.googleapis.com/inventories/v1beta/{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/v1beta/{name}

자세한 내용은 식별자 변경사항을 참고하세요.

또 다른 예로 Merchant API를 사용하여 판매자 센터 ID 4321에서 식별자가 online~en~US~1234인 제품을 가져오는 것은 다음과 같습니다.

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

여기서 {name}accounts/4321/products/online~en~US~1234와 같습니다. 이 새로운 이름 필드는 Merchant API의 모든 읽기 및 쓰기 호출에 대한 리소스 식별자로 반환됩니다.

Content API for Shopping에서는 콜론 (:)이 제품 이름의 구분 기호를 나타내지만 Merchant API에서는 물결표 (~)가 이 기능을 실행합니다.

예를 들어 Content API for Shopping의 제품 ID는 다음과 같습니다.

channel:contentLanguage:feedLabel:offerId.

Merchant Center API에서 다음과 같이 변경됩니다.

channel~contentLanguage~feedLabel~offerId.

하위 리소스의 상위 필드

Merchant API에서 모든 하위 리소스에는 parent 필드가 있습니다. 전체 상위 리소스를 전달하는 대신 parent 필드를 사용하여 하위를 삽입할 리소스의 {name}를 지정할 수 있습니다. 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</code>

상위 요소는 accounts/{account}/products/{product}입니다. 이 경우 계정이 제품 리소스의 상위 요소이므로 localInventories 리소스에는 이름 식별자 (accounts/products/)에 포함된 두 개의 상위 요소가 있습니다.

일반적인 enum

일반적인 enum을 사용하면 일관성이 높아집니다.

Destination.DestinationEnum 필드는 리소스를 표시할 구매 경로를 지정합니다. DestinationEnum는 대상 타겟팅에 사용할 수 있는 모든 값을 나열하며 프로모션 속성과 같은 하위 API에서 통합됩니다.

ReportingContext.ReportingContextEnum 필드는 계정 및 제품 문제에 적용되는 컨텍스트를 나타냅니다. 이 필드는 보고 방법 전반에서 사용됩니다 (예: IssueSeverityPerReportingContext).

이전 버전과의 호환성

Merchant API를 사용하기 시작해도 기존 Content API for Shopping 통합은 중단 없이 계속 작동합니다. 자세한 내용은 호환성을 참고하세요.

하위 API를 판매자 API로 이전한 후에는 이전된 하위 API에 판매자 API만 사용하는 것이 좋습니다.

리모트 프로시져 콜 (gRPC) 사용 가능 여부

gRPC는 Merchant API와 통합하는 데 권장되는 새로운 방법입니다.

장점은 다음과 같습니다.

맞춤 일괄 처리가 내장 일괄 처리로 변경됨

비동기 호출을 사용하면 일괄 처리가 더 효율적으로 실행됩니다. 병렬 호출을 사용하여 Merchant API에서 일괄 처리를 구현하는 방법과 동시 요청을 위한 코드 리팩터링 방법을 자세히 알아보세요.

마이그레이션을 신속하게 진행하려면 클라이언트 라이브러리를 사용하는 것이 좋습니다.

판매자 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에 이 기능이 필요한 경우 의견에 이유를 알려주세요.

독점적인 기능

향후 기능은 Merchant API에만 표시됩니다. (2025년 연간 피드 사양과 같은 몇 가지 예외가 있습니다.)

Merchant API 전용 기능에는 다음이 포함됩니다.

  • Reviews API 리뷰를 사용하여 제품 및 매장 평점을 구현하고 관리합니다. 자세한 내용은 판매자 리뷰제품 리뷰를 참고하세요.
  • 알림: 계정의 제품 데이터 변경사항에 대한 푸시 알림을 받도록 신청합니다.

가격

판매자 공통 패키지에서 Price에 변경된 사항은 다음과 같습니다.

Content API for Shopping Merchant API
금액 필드 value:string amountMicros:int64
통화 필드 currency:string currencyCode:string

이제 Price 금액이 마이크로 단위로 기록되며, 1백만 마이크로는 통화의 표준 단위와 같습니다.

Content API for Shopping에서 Price은 문자열 형식의 십진수였습니다.

금액 필드 이름이 value에서 amountMicros으로 변경됨

통화 필드 이름이 currency에서 currencyCode으로 변경되었습니다. 형식은 계속 ISO 4217입니다.

최신 업데이트 및 공지사항

더 세부적인 업데이트는 각 하위 API 관련 출시 노트를 참고하세요. 정기적인 집계 판매자 API 업데이트에 대한 자세한 내용은 최신 업데이트를 참고하세요.

자세한 내용과 Merchant API에 대해 자세히 알아보려면 개발자 사이트 개요와 전체 이전 가이드를 참고하세요.

판매자 API 및 하위 API에 대한 자세한 내용은 판매자 API 설계를 참고하세요.