asc-revenuecat-catalog-sync

asc-revenuecat-catalog-sync

热门

使用 `asc` 命令行工具和 RevenueCat MCP,比对并同步 App Store Connect (ASC) 的自动续期订阅和 App 内购买项目(IAP)到 RevenueCat 的产品(products)、权益(entitlements)、提供项(offerings)及包(packages)。适用于在 ASC 与 RevenueCat 之间初始化或同步订阅产品目录的场景。

948Star
50Fork
更新于 2026/7/31
SKILL.md
只读
名称
asc-revenuecat-catalog-sync
描述

使用 `asc` 命令行工具和 RevenueCat MCP,比对并同步 App Store Connect (ASC) 的自动续期订阅和 App 内购买项目(IAP)到 RevenueCat 的产品(products)、权益(entitlements)、提供项(offerings)及包(packages)。适用于在 ASC 与 RevenueCat 之间初始化或同步订阅产品目录的场景。

asc 与 RevenueCat 订阅目录同步

使用本 Skill 保持 App Store Connect (ASC) 与 RevenueCat 之间的配置一致,包括补全缺失的 ASC 项目并将其映射到 RevenueCat 资源。

适用场景

  • 希望根据现有的 ASC 目录快速初始化 RevenueCat 配置。
  • 需要补全缺失的 ASC 订阅/IAP 项目,随后将其映射至 RevenueCat。
  • 发版前需要对两边配置做配置漂移审计(Drift Audit)。
  • 需要基于唯一标识符进行确定性的产品映射。

前置条件

  • 已配置 asc 身份认证(通过 asc auth loginASC_* 环境变量)。
  • 已配置并认证 RevenueCat MCP 服务端。
  • 在 Cursor 与 VS Code 中,RevenueCat MCP 支持 OAuth 认证,同时也支持 API Key 认证。
  • 已明确以下参数:
    • ASC 应用 ID(APP_ID
    • RevenueCat 的 project_id
    • 目标 RevenueCat 应用类型(app_storemac_app_store)以及用于新建流程的 Bundle ID
  • 执行修改时,请使用具备写入权限的 RevenueCat API v2 Key。

安全默认机制

  • 默认以 审计模式(Audit mode,只读) 启动。
  • 在执行写入操作前必须经过明确确认。
  • 此工作流中绝不删除任何现有资源。
  • 单个项目失败时继续后续流程,并在最后汇总报告所有失败项。

规范标识符

  • 跨系统的核心关联键:ASC 的 productId == RevenueCat 的 store_identifier
  • 产品上线后,请保持 productId 稳定不变。
  • 切勿将显示名称(display name)用作唯一标识符。

边界声明

  • RevenueCat MCP 仅用于配置 RevenueCat 端的资源,不会直接在 App Store Connect 中创建产品。
  • 在向 RevenueCat 映射之前,先使用 asc 命令创建缺失的 ASC 订阅组、订阅项和 IAP。

操作模式

1) 审计模式(默认)

  1. 读取源端 ASC 目录。
  2. 读取目标端 RevenueCat 目录。
  3. 生成包含以下操作的 Diff 差异对比:
    • ASC 端缺失的项目
    • RevenueCat 端缺失的项目
    • 映射冲突(标识符/类型/应用不匹配)
  4. 展示变更计划并等待确认。

2) 应用模式(需明确指定)

按以下顺序执行已批准的操作:

  1. 确保 ASC 的组/订阅/IAP 存在。
  2. 确保 RevenueCat 的应用/产品存在。
  3. 确保权益(entitlements)及产品关联关系存在。
  4. 确保提供项(offerings)、包(packages)及包关联关系存在。
  5. 校验并输出最终的比对对账汇总。

逐步工作流

步骤 A - 读取当前 ASC 目录

asc subscriptions groups list --app "APP_ID" --paginate --output json
asc iap list --app "APP_ID" --paginate --output json
# 遍历每个订阅组:
asc subscriptions list --group-id "GROUP_ID" --paginate --output json

步骤 B - 通过 MCP 读取当前 RevenueCat 目录

使用以下 MCP 工具(在适用处传入 project_id 并处理分页):

  • mcp_RC_get_project
  • mcp_RC_list_apps
  • mcp_RC_list_products
  • mcp_RC_list_entitlements
  • mcp_RC_list_offerings
  • mcp_RC_list_packages

步骤 C - 构建映射计划

将 ASC 产品类型映射为 RevenueCat 产品类型:

  • ASC subscription -> RevenueCat subscription
  • ASC IAP CONSUMABLE -> RevenueCat consumable
  • ASC IAP NON_CONSUMABLE -> RevenueCat non_consumable
  • ASC IAP NON_RENEWING_SUBSCRIPTION -> RevenueCat non_renewing_subscription

建议的权益策略:

  • 自动续期订阅:每个订阅组分配一个权益(或按用户显式指定的映射)
  • 非消耗型 IAP:每个产品分配一个权益
  • 消耗型 IAP:默认不关联权益,除非用户显式要求

步骤 D - 补全缺失的 ASC 项目(若要求)

在写入前,先解析确定每一个父节点与版本。订阅组按精确的参考名称(referenceName)匹配,产品按 productId 匹配;切勿将显示名称(display name)作为标识依据。当资源已存在时复用规范 ID,仅在完整分页读取证实缺失时才执行创建命令。RevenueCat 端存在产品映射并不代表对应的 ASC 订阅已就绪可供审核(review-ready)。

# 按精确 referenceName 解析 GROUP_ID。
asc subscriptions groups list --app "APP_ID" --paginate --output json
# 当且仅当完整分页列表中精确匹配数为 0 时执行创建:
asc subscriptions groups create --app "APP_ID" --reference-name "Premium" --output json
# 若匹配到 1 个,复用其 ID。若匹配到多个,停止操作并要求显式提供 GROUP_ID。

# 在 GROUP_ID 内按精确 productId 解析 SUB_ID。仅在父节点缺失或显式批准对比同名产品 ID 时才执行 setup。
asc subscriptions list --group-id "GROUP_ID" --paginate --output json
# 当且仅当完整分页列表中精确匹配数为 0 时执行 setup:
asc subscriptions setup \
  --app "APP_ID" \
  --group-id "GROUP_ID" \
  --reference-name "Monthly" \
  --product-id "com.example.premium.monthly" \
  --subscription-period ONE_MONTH \
  --review-screenshot "./review.png" \
  --price "3.99" \
  --price-territory "USA" \
  --territories "USA" \
  --no-verify \
  --output json
# 若匹配到 1 个,复用其 ID。若匹配到多个,停止操作并要求显式提供 SUB_ID。
# 仅在显式批准对账时,才对已有 SUB_ID 重新运行 setup。

# 解析当前审核生命周期中唯一的硬性/可变组版本(mutable group version)。
asc subscriptions groups versions list --group-id "GROUP_ID" --state PREPARE_FOR_SUBMISSION --paginate --output json
# 当且仅当列表匹配数为 0 时执行创建:
asc subscriptions groups versions create --group-id "GROUP_ID" --output json
# 若匹配到 1 个,复用 .data[0].id。若匹配到多个,停止操作并要求显式提供 GROUP_VERSION_ID。

# 在 GROUP_VERSION_ID 上解析 en-US 本地化语言包。仅在缺失时创建;若解析出的本地化 ID 属性值不一致则执行更新。
asc subscriptions groups versions localizations list --version-id "GROUP_VERSION_ID" --paginate --output json
asc subscriptions groups versions localizations create --version-id "GROUP_VERSION_ID" --locale "en-US" --name "Premium" --output json
asc subscriptions groups versions localizations update --id "GROUP_LOC_ID" --name "Premium"

# 解析当前审核生命周期中唯一的硬性/可变订阅版本(mutable subscription version)。
asc subscriptions versions list --subscription-id "SUB_ID" --state PREPARE_FOR_SUBMISSION --paginate --output json
# 当且仅当列表匹配数为 0 时执行创建:
asc subscriptions versions create --subscription-id "SUB_ID" --output json
# 若匹配到 1 个,复用 .data[0].id。若匹配到多个,停止操作并要求显式提供 SUBSCRIPTION_VERSION_ID。
asc subscriptions versions localizations list --version-id "SUBSCRIPTION_VERSION_ID" --paginate --output json
asc subscriptions versions localizations create --version-id "SUBSCRIPTION_VERSION_ID" --locale "en-US" --name "Premium Monthly" --description "Unlock all premium features." --output json
asc subscriptions versions localizations update --id "SUBSCRIPTION_LOC_ID" --name "Premium Monthly" --description "Unlock all premium features."

# 回读上述选择的精确版本,然后运行最终的严格校验器。
asc subscriptions groups versions localizations list --version-id "GROUP_VERSION_ID" --paginate --output table
asc subscriptions versions localizations list --version-id "SUBSCRIPTION_VERSION_ID" --paginate --output table
asc validate subscriptions --app "APP_ID" --strict --output table

# 按精确 productId 解析 IAP_ID。
asc iap list --app "APP_ID" --paginate --output json
# 当且仅当完整分页列表中精确匹配数为 0 时执行创建:
asc iap create \
  --app "APP_ID" \
  --type NON_CONSUMABLE \
  --ref-name "Lifetime" \
  --product-id "com.example.lifetime" \
  --output json
# 若匹配到 1 个,复用其 ID。若匹配到多个,停止操作并要求显式提供 IAP_ID。

# 解析当前审核生命周期中唯一的硬性/可变 IAP 版本(mutable IAP version)。
asc iap versions list --iap-id "IAP_ID" --state PREPARE_FOR_SUBMISSION --paginate --output json
# 当且仅当列表匹配数为 0 时执行创建:
asc iap versions create --iap-id "IAP_ID" --output json
# 若匹配到 1 个,复用 .data[0].id。若匹配到多个,停止操作并要求显式提供 IAP_VERSION_ID。
asc iap versions localizations list --version-id "IAP_VERSION_ID" --paginate --output json
asc iap versions localizations create --version-id "IAP_VERSION_ID" --locale "en-US" --name "Lifetime" --description "Unlock all premium features." --output json
asc iap versions localizations update --localization-id "IAP_LOC_ID" --name "Lifetime" --description "Unlock all premium features."
asc iap versions localizations list --version-id "IAP_VERSION_ID" --paginate --output table

上述每个相邻的“创建/更新”对都是带有条件的,绝不是盲目按顺序执行的序列:当列表无匹配项时创建,当解析出的匹配项属性值不同时更新,若已完全一致则不作处理。从创建响应的 .data.id 或先前列表查询结果的 .data[].id 中提取规范 ID,供后续命令使用。对于每个版本列表,PREPARE_FOR_SUBMISSION 的匹配数为 0 表示创建,为 1 表示复用该 ID,超过 1 个则暂停并要求用户手动选择明确的版本 ID。切勿通过新建版本来试图消除歧义:实测表明删除父资源并不能可靠地级联删除其下属的 IAP 或订阅版本。

subscriptions setup 负责完成父节点创建、App 审核截图提交、完整的 App Store 价格矩阵配置以及销售可用范围设置。而版本作用域(version-scoped)的命令则用于补充 RevenueCat 无法配置的订阅组及订阅项本地化语言包。销售可用范围需严格限制在请求的地区;价格配置依然依赖 Apple 完整的等效地区矩阵。在此拆分工作流中故意使用 --no-verify,是因为最终校验必须等到版本元数据补充完毕后才能进行;显式回读与校验器才是最终的关卡(Gate)。

若通过 API 创建的现有订阅在选定基础价格未变的情况下依然保持 MISSING_METADATA 状态,请带着相同的 setup 入参重新运行并加上 --repair。Repair 参数会以原子方式重建并重新保存完整的等效价格矩阵,而非简单的重复发送单价 POST 请求。

对于每一个解析完成的 ASC 订阅,在创建或关联其 RevenueCat 产品前,必须通过以下最终校验关卡。即使该订阅及其选定版本完全复用且未进行任何 ASC 写入,也必须在完成最终 ASC 比对后运行:

mkdir -p "./audit"
asc validate subscriptions --app "APP_ID" --strict --output json --pretty \
  > "./audit/subscriptions-validation.json"

对于每一个解析完成的 ASC IAP,在创建或关联其 RevenueCat 产品前,必须通过 IAP 校验关卡。即使该 IAP 及其选定版本完全复用且未进行任何 ASC 写入,也必须在完成最终 ASC 比对后运行:

mkdir -p "./audit"
asc validate iap --app "APP_ID" --strict --output json --pretty \
  > "./audit/iap-validation.json"

上述两条命令都是严格的映射卡点(Strict mapping gates),而非写入后的冒烟测试。只要校验结果报告了警告、错误、MISSING_METADATA、审核截图未处于 COMPLETE 状态、或存在不完整/未验证的价格覆盖率,就决不能映射任何已解析或复用的订阅。只要校验器报告错误或警告,也绝不映射任何已解析或复用的 IAP。即便是零写入的审计或应用运行,在创建或关联 RevenueCat 产品之前,也必须执行对应的关卡校验并要求退出码为 0。使用标准重定向会保留校验器原本的退出状态码。请保留 ./audit/subscriptions-validation.json./audit/iap-validation.json 作为最终的审计留存证据。

步骤 E - 确保 RevenueCat 应用及产品就绪

使用 MCP 命令:

  • 若应用缺失则创建:mcp_RC_create_app
  • 创建产品:mcp_RC_create_product
    • store_identifier = ASC 的 productId
    • app_id = RevenueCat 应用 ID
    • type = 上述映射规则中的类型

步骤 F - 确保权益及关联关系就绪

使用 MCP 命令:

  • 查询/创建权益:mcp_RC_list_entitlementsmcp_RC_create_entitlement
  • 将产品关联至权益:mcp_RC_attach_products_to_entitlement
  • 验证关联关系:`mcp_RC_get_products_from_entitleme

<!-- truncated for translation batch; full body continues in source -->