App Store Review API 开发者指南

借助 App Store Review API,通过“Play 上的第三方应用商店”计划在 Google Play 上注册的第三方应用商店,可以为其商店中托管的应用提供所需的详细信息。这包括应用元数据、商品详情、APK 二进制文件和政策合规性声明。

如需查看端点、方法和资源架构的完整列表,请参阅 App Store Review API 参考文档。

准备工作

您必须先完成主要的使用入门指南,设置 API 访问权限、服务凭证和 Google Cloud 项目,然后才能调用 App Store Review API。App Store Review API 允许每个应用商店每分钟最多发送 300 个请求。


API 设计与架构

App Store Review API 基于原子快照模式运行。该 API 并不使用事务性会话;您需要先逐个上传文件,随后通过单次原子调用提交完整状态:

  1. 您需要逐次发起直接调用,分别上传各个文件和资源(APK、图片和政策文件)。
  2. 您需要缓存这些文件对应的返回 ID。
  3. 您需要发起一个最终的 UpdateAppStoreHostedApp 请求,以原子方式提交整个托管应用的状态。

1. 注册

如需注册托管应用,请调用 createappstorehostedapp 方法,并指定应用的软件包名称和商店的软件包名称。 如需详细了解请求和响应架构,请参阅 API 参考文档。


2. 二进制文件和资源上传

注册托管应用后,您必须使用专门的上传端点上传其资源:

资源缓存和重用

为优化带宽和性能,请勿重新上传相同的资源。 返回的所有 apkId、imageId 和 fileId 令牌都是持久的。您可以将这些 ID 缓存在自己的后端数据库中,以便在后续的托管应用更新中重复使用。例如,如果您要更新托管应用的说明,但应用图标和屏幕截图保持不变,请在下一次更新调用中使用缓存的 imageId 令牌。


3. 组装并提交

成功上传所有资源并检索到各自的 ID 后,您必须组装完整的托管应用状态,并使用 updateappstorehostedapp 方法提交该状态。此方法接受托管应用详情、本地化商店详情、有效 APK 集和安全声明的完整原子表示形式。

此调用将使用请求中描述的新状态,替换原有的任何活跃状态。

请求正文示例

以下是一个贴近实际且语法正确的 JSON 请求正文,展示了所有关键元素:

{
  "appStorePackageName": "com.example.thirdparty.store",
  "packageName": "com.example.hostedapp.game",
  "appDetails": {
    "developerName": "Adventure Games Studio Ltd.",
    "contactEmail": "support@adventuregames.example.com",
    "developerWebsite": "https://adventuregames.example.com"
  },
  "activeLocalizedStoreListings": [
    {
      "languageCode": "en-US",
      "appName": "Super Quest Legends",
      "shortDescription": "An epic fantasy RPG adventure.",
      "fullDescription": "Super Quest Legends is an immersive action RPG featuring real-time battles, customizable classes, and a deep fantasy narrative. Journey through a magical realm, fight epic bosses, and team up with friends in dungeon raids.",
      "appIconId": "987123",
      "screenshotId": [
        "102938",
        "475869",
        "384756"
      ],
      "videoLink": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
    },
    {
      "languageCode": "es-ES",
      "appName": "Super Quest Leyendas",
      "shortDescription": "Una aventura épica de RPG fantástico.",
      "fullDescription": "Super Quest Leyendas es un RPG de acción inmersivo con batallas en tiempo real, clases personalizables y una profunda narrativa de fantasía. Viaja a través de un reino mágico, lucha contra jefes épicos y únete a amigos en incursiones.",
      "appIconId": "987123",
      "screenshotId": [
        "102938",
        "475869",
        "384756"
      ]
    }
  ],
  "activeApks": {
    "activeApkSets": [
      {
        "baseApkId": "554433"
      },
      {
        "baseApkId": "990011"
      }
    ]
  },
  "policyDeclarations": [
    {
      "declarationId": "POLICY_DECLARATION_ID_TARGET_AUDIENCE_CONTENT",
      "responses": [
        {
          "questionId": "POLICY_QUESTION_ID_TAC_TARGET_AGE_GROUPS",
          "multipleChoiceResponse": {
            "values": [
              "POLICY_RESPONSE_CHOICE_ID_TAC_AGE_EIGHTEEN_AND_ABOVE"
            ]
          }
        },
        // ... other responses for TAC
      ]
    },
    {
      "declarationId": "POLICY_DECLARATION_ID_ADVERTISING_ID",
      "responses": [
        {
          "questionId": "POLICY_QUESTION_ID_AD_ID_IS_USED",
          "booleanResponse": {
            "value": false
          }
        }
        // ... other responses for AD_ID
      ]
    }
    // ... other declarations
  ]
}

政策声明

使用 API 提交或更新应用信息时,您必须填写所有必填政策声明。

声明要求

需要提交的声明类型如下:

所有应用均需填写(用于确认是否需要补充其他声明):

  1. 健康类应用:请告知我们应用使用了哪些健康类功能,以帮助我们了解应用必须符合“健康类应用”政策中的哪些要求。
  2. 涉及金融产品和服务:如果应用涉及金融产品和服务,则可能需要遵守某些国家或地区的特定法规。请提交应用中涉及金融产品和服务的最新准确详细信息,这有助于我们确保由适当的团队审核您提交的内容。
  3. 广告 ID:帮助我们了解应用是否使用了广告 ID。
  4. 测试凭证(登录详细信息):如果应用的任何部分因登录详细信息、会员身份、地理位置或其他身份验证方式而受限,请提供有关如何访问这些部分的说明。
  5. 隐私权政策:指向应用隐私权政策的链接以及有关该政策的详细信息。
  6. 目标受众群体和内容:您必须声明应用的目标年龄段以及与应用内容相关的其他信息。这有助于确保专为儿童设计的应用安全无害且适合儿童使用。
  7. 广告:您必须告知我们应用是否包含广告。

特定应用需填写:

  1. 政府应用:请说明该应用是否供任何形式的政府机构使用。这包括国家/地区级、州/省级、市级政府机构以及当地权力机构。这有助于我们确保由适当的团队审核您提交的内容。如果未填写此声明,该应用将被视为非政府应用。
  2. 儿童安全标准:“社交”类或“约会交友”类应用必须填写此声明。社交类或约会交友类应用必须提供已发布的安全标准和联系信息,以符合我们的“儿童安全标准”政策。
  3. 新闻和杂志应用:“新闻和杂志”类应用必须填写此声明。请提供新闻和杂志应用的详细信息,确保应用背后的运营实体透明公开。

API 请求结构

政策声明在 UpdateAppStoreHostedAppRequest 正文中的 policyDeclarations 数组内提供。 此数组中的每一项都是一个 AppStoreAppPolicyDeclaration 对象。

AppStoreAppPolicyDeclaration 对象:

  • declarationId(字符串,必需):政策声明的唯一标识符(例如 POLICY_DECLARATION_ID_FINANCE、POLICY_DECLARATION_ID_TARGET_AUDIENCE_CONTENT)。
  • responses(PolicyResponse 数组,必需):该特定声明中各问题的答案列表。

PolicyResponse 对象:

  • questionId(字符串,必需):所回答的特定问题的唯一标识符(例如 POLICY_QUESTION_ID_FINANCIAL_PRODUCT_TYPES、POLICY_QUESTION_ID_TAC_TARGET_AGE_GROUPS)。
  • value(必需):答案本身,可以是以下类型之一:
    • booleanResponse:用于“是/否”问题。
      • value(布尔值)
    • stringResponse:用于纯文本答案,包括网址。
      • value(字符串)
    • singleChoiceResponse:适用于只能从列表中选择一个选项的情况。
      • value(字符串):所选回答选项的 ID。
    • multipleChoiceResponse:适用于可以选择多个选项的情况。
      • values(字符串数组):所选回答选项的 ID。
    • documentResponse:用于需要上传文档的问题。请参阅处理文档上传。
    • groupResponse:用于重复的嵌套问题集。
    • keyedGroupResponse:用于按特定键分组的嵌套问题集。

如需查看声明的示例代码段,请参阅详细指南。

处理文档上传

某些政策问题要求您提供证明文档(例如,涉及金融产品和服务的许可)。文档无法直接嵌入到 UpdateAppStoreHostedAppRequest 中。 您必须通过以下方式提供文档:

  1. 上传文档:使用 UploadAppStoreAppPolicyDeclarationFile 端点。这是一项媒体上传请求。fileType 应设置为 DECLARATION_FILE_TYPE_DOCUMENT。

    • 端点:POST /androidpublisher/v3/appstore/{appStorePackageName}/apps/{packageName}/policyDeclarationFiles:upload
    • 如果上传成功,响应中将包含 fileId。
  2. 引用文档 ID:针对文档类问题,在 PolicyResponse 中使用 documentResponse 类型。使用从上传步骤中获得的 fileId 填充 documentId 字段。

PolicyDocumentResponse 对象:

  • documentId(字符串,必需):从 UploadAppStoreAppPolicyDeclarationFile 端点返回的 ID。
  • expiryDate(日期,可选):文档的失效日期(如适用)。
  • nonExpiring(布尔值,可选):如果文档不会过期,则设置为 true。

文档类回答示例:

// Inside a PolicyResponse object
{
  "questionId": "POLICY_QUESTION_ID_FINANCE_CRYPTO_US_FINCEN_LICENSE", // Example ID
  "documentResponse": {
    "documentId": "123456789", // The fileId from upload
    "expiryDate": {
      "year": 2027,
      "month": 6,
      "day": 1
    }
  }
}

4. 控制可用性

使用 UpdateAppStoreHostedApp 提交托管应用状态后,系统会自动处理该应用,并在 Google Play 中默认将其标记为已发布,以供第三方应用商店使用。

如需在提交应用后控制其可用性,请调用 updateappstorehostedapppublishstatus 方法来更新其状态:

  • 取消发布应用:如需使托管应用不可用,请将 publishState 字段设置为 APP_STORE_APP_PUBLISH_STATE_UNPUBLISHED。
  • 重新发布应用:如需在不修改商品详情或重新上传资源的情况下,使之前已取消发布的应用再次可用,请将 publishState 字段设置为 APP_STORE_APP_PUBLISH_STATE_PUBLISHED。