查看影响商家账号的问题

账号问题会影响商品的曝光度,以及您参与各种 Merchant Center 计划的能力。借助 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 通过 ListAccountIssuesRequest 中的 page_sizepage_token 参数支持分页。这样,您就可以以可管理的块检索问题。page_size 的最大值为 1000,默认值为 50。
  • 排序:API 返回的问题通常按严重程度和内部优先级排序,与它们在 Merchant Center 中的显示方式类似。请注意,该 API 不支持自定义排序。
  • 数据源:Accounts 子 API 从 Merchant Center 中“诊断”页面所用的同一后端检索数据。

检索账号的问题

如需列出账号问题,请向 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"
    }
  ]
}

列出特定账号的账号问题

此使用情形展示了如何检索给定 Merchant Center 账号的所有账号级问题。返回的信息可帮助您找出并解决影响账号效果和各种计划资格的问题。

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

Java

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"

列出高级账号的所有子账号的账号问题

如果您管理的是高级账号,可能需要检查所有子账号是否存在问题。此示例演示了如何列出子账号,然后针对每个子账号异步检索其账号问题。这种方法可高效处理多个账号。

Java

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.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 service settings using the credentials retrieved above.
    AccountsServiceSettings accountsServiceSettings =
        AccountsServiceSettings.newBuilder()
            .setCredentialsProvider(FixedCredentialsProvider.create(credential))
            .build();

    // 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 (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"
 ```