판매자 계정에 영향을 미치는 문제 보기

계정 문제는 제품 공개 상태와 다양한 판매자 센터 프로그램 참여 가능 여부에 영향을 미칩니다. Accounts 하위 API를 사용하면 판매자 계정에 영향을 미치는 문제 목록을 가져올 수 있습니다. 이렇게 하면 문제를 선제적으로 파악하고 해결할 수 있습니다.

쇼핑 광고무료 등록정보 정책을 준수해야 합니다. Google 쇼핑은 이러한 정책을 시행하고, 이러한 정책을 위반하는 콘텐츠나 행동이 발견되면 적절하게 대응할 권리를 보유합니다.

AccountIssue은 다음과 같은 세부정보를 제공합니다.

  • title: 문제의 요약입니다.
  • severity: 문제의 심각도입니다. 예를 들면 다음과 같습니다.
    • CRITICAL: 혜택이 게재되지 않도록 하는 문제입니다.
    • ERROR: 혜택에 영향을 미치거나 문제를 나타낼 수 있는 문제입니다.
    • SUGGESTION: 개선을 위한 권장사항입니다.
  • impactedDestinations: 문제의 영향을 받는 프로그램 (예: 쇼핑 광고 또는 무료 등록정보) 및 지역과 해당 맥락에서의 심각도입니다.
  • detail: 문제에 관한 추가 컨텍스트가 포함된 메시지
  • documentationUri: 문제를 해결하는 방법에 관한 고객센터 도움말 링크입니다.

특별 고려사항

  • 국제화 (i18n): 계정 문제를 나열할 때 요청에 language_code (예: 'en-US', 'fr-FR') 및 time_zone(예: 'America/Los_Angeles', 'Europe/Paris')를 지정할 수 있습니다. 이렇게 하면 문제 detail와 같은 응답의 사람이 읽을 수 있는 문자열이 적절하게 현지화되었는지 확인할 수 있습니다. 이러한 필드가 제공되지 않으면 API는 기본적으로 영어 ('en-US')와 'America/Los_Angeles' (태평양 표준시) 시간대를 사용합니다.
  • 페이지로 나누기: API는 ListAccountIssuesRequestpage_sizepage_token 매개변수를 통해 페이지로 나누기를 지원합니다. 이렇게 하면 관리 가능한 청크로 문제를 가져올 수 있습니다. 최대 page_size는 1, 000이고 기본값은 50입니다.
  • 순서: API에서 반환된 문제는 일반적으로 심각도와 내부 우선순위에 따라 정렬되며, 이는 판매자 센터에 표시되는 방식과 유사합니다. API는 맞춤 정렬을 지원하지 않습니다.
  • 데이터 소스: 계정 하위 API는 판매자 센터의 진단 페이지에서 사용하는 것과 동일한 백엔드에서 데이터를 가져옵니다.

계정의 문제 가져오기

계정 문제를 나열하려면 accounts.issues.list 메서드에 GET 요청을 전송합니다.

GET https://merchantapi.googleapis.com/accounts/v1/accounts/{ACCOUNT_ID}/issues?language_code=en-GB&time_zone.id=Europe/London&page_size=10

다음은 '방문 페이지가 작동하지 않음' 위반으로 인해 정지된 하위 계정의 샘플 응답입니다.

{
  "accountIssues": [
    {
      "name": "accounts/{ACCOUNT_ID}/issues/home-page-issue",
      "title": "Online store not confirmed",
      "severity": "CRITICAL",
      "impactedDestinations": [
        {
          "reportingContext": "SHOPPING_ADS",
          "impacts": [
            {
              "regionCode": "001",
              "severity": "CRITICAL"
            }
          ]
        }
      ],
      "detail": "The ownership of the online store must be verified through Merchant Center",
      "documentationUri": "https://support.google.com/merchants/answer/176793?hl=en-US"
    },
    {
      "name": "accounts/{ACCOUNT_ID}/issues/editorial-and-professional-standards-destination-url-down-policy",
      "title": "Landing page not working",
      "severity": "CRITICAL",
      "impactedDestinations": [
        {
          "reportingContext": "SHOPPING_ADS",
          "impacts": [
            {
              "regionCode": "ES",
              "severity": "CRITICAL"
            }
          ]
        },
        {
          "reportingContext": "DEMAND_GEN_ADS",
          "impacts": [
            {
              "regionCode": "ES",
              "severity": "CRITICAL"
            }
          ]
        },
        {
          "reportingContext": "VIDEO_ADS",
          "impacts": [
            {
              "regionCode": "ES",
              "severity": "CRITICAL"
            }
          ]
        }
      ],
      "detail": "Broken landing pages or broken links in your online store are not allowed",
      "documentationUri": "https://support.google.com/merchants/answer/12079604?hl=en-US"
    },
    {
      "name": "accounts/{ACCOUNT_ID}/issues/pending-phone-verification",
      "title": "Your phone number needs to be verified",
      "severity": "CRITICAL",
      "detail": "Verify your phone number to confirm your identity",
      "documentationUri": "https://support.google.com/merchants/answer/12471579?hl=en-US"
    },
    {
      "name": "accounts/{ACCOUNT_ID}/issues/pending-address-and-phone",
      "title": "Missing business address",
      "severity": "CRITICAL",
      "detail": "Provide a valid business address in Merchant Center",
      "documentationUri": "https://support.google.com/merchants/answer/12471579?hl=en-US"
    }
  ]
}

특정 계정의 계정 문제 나열

이 사용 사례에서는 지정된 판매자 센터 계정의 모든 계정 수준 문제를 가져오는 방법을 보여줍니다. 반환된 정보를 통해 계정의 실적과 다양한 프로그램의 자격 요건에 영향을 미치는 문제를 파악하고 해결할 수 있습니다.

AppsScript

/**
 * Lists all issues for a given Merchant Center account.
 */
function listAccountIssues() {
  // IMPORTANT:
  // Enable the Merchant API Accounts sub-API Advanced Service and call it
  // "MerchantApiAccounts"

  // Replace this with your Merchant Center ID.
  const accountId = '<MERCHANT_CENTER_ID>';

  // Construct the parent name
  const parent = 'accounts/' + accountId;

  try {
    console.log('Sending list Account Issues request');
    // Set pageSize to the maximum value (default: 50)
    const pageSize = 100;
    let pageToken;
    let count = 0;
    // Call the Account.Issues.list API method. Use the pageToken to iterate
    // through all pages of results.
    do {
      const response = MerchantApiAccounts.Accounts.Issues.list(parent, {pageSize, pageToken});
      for (const issue of response.accountIssues) {
        console.log(issue);
        count++;
      }
      pageToken = response.nextPageToken;
    } while (pageToken); // Exits when there is no next page token.
    console.log('The following count of Account Issues were returned: ', count);
  } catch (e) {
    console.log('ERROR!');
    console.log(e);
  }
}

자바

import com.google.api.gax.core.FixedCredentialsProvider;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.shopping.merchant.accounts.v1.AccountIssue;
import com.google.shopping.merchant.accounts.v1.AccountIssueServiceClient;
import com.google.shopping.merchant.accounts.v1.AccountIssueServiceClient.ListAccountIssuesPagedResponse;
import com.google.shopping.merchant.accounts.v1.AccountIssueServiceSettings;
import com.google.shopping.merchant.accounts.v1.AccountName;
import com.google.shopping.merchant.accounts.v1.ListAccountIssuesRequest;
import shopping.merchant.samples.utils.Authenticator;
import shopping.merchant.samples.utils.Config;

/**
 * This class demonstrates how to list all the account issues of an account.
 *
 * <p>If you want to query the account issues of all the sub-accounts of an advanced account, see
 * ListAdvancedAccountIssuesSampleAsync.
 */
public class ListAccountIssuesSample {

  public static void listAccountIssues(Config config) throws Exception {

    // Obtains OAuth token based on the user's configuration.
    GoogleCredentials credential = new Authenticator().authenticate();

    // Creates service settings using the credentials retrieved above.
    AccountIssueServiceSettings accountIssueServiceSettings =
        AccountIssueServiceSettings.newBuilder()
            .setCredentialsProvider(FixedCredentialsProvider.create(credential))
            .build();

    // Calls the API and catches and prints any network failures/errors.
    try (AccountIssueServiceClient accountIssueServiceClient =
        AccountIssueServiceClient.create(accountIssueServiceSettings)) {

      // Gets the account ID from the config file.
      String accountId = config.getAccountId().toString();

      // Creates account name to identify account.
      String name = AccountName.newBuilder().setAccount(accountId).build().toString();
      ListAccountIssuesRequest request =
          ListAccountIssuesRequest.newBuilder().setParent(name).build();

      System.out.println("Sending list account issues request:");
      ListAccountIssuesPagedResponse response =
          accountIssueServiceClient.listAccountIssues(request);

      int count = 0;

      // Iterates over all rows in all pages and prints the issue in each row.
      // Automatically uses the `nextPageToken` if returned to fetch all pages of data.
      for (AccountIssue accountIssue : response.iterateAll()) {
        System.out.println(accountIssue);
        count++;
      }
      System.out.print("The following count of account issues were returned: ");
      System.out.println(count);
    } catch (Exception e) {
      System.out.println("An error has occured: ");
      System.out.println(e);
    }
  }

  public static void main(String[] args) throws Exception {
    Config config = Config.load();
    listAccountIssues(config);
  }
}

PHP

use Google\ApiCore\ApiException;
use Google\Shopping\Merchant\Accounts\V1\Client\AccountIssueServiceClient;
use Google\Shopping\Merchant\Accounts\V1\ListAccountIssuesRequest;

/**
 * Lists all the account issues of an account.
 */
class ListAccountIssues
{
    /**
     * A helper function to create the parent string.
     *
     * @param array $accountId
     *      The account.
     *
     * @return string The parent has the format: `accounts/{account_id}`
     */
    private static function getParent($accountId)
    {
        return sprintf("accounts/%s", $accountId);
    }

    /**
     * Lists all the account issues for a given Merchant Center account.
     *
     * @param array $config
     *      The configuration data used for authentication and getting the acccount ID.
     * @return void
     */
    public static function listAccountIssuesSample($config): void
    {
        // Gets the OAuth credentials.
        $credentials = Authentication::useServiceAccountOrTokenFile();

        // Creates options config.
        $options = ['credentials' => $credentials];

        // Creates a client.
        $accountIssueServiceClient = new AccountIssueServiceClient($options);

        // Creates parent.
        $parent = self::getParent($config['accountId']);

        // Creates the request.
        $request = new ListAccountIssuesRequest(['parent' => $parent]);

        // Calls the API and catches and prints any network failures/errors.
        try {
            print "Sending list account issues request:\n";
            $response = $accountIssueServiceClient->listAccountIssues($request);

            $count = 0;
            // Iterates over all elements and prints the issue in each row.
            foreach ($response->iterateAllElements() as $accountIssue) {
                print_r($accountIssue);
                $count++;
            }
            print "The following count of account issues were returned: ";
            print $count . "\n";
        } catch (ApiException $e) {
            print "An error has occured: \n";
            print $e->getMessage() . "\n";
        }
    }

    /**
     * Helper to execute the sample.
     *
     * @return void
     */
    public function callSample(): void
    {
        $config = Config::generateConfig();

        // Lists the account issues.
        self::listAccountIssuesSample($config);
    }
}

// Run the script
$sample = new ListAccountIssues();
$sample->callSample();

Python

from examples.authentication import configuration
from examples.authentication import generate_user_credentials
from google.shopping.merchant_accounts_v1 import AccountIssueServiceClient
from google.shopping.merchant_accounts_v1 import ListAccountIssuesRequest

_ACCOUNT = configuration.Configuration().read_merchant_info()
_PARENT = f"accounts/{_ACCOUNT}"


def list_account_issues():
  """Lists all the account issues of an account."""

  # Gets OAuth Credentials.
  credentials = generate_user_credentials.main()

  # Creates a client.
  client = AccountIssueServiceClient(credentials=credentials)

  request = ListAccountIssuesRequest(parent=_PARENT)

  print("Sending list account issues request:")

  # Makes the request and catches and prints any error messages.
  try:
    response = client.list_account_issues(request=request)
    count = 0

    for account_issue in response:
      print(account_issue)
      count += 1
    print("The following count of account issues were returned: ")
    print(count)

  except RuntimeError as e:
    print("An error has occured: ")
    print(e)


if __name__ == "__main__":
  list_account_issues()

cURL

curl -X GET \
"https://merchantapi.googleapis.com/accounts/v1/accounts/{ACCOUNT_ID}/issues?language_code=en-US&time_zone.id=America/Los_Angeles&page_size=50" \
--header "Authorization: Bearer {YOUR_ACCESS_TOKEN}" \
--header "Accept: application/json"

고급 계정의 모든 하위 계정에 대한 계정 문제 나열

고급 계정을 관리하는 경우 모든 하위 계정에서 문제를 확인해야 할 수 있습니다. 이 예에서는 하위 계정을 나열한 다음 각 하위 계정의 계정 문제를 비동기적으로 가져오는 방법을 보여줍니다. 이 방법은 여러 계정을 처리하는 데 효율적입니다.

자바

import static com.google.api.core.ApiFutures.transform;

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.accounts.v1.AccountIssueServiceClient;
import com.google.shopping.merchant.accounts.v1.AccountIssueServiceSettings;
import com.google.shopping.merchant.accounts.v1.AccountName;
import com.google.shopping.merchant.accounts.v1.AccountsServiceClient;
import com.google.shopping.merchant.accounts.v1.AccountsServiceClient.ListSubAccountsPagedResponse;
import com.google.shopping.merchant.accounts.v1.AccountsServiceSettings;
import com.google.shopping.merchant.accounts.v1.ListAccountIssuesRequest;
import com.google.shopping.merchant.accounts.v1.ListAccountIssuesResponse;
import com.google.shopping.merchant.accounts.v1.ListSubAccountsRequest;
import java.io.IOException;
import java.util.AbstractMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
import shopping.merchant.samples.utils.Authenticator;
import shopping.merchant.samples.utils.Config;

/**
 * This class demonstrates how to list the account issues of all the sub-accounts of an advanced
 * account.
 */
public class ListAdvancedAccountIssuesAsyncSample {

  /** Returns the list of issues for the given account. */
  private static ApiFuture<ListAccountIssuesResponse> getAccountIssues(
      AccountIssueServiceClient accountIssueServiceClient, String account) {
    return accountIssueServiceClient
        .listAccountIssuesCallable()
        .futureCall(ListAccountIssuesRequest.newBuilder().setParent(account).build());
  }

  /**
   * Returns a map of account issues where key is the sub-account resource name and the value is the
   * list of issues for each sub-account. Takes the API clients and the name of the advanced account
   * as input.
   */
  private static ApiFuture<Map<String, ListAccountIssuesResponse>> getSubAccountIssues(
      AccountsServiceClient accountsServiceClient,
      AccountIssueServiceClient accountIssueServiceClient,
      String advancedAccount)
      throws IOException {

    // Creates a direct executor to run the transform functions.
    Executor executor = MoreExecutors.directExecutor();

    // The parent has the format: accounts/{account}
    ListSubAccountsRequest request =
        ListSubAccountsRequest.newBuilder().setProvider(advancedAccount).build();
    System.out.println("Sending list subaccounts request:");

    // Lists all sub-accounts of the advanced account.
    ListSubAccountsPagedResponse listSubAccountsResponse =
        accountsServiceClient.listSubAccounts(request);

    // Iterates over all subAccounts and lists account issues for each.
    // Automatically uses the `nextPageToken` if returned to fetch all pages of data.
    List<ApiFuture<AbstractMap.SimpleEntry<String, ListAccountIssuesResponse>>>
        accountIssuesFutures =
            StreamSupport.stream(listSubAccountsResponse.iterateAll().spliterator(), false)
                .map(
                    account ->
                        transform(
                            getAccountIssues(accountIssueServiceClient, account.getName()),
                            (ListAccountIssuesResponse response) ->
                                new AbstractMap.SimpleEntry<>(account.getName(), response),
                            executor))
                .collect(Collectors.toList());

    // Collects all the responses into a single future.
    ApiFuture<List<AbstractMap.SimpleEntry<String, ListAccountIssuesResponse>>> accountIssuesList =
        ApiFutures.allAsList(accountIssuesFutures);

    // Transforms the list of responses into a map.
    return transform(
        accountIssuesList,
        (List<AbstractMap.SimpleEntry<String, ListAccountIssuesResponse>> list) ->
            list.stream()
                .collect(
                    Collectors.toMap(
                        AbstractMap.SimpleEntry::getKey,
                        AbstractMap.SimpleEntry::getValue,
                        (a, b) -> a)),
        executor);
  }

  public static void listAccountIssues(Config config) throws Exception {

    // Obtains OAuth token based on the user's configuration.
    GoogleCredentials credential = new Authenticator().authenticate();

    // Gets the account ID from the config file.
    // Make sure to use the advanced account ID here, otherwise the API will return an error.
    String accountId = config.getAccountId().toString();

    // Creates account name to identify account.
    String parent = AccountName.newBuilder().setAccount(accountId).build().toString();

    // 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.
    AccountsServiceSettings accountsServiceSettings =
        AccountsServiceSettings.newBuilder()
            .setCredentialsProvider(FixedCredentialsProvider.create(credential))
            .setTransportChannelProvider(channelProvider)
            .build();

    // Creates service settings using the credentials retrieved above.
    AccountIssueServiceSettings accountIssueServiceSettings =
        AccountIssueServiceSettings.newBuilder()
            .setCredentialsProvider(FixedCredentialsProvider.create(credential))
            .setTransportChannelProvider(channelProvider)
            .build();

    // Calls the API and catches and prints any network failures/errors.
    try (AccountsServiceClient accountsServiceClient =
            AccountsServiceClient.create(accountsServiceSettings);
        AccountIssueServiceClient accountIssueServiceClient =
            AccountIssueServiceClient.create(accountIssueServiceSettings)) {

      ApiFuture<Map<String, ListAccountIssuesResponse>> subAccountIssues =
          getSubAccountIssues(accountsServiceClient, accountIssueServiceClient, parent);

      ApiFutures.addCallback(
          subAccountIssues,
          new ApiFutureCallback<Map<String, ListAccountIssuesResponse>>() {
            @Override
            public void onSuccess(Map<String, ListAccountIssuesResponse> results) {
              System.out.println("Account Issues");
              for (Entry<String, ListAccountIssuesResponse> entry : results.entrySet()) {
                System.out.println("Issues for account " + entry.getKey());
                System.out.println(entry.getValue());
              }
            }

            @Override
            public void onFailure(Throwable throwable) {
              System.out.println(throwable);
            }
          },
          MoreExecutors.directExecutor());
    } catch (Exception e) {
      System.out.println("An error has occured: ");
      System.out.println(e);
    }
  }

  public static void main(String[] args) throws Exception {
    Config config = Config.load();
    listAccountIssues(config);
  }
}

cURL

고급 계정의 하위 계정 문제를 나열하려면 먼저 하위 계정을 나열하고 (예: accounts.listSubaccounts 사용) 각 하위 계정 ID를 반복하여 accounts.issues.list 메서드를 호출합니다. 다음 curl 예시에서는 단일 하위 계정의 문제를 나열하는 방법을 보여줍니다. 각 하위 계정 ID에 대해 이 요청을 반복합니다.

 curl -X GET \
 "https://merchantapi.googleapis.com/accounts/v1/accounts/{SUB_ACCOUNT_ID}/issues?language_code=en-US&time_zone.id=America/Los_Angeles&page_size=50" \
 --header "Authorization: Bearer {YOUR_ACCESS_TOKEN}" \
 --header "Accept: application/json"
 ```