mcpField
G
gplay-ppp-pricing

gplay-ppp-pricing

github.com/tamtom营销与增长52352 次安装13 周前更新
代码仓库

关于 gplay-ppp-pricing

gplay-ppp-pricing 是用于 Google Play 商品的按购买力平价制定区域价格的技能,面向管理应用内商品和订阅定价的开发者。它涵盖旧版与新版商品 API,并强调获取现有区域配置后合并更新,避免移除地区数据。

主要功能

  1. 01按区域购买力系数计算价格
  2. 02支持应用内商品与一次性商品
  3. 03支持订阅价格调整
  4. 04合并保留现有区域配置
  5. 05说明区域版本及更新掩码要求

适用场景

  1. 01为不同国家设置本地化商品价格
  2. 02调整现有订阅的区域定价
  3. 03创建带区域价格的一次性商品

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/tamtom/gplay-cli-skills --skill gplay-ppp-pricing

安装后在 Claude Code 中输入/gplay-ppp-pricing确认已加载。

详细介绍

PPP 定价(按地区定价)

使用此技能,根据购买力平价或自定义定价策略,为不同国家设置不同价格。

前提条件

  • 确保已设置凭据(gplay auth login --service-account 或 GPLAY_SERVICE_ACCOUNT 环境变量)。
  • 使用 GPLAY_PACKAGE,或显式传入 --package。
  • 确定基础地区(通常为 US)和基础价格。

重要:必需的标志

更新会修改定价的订阅或一次性商品时,必须提供:

  • --regions-version:Google Play API 更新地区定价时必需。请使用最新版本。如果不知道当前版本,请发送任意值(例如 "2022/02")——API 错误会告知最新版本(例如 latest value is ExternalRegionLaunchVersionId{versionId=2025/03})。然后使用正确版本重试。
  • --update-mask "basePlans":更新订阅时必需。若未提供,API 将返回:"update_mask must contain at least one path."
  • 对于一次性商品,请使用 --update-mask "purchaseOptions"。

重要:保留所有现有地区(先获取再合并)

Google Play API 会拒绝删除现有地区配置的更新。 如果某个订阅已配置 173 个地区,而你只发送 30 个 PPP 地区,API 将返回:"Regional configs were removed from the base plan: BM, BO, CI..."

始终遵循先获取再合并的模式:

  1. 获取当前商品,以取得所有现有地区配置
  2. 仅将 PPP 目标地区替换为计算出的价格
  3. 发送完整的合并列表(所有原有地区 + PPP 覆盖项)

此规则也适用于:

  • otherRegionsConfig(订阅)——如果之前已在某个基本方案中设置,更新 JSON 中必须包含此项。
  • newRegionsConfig(一次性商品购买选项)——如果之前已设置(包含 usdPrice、eurPrice 和 availability),则必须包含此项。省略会导致:"Cannot remove currency for new regions once it has been added: EUR."

重要:货币代码应以 Google Play 为准,不要凭假设填写

不要对货币与地区的映射进行硬编码。 货币代码会因 --regions-version 的值而变化(例如,在采用欧元后,旧版本中的保加利亚 BG 使用 BGN,而新版本中使用 EUR)。

始终使用获取到的现有地区配置中的货币代码。 对于价格被覆盖的 PPP 目标地区,请使用下方乘数表中的货币。对于所有其他地区,请原样保留 Google Play 返回的现有货币。

PPP 乘数表

将这些乘数应用于基础 USD 价格。所有结果均四舍五入为以 .99 结尾(例如,$4.73 → $4.99,₹249.37 → ₹249.99)。

第 1 档 — 全价(1.0x–1.1x)
地区代码乘数货币
美国US1.0xUSD
英国GB1.0xGBP
德国DE1.0xEUR
澳大利亚AU1.0xAUD
瑞士CH1.1xCHF
加拿大CA1.0xCAD
荷兰NL1.0xEUR
瑞典SE1.0xSEK
挪威NO1.05xNOK
丹麦DK1.0xDKK
第 2 档 — 中等(0.6x–0.8x)
地区代码乘数货币
法国FR0.8xEUR
西班牙ES0.7xEUR
意大利IT0.7xEUR
日本JP0.8xJPY
韩国KR0.7xKRW
波兰PL0.6xPLN
葡萄牙PT0.7xEUR
捷克共和国CZ0.6xCZK
希腊GR0.65xEUR
智利CL0.6xCLP
沙特阿拉伯SA0.8xSAR
阿联酋AE0.8xAED
第 3 档 — 低(0.3x–0.5x)
地区代码乘数货币
印度IN0.3xINR
巴西BR0.5xBRL
墨西哥MX0.45xMXN
印度尼西亚ID0.3xIDR
土耳其TR0.35xTRY
越南VN0.3xVND
菲律宾PH0.35xPHP
埃及EG0.3xEGP
哥伦比亚CO0.4xCOP
阿根廷AR0.3xARS
尼日利亚NG0.3xNGN
巴基斯坦PK0.25xPKR
泰国TH0.4xTHB
马来西亚MY0.45xMYR
南非ZA0.4xZAR
乌克兰UA0.3xUAH

工作流:设置基于 PPP 的 IAP 定价(旧版 inappproducts API)

将此工作流用于通过 gplay iap 创建的旧版托管商品。此类商品使用 priceMicros/currency 格式。

1. 列出应用内商品
gplay iap list --package "PACKAGE"
2. 获取当前商品详情
gplay iap get --package "PACKAGE" --sku "SKU"

记下当前的 defaultPrice,将其作为基础价格,并保存所有现有的 prices 条目。

3. 构建经 PPP 调整的价格 JSON(先获取再合并)

**必须包含所有现有地区价格,而不仅仅是 PPP 目标地区。**先获取当前商品,然后覆盖 PPP 地区。

{
  "sku": "premium_upgrade",
  "defaultPrice": {
    "priceMicros": "9990000",
    "currency": "USD"
  },
  "prices": {
    "US": { "priceMicros": "9990000", "currency": "USD" },
    "IN": { "priceMicros": "2499900", "currency": "INR" },
    "BR": { "priceMicros": "24990000", "currency": "BRL" },
    "GB": { "priceMicros": "9990000", "currency": "GBP" },
    "DE": { "priceMicros": "9990000", "currency": "EUR" }
  }
}
4. 更新商品
gplay iap update \
  --package "PACKAGE" \
  --sku "SKU" \
  --json @ppp-prices.json
5. 验证价格
gplay iap get --package "PACKAGE" --sku "SKU"

工作流:创建采用 PPP 定价的新一次性商品

从头开始创建全新的一次性商品并设置 PPP 定价时,使用此工作流。

1. 参考现有商品的地区配置结构

如果已有一次性商品(OTP),请获取该商品,将其用作地区配置格式的模板:

gplay onetimeproducts get --package "PACKAGE" --product-id "EXISTING_PRODUCT_ID"

记下 regionsVersion 和 regionalPricingAndAvailabilityConfigs 的结构。

2. 构建包含 PPP 定价的商品 JSON

构建完整的商品 JSON,其中包括商品详情、购买选项和所有地区定价配置。价格格式使用 units/nanos/currencyCode(参见下方的格式参考)。

{
  "productId": "premium_lifetime_50off",
  "listings": [
    { "languageCode": "en-US", "title": "Premium (50% off)", "description": "Lifetime access at 50% off" }
  ],
  "purchaseOptions": [
    {
      "buyOption": { "legacyCompatible": true },
      "newRegionsConfig": {
        "availability": "AVAILABLE",
        "usdPrice": { "currencyCode": "USD", "units": "14", "nanos": 990000000 },
        "eurPrice": { "currencyCode": "EUR", "units": "13", "nanos": 990000000 }
      },
      "regionalPricingAndAvailabilityConfigs": [
        { "regionCode": "US", "availability": "AVAILABLE", "price": { "currencyCode": "USD", "units": "14", "nanos": 990000000 } },
        { "regionCode": "IN", "availability": "AVAILABLE", "price": { "currencyCode": "INR", "units": "373", "nanos": 990000000 } },
        { "regionCode": "BR", "availability": "AVAILABLE", "price": { "currencyCode": "BRL", "units": "37", "nanos": 990000000 } }
      ]
    }
  ]
}
3. 创建商品

即使是创建,也必须使用 --regions-version——create 命令内部使用了带 allowMissing=true 的 PATCH:

gplay onetimeproducts create \
  --package "PACKAGE" \
  --product-id "premium_lifetime_50off" \
  --json @new-otp.json \
  --regions-version "2025/03"

商品创建后处于 DRAFT 状态。

4. 激活购买选项

新商品初始状态为 DRAFT。使用 purchase-options batch-update-states 激活:

gplay purchase-options batch-update-states \
  --package "PACKAGE" \
  --product-id "premium_lifetime_50off" \
  --json '{"requests":[{"activatePurchaseOptionRequest":{"packageName":"PACKAGE","productId":"premium_lifetime_50off","purchaseOptionId":"default"}}]}'
5. 验证商品
gplay onetimeproducts get --package "PACKAGE" --product-id "premium_lifetime_50off"

确认状态为 ACTIVE,且所有地区的价格均正确。

工作流:更新现有一次性商品的 PPP 定价(新变现 API)

将此工作流用于通过 gplay onetimeproducts 创建的现有一次性商品。此类商品使用 units/nanos/currencyCode 格式,并包含带有 regionalPricingAndAvailabilityConfigs 的 purchaseOptions。

1. 列出一次性商品
gplay onetimeproducts list --package "PACKAGE"
2. 获取当前商品并保存所有地区配置
gplay onetimeproducts get --package "PACKAGE" --product-id "PRODUCT_ID"

保存完整 JSON。请注意:

  • purchaseOptions[].regionalPricingAndAvailabilityConfigs 数组——需要包含所有条目
  • purchaseOptions[].newRegionsConfig——如果之前已设置,则必须包含(其中包含 usdPrice、eurPrice、availability)
3. 构建经 PPP 调整的 JSON(先获取再合并)

先使用现有 regionalPricingAndAvailabilityConfigs 的完整列表,然后覆盖 PPP 目标地区的计算价格。其他地区保持不变。

价格格式使用 units(作为字符串的整数部分)和 nanos(作为整数的小数部分,范围为 0–999999999):

  • $5.99 → "units": "5", "nanos": 990000000
  • ₹149.99 → "units": "149", "nanos": 990000000
  • ¥719 → "units": "719", "nanos": 0
{
  "productId": "premium_lifetime",
  "purchaseOptions": [
    {
      "purchaseOptionId": "EXISTING_OPTION_ID",
      "buyOption": { "legacyCompatible": true },
      "newRegionsConfig": {
        "availability": "AVAILABLE",
        "usdPrice": { "currencyCode": "USD", "units": "29", "nanos": 990000000 },
        "eurPrice": { "currencyCode": "EUR", "units": "27", "nanos": 990000000 }
      },
      "regionalPricingAndAvailabilityConfigs": [
        { "regionCode": "US", "availability": "AVAILABLE", "price": { "currencyCode": "USD", "units": "29", "nanos": 990000000 } },
        { "regionCode": "IN", "availability": "AVAILABLE", "price": { "currencyCode": "INR", "units": "746", "nanos": 990000000 } },
        { "regionCode": "BR", "availability": "AVAILABLE", "price": { "currencyCode": "BRL", "units": "74", "nanos": 990000000 } },
        { "regionCode": "AE", "availability": "AVAILABLE", "price": { "currencyCode": "AED", "units": "109", "nanos": 990000000 } }
      ]
    }
  ]
}

重要:

  • regionalPricingAndAvailabilityConfigs 数组必须包含现有商品的所有地区。仅覆盖 PPP 目标地区的价格。
  • 如果现有商品已设置 newRegionsConfig,则必须包含该项。省略会导致错误:“添加货币后,无法为新地区移除该货币。”
4. 对商品执行 Patch
gplay onetimeproducts patch \
  --package "PACKAGE" \
  --product-id "PRODUCT_ID" \
  --json @ppp-otp.json \
  --regions-version "2025/03" \
  --update-mask "purchaseOptions"
5. 验证价格
gplay onetimeproducts get --package "PACKAGE" --product-id "PRODUCT_ID"

工作流:设置基于 PPP 的订阅定价

1. 列出订阅
gplay subscriptions list --package "PACKAGE"
2. 获取当前订阅并保存所有地区配置
gplay subscriptions get --package "PACKAGE" --product-id "PRODUCT_ID"

保存完整的 JSON。对于每个基础方案,请记录:

  • otherRegionsConfig(USD 和 EUR 基准价格)——如果之前已设置,则必须包含
  • regionalConfigs 数组——必须包含所有现有地区
  • autoRenewingBasePlanType 或 prepaidBasePlanType
3. 构建经 PPP 调整的订阅 JSON(先获取,再合并)

先保留每个基础方案中完整的现有 regionalConfigs,然后覆盖 PPP 目标地区。其他所有地区保持不变。

订阅价格使用 units/nanos/currencyCode 格式:

{
  "productId": "premium_monthly",
  "basePlans": [
    {
      "basePlanId": "monthly",
      "otherRegionsConfig": {
        "newSubscriberAvailability": true,
        "usdPrice": { "currencyCode": "USD", "units": "5", "nanos": 990000000 },
        "eurPrice": { "currencyCode": "EUR", "units": "5", "nanos": 70000000 }
      },
      "regionalConfigs": [
        { "regionCode": "US", "newSubscriberAvailability": true, "price": { "currencyCode": "USD", "units": "5", "nanos": 990000000 } },
        { "regionCode": "IN", "newSubscriberAvailability": true, "price": { "currencyCode": "INR", "units": "149", "nanos": 990000000 } },
        { "regionCode": "BR", "newSubscriberAvailability": true, "price": { "currencyCode": "BRL", "units": "14", "nanos": 990000000 } },
        { "regionCode": "AE", "newSubscriberAvailability": true, "price": { "currencyCode": "AED", "units": "22", "nanos": 990000000 } }
      ],
      "autoRenewingBasePlanType": { "billingPeriodDuration": "P1M" }
    }
  ]
}

重要: regionalConfigs 数组必须包含现有基础方案中的所有地区。如果订阅已有 173 个地区,则必须包含全部 173 个。仅覆盖 PPP 目标地区的价格。

4. 更新订阅
gplay subscriptions update \
  --package "PACKAGE" \
  --product-id "PRODUCT_ID" \
  --json @ppp-subscription.json \
  --regions-version "2025/03" \
  --update-mask "basePlans"

必须提供全部三个标志:

  • --json:包含合并后地区配置的订阅 JSON
  • --regions-version:使用最新版本(参见下文“查找地区版本”)
  • --update-mask "basePlans":告知 API 要更新哪些字段
5. 验证价格
gplay subscriptions get --package "PACKAGE" --product-id "PRODUCT_ID"

检查所有基础方案中的 regionalConfigs,确认 PPP 目标地区的价格已更新,且其他所有地区均已保留。

查找地区版本

更新价格时必须使用 --regions-version 标志。查找最新版本的方法:

  1. 使用任意版本(例如 "2022/02")尝试更新
  2. 如果版本已过期,API 错误会告知最新版本:
    Invalid regions version 2024/01, latest value is ExternalRegionLaunchVersionId{versionId=2025/03}
    
  3. 使用错误消息中的版本重试

不同版本之间的货币代码可能会变化(例如,有国家加入欧元区)。始终使用获取到的现有数据中的货币代码,而不要使用硬编码映射。

工作流:迁移现有订阅者价格

更新有活跃订阅者的订阅的 PPP 价格时,新价格仅适用于新订阅者。要迁移现有订阅者:

1. 更新价格(以上步骤)
2. 将现有订阅者迁移到新价格
gplay baseplans migrate-prices \
  --package "PACKAGE" \
  --product-id "PRODUCT_ID" \
  --base-plan-id "BASE_PLAN_ID" \
  --json @migration.json
3. 对每个基础方案重复操作

对所有价格已更改的基础方案应用迁移:

# Monthly plan
gplay baseplans migrate-prices \
  --package "PACKAGE" \
  --product-id "PRODUCT_ID" \
  --base-plan-id monthly \
  --json @migration.json

# Yearly plan
gplay baseplans migrate-prices \
  --package "PACKAGE" \
  --product-id "PRODUCT_ID" \
  --base-plan-id yearly \
  --json @migration.json
4. 验证迁移
gplay subscriptions get --package "PACKAGE" --product-id "PRODUCT_ID"

更新现有 PPP 价格

要更改某个地区的价格:

  1. 获取当前产品/订阅,以取得所有现有地区配置。
  2. 使用新的基准价格或新乘数重新计算经 PPP 调整的价格。
  3. 将新的 PPP 价格合并到完整的地区配置列表中。
  4. 使用合并后的 JSON 更新(必须包含所有地区,而不只是已更改的地区)。
  5. 对有活跃订阅者的订阅,针对每个受影响的基础方案运行 migrate-prices。
  6. 通过获取数据并查看摘要来验证。

批量处理多个产品的 PPP

多个旧版 IAP
gplay iap batch-update \
  --package "PACKAGE" \
  --json @ppp-all-iaps.json
多个一次性产品

批量更新时,regionsVersion 和 updateMask 必须放在 JSON 的每个请求中(而不是作为 CLI 标志):

gplay onetimeproducts batch-update \
  --package "PACKAGE" \
  --json @ppp-all-otps.json

批量 JSON 格式:

{
  "requests": [
    {
      "oneTimeProduct": { "productId": "product_1", "purchaseOptions": [...] },
      "regionsVersion": { "version": "2025/03" },
      "updateMask": "purchaseOptions"
    },
    {
      "oneTimeProduct": { "productId": "product_2", "purchaseOptions": [...] },
      "regionsVersion": { "version": "2025/03" },
      "updateMask": "purchaseOptions"
    }
  ]
}
多个订阅

逐个更新每个订阅:

gplay subscriptions update --package "PACKAGE" --product-id "sub_1" --json @ppp-sub1.json --regions-version "2025/03" --update-mask "basePlans"
gplay subscriptions update --package "PACKAGE" --product-id "sub_2" --json @ppp-sub2.json --regions-version "2025/03" --update-mask "basePlans"

常见 PPP 策略

BigMac 指数法

根据相对购买力调整价格:

  • 美国:$9.99(基准)
  • 印度:$2.99(约 7 折)
  • 巴西:$4.99(约 5 折)
  • 英国:$9.99(相近)
  • 瑞士:$10.99(溢价)
分级地区定价

将国家分为不同价格层级:

  • 第 1 级(全价):美国、英国、德国、澳大利亚、瑞士、加拿大
  • 第 2 级(中等):法国、西班牙、意大利、日本、韩国、沙特阿拉伯
  • 第 3 级(低价):印度、巴西、墨西哥、印度尼西亚、土耳其、越南、埃及
收入优化
  • 从第 3 级折扣开始,以在价格敏感型市场获取更多用户。
  • 应用 PPP 后,按地区监测转化率。
  • 根据实际收入数据调整乘数。

常见陷阱

  1. 只发送 PPP 地区 — API 会拒绝删除现有地区的更新。请始终先获取数据,再合并。
  2. 缺少 --regions-version — 任何价格更新都必须提供此参数。如果填写错误,API 错误会告知最新版本。
  3. 缺少 --update-mask — 订阅使用 "basePlans",一次性商品使用 "purchaseOptions"。
  4. 缺少 otherRegionsConfig — 如果订阅基础方案之前设置了 otherRegionsConfig,则更新时必须包含它。
  5. 缺少 newRegionsConfig — 如果一次性商品的购买选项之前设置了 newRegionsConfig,则必须包含它。省略此项会导致错误:“添加新地区的货币后,无法移除该货币。”
  6. 货币代码错误 — 不要自行假定货币代码。请从 Google Play 获取,因为货币代码会随地区版本变化。
  7. 混用 API 格式 — 旧版 IAP 使用 priceMicros/currency。新版订阅和一次性商品使用 units/nanos/currencyCode。请勿混用。
  8. --dry-run 是全局标志 — 将它放在子命令之前:gplay --dry-run subscriptions update ...,而不是 gplay subscriptions update --dry-run ...。后一种写法会报错:“提供了未定义的标志。”
  9. 批量更新 JSON 格式 — 对于 onetimeproducts batch-update 和 subscriptions batch-update,regionsVersion 和 updateMask 应放在 JSON 中的每个请求对象内,而不是作为 CLI 标志。
  10. 商品 ID 是永久的 — 删除商品后,Google Play 会永久保留其商品 ID。如果你通过 gplay iap create 创建商品后将其删除,该 ID 将无法再次使用,甚至不能通过 gplay onetimeproducts create 重用。请务必谨慎选择商品 ID。请勿先通过旧版 API 创建商品,再尝试通过新版 API 重新创建。
  11. 新的 OTP 商品初始状态为 DRAFT — 执行 gplay onetimeproducts create 后,购买选项处于 DRAFT 状态。必须使用 gplay purchase-options batch-update-states 将其激活,用户才能使用。
  12. 创建时也必须提供 --regions-version — onetimeproducts create 内部使用 allowMissing=true 执行 PATCH,因此创建新商品时也必须提供 --regions-version,而不仅仅是在更新时需要。
  13. 使用 gplay --help 查找命令 — 购买选项的激活命令位于 gplay purchase-options 下,而非 gplay onetimeproducts 下。请始终运行 gplay --help 查看所有顶层命令组。

注意事项

  • 订阅价格变更会立即对新订阅者生效。
  • 现有订阅者需要通过 migrate-prices 显式迁移价格。
  • 使用 gplay pricing convert 参考货币换算,但还需叠加 PPP 乘数。
  • 更新后请务必获取商品并查看摘要,以验证价格。
  • PPP 乘数表提供了起始参考值,请根据市场数据和营收目标进行调整。

评论

支持 Markdown