使用 `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 login或ASC_*环境变量)。 - 已配置并认证 RevenueCat MCP 服务端。
- 在 Cursor 与 VS Code 中,RevenueCat MCP 支持 OAuth 认证,同时也支持 API Key 认证。
- 已明确以下参数:
- ASC 应用 ID(
APP_ID) - RevenueCat 的
project_id - 目标 RevenueCat 应用类型(
app_store或mac_app_store)以及用于新建流程的 Bundle ID
- ASC 应用 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) 审计模式(默认)
- 读取源端 ASC 目录。
- 读取目标端 RevenueCat 目录。
- 生成包含以下操作的 Diff 差异对比:
- ASC 端缺失的项目
- RevenueCat 端缺失的项目
- 映射冲突(标识符/类型/应用不匹配)
- 展示变更计划并等待确认。
2) 应用模式(需明确指定)
按以下顺序执行已批准的操作:
- 确保 ASC 的组/订阅/IAP 存在。
- 确保 RevenueCat 的应用/产品存在。
- 确保权益(entitlements)及产品关联关系存在。
- 确保提供项(offerings)、包(packages)及包关联关系存在。
- 校验并输出最终的比对对账汇总。
逐步工作流
步骤 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_projectmcp_RC_list_appsmcp_RC_list_productsmcp_RC_list_entitlementsmcp_RC_list_offeringsmcp_RC_list_packages
步骤 C - 构建映射计划
将 ASC 产品类型映射为 RevenueCat 产品类型:
- ASC subscription -> RevenueCat
subscription - ASC IAP
CONSUMABLE-> RevenueCatconsumable - ASC IAP
NON_CONSUMABLE-> RevenueCatnon_consumable - ASC IAP
NON_RENEWING_SUBSCRIPTION-> RevenueCatnon_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_productstore_identifier= ASC 的productIdapp_id= RevenueCat 应用 IDtype= 上述映射规则中的类型
步骤 F - 确保权益及关联关系就绪
使用 MCP 命令:
- 查询/创建权益:
mcp_RC_list_entitlements、mcp_RC_create_entitlement - 将产品关联至权益:
mcp_RC_attach_products_to_entitlement - 验证关联关系:`mcp_RC_get_products_from_entitleme
<!-- truncated for translation batch; full body continues in source -->






