关于 asc-subscriptions
使用 `asc` CLI 管理 App Store Connect 自动续订订阅的技能,涵盖订阅组、定价、本地化、优惠、兑换码和审核截图。
主要功能
- 01创建和管理订阅组及层级
- 02配置各地区的订阅价格
- 03管理本地化内容和订阅优惠
- 04创建并停用优惠码
- 05上传和管理审核截图
适用场景
- 01在 App Store Connect 配置订阅产品
- 02调整特定地区的价格
- 03创建入门优惠或挽回优惠
- 04生成并获取优惠码批次
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ tddworks/ asc-cli-skills --skill asc-subscriptions安装后在 Claude Code 中输入/asc-subscriptions确认已加载。
详细介绍
asc 订阅
通过 asc CLI 管理自动续期订阅组、层级、本地化、定价、优惠和审核素材。
订阅组
asc subscription-groups list --app-id <APP_ID>
asc subscription-groups create --app-id <APP_ID> --reference-name "Premium Plans"
asc subscription-groups update --group-id <GROUP_ID> --reference-name "Premium"
asc subscription-groups delete --group-id <GROUP_ID>
组本地化(每个地区的显示名称 + 自定 App 名称)
asc subscription-group-localizations list --group-id <GROUP_ID>
asc subscription-group-localizations create --group-id <GROUP_ID> --locale en-US --name "Premium Plans" [--custom-app-name "Premium App"]
asc subscription-group-localizations update --localization-id <LOC> [--name "..."] [--custom-app-name "..."]
asc subscription-group-localizations delete --localization-id <LOC>
订阅(生命周期)
asc subscriptions list --group-id <GROUP_ID>
asc subscriptions create --group-id <GROUP_ID> --name "Monthly Premium" \
--product-id "com.app.monthly" --period ONE_MONTH \
[--family-sharable] [--group-level 1]
asc subscriptions update --subscription-id <SUB_ID> \
[--name "..."] [--family-sharable | --not-family-sharable] [--group-level <n>] [--review-note "..."]
asc subscriptions delete --subscription-id <SUB_ID>
asc subscriptions submit --subscription-id <SUB_ID> # state must be READY_TO_SUBMIT
asc subscriptions unsubmit --submission-id <SUBMISSION_ID> # withdraw from review (manual Request<Void>)
asc subscriptions versions list --subscription-id <SUB_ID> # review versions + state (addToSubmission when submittable)
asc subscription-groups versions list --group-id <GROUP_ID> # a group's first subscription needs the group version too
首次提交的订阅? Apple 只会将其与 App 版本(及其所属组的版本)一同审核,因此 asc subscriptions submit 对此类订阅会失败。请与 App 一同提交:asc versions submit --version-id <VERSION_ID> --with-products(先使用 --dry-run 运行)。请参阅 submit-with-products.md。
--period ∈ ONE_WEEK、ONE_MONTH、TWO_MONTHS、THREE_MONTHS、SIX_MONTHS、ONE_YEAR。
订阅定价(按地区,包含 proceedsYear2)
asc subscriptions price-points list --subscription-id <SUB_ID> [--territory USA]
asc subscriptions prices set \
--subscription-id <SUB_ID> \
--territory USA \
--price-point-id <PP> \
[--start-date 2026-06-01] \
[--preserve-current-price]
订阅按地区定价(没有基础地区)。每个价格点都包含 customerPrice、proceeds 和 proceedsYear2。
订阅本地化
asc subscription-localizations list --subscription-id <SUB_ID>
asc subscription-localizations create --subscription-id <SUB_ID> --locale en-US --name "Monthly Premium" [--description "..."]
asc subscription-localizations update --localization-id <LOC> [--name "..."] [--description "..."]
asc subscription-localizations delete --localization-id <LOC>
入门优惠
asc subscription-offers list --subscription-id <SUB_ID>
# Free trial
asc subscription-offers create --subscription-id <SUB_ID> \
--duration ONE_MONTH --mode FREE_TRIAL --periods 1
# Paid intro offer — price-point-id required for PAY_AS_YOU_GO / PAY_UP_FRONT
asc subscription-offers create --subscription-id <SUB_ID> \
--duration THREE_MONTHS --mode PAY_AS_YOU_GO --periods 3 \
--territory USA --price-point-id <PP>
asc subscription-offers delete --offer-id <OFFER_ID>
--duration ∈ THREE_DAYS、ONE_WEEK、TWO_WEEKS、ONE_MONTH、TWO_MONTHS、THREE_MONTHS、SIX_MONTHS、ONE_YEAR。--mode ∈ FREE_TRIAL、PAY_AS_YOU_GO、PAY_UP_FRONT。
促销优惠(App 内优惠,按地区定价)
asc subscription-promotional-offers list --subscription-id <SUB_ID>
asc subscription-promotional-offers create --subscription-id <SUB_ID> \
--name "Loyalty25" --offer-code loyalty25 \
--duration THREE_MONTHS --mode PAY_AS_YOU_GO --periods 3 \
--price USA=spp-1 --price GBR=spp-2 # repeatable: TERRITORY=PRICE_POINT_ID
asc subscription-promotional-offers delete --offer-id <OFFER_ID>
asc subscription-promotional-offers prices list --offer-id <OFFER_ID>
--price 使用 ${newPromoOfferPrice-N} 内联编码,其中 N 为从 1 开始的本地 ID(与 ASC 网页 UI 的结构一致)。
挽回优惠(已流失的订阅者)
asc win-back-offers list --subscription-id <SUB_ID>
asc win-back-offers create --subscription-id <SUB_ID> \
--reference-name "Lapsed Q4" --offer-id lapsedQ4 \
--duration ONE_MONTH --mode FREE_TRIAL --periods 1 \
--paid-months 3 --since-min 1 --since-max 6 --wait-months 2 \
--start-date 2026-04-01 --end-date 2026-12-31 \
--priority HIGH --promotion-intent USE_AUTO_GENERATED_ASSETS \
[--price USA=spp-1 ...]
asc win-back-offers update --offer-id <OFFER_ID> \
[--start-date YYYY-MM-DD] [--end-date YYYY-MM-DD] \
[--priority HIGH|NORMAL] [--promotion-intent NOT_PROMOTED|USE_AUTO_GENERATED_ASSETS] \
[--paid-months <n>] [--since-min <n>] [--since-max <n>] [--wait-months <n>]
asc win-back-offers delete --offer-id <OFFER_ID>
asc win-back-offers prices list --offer-id <OFFER_ID>
资格模型:--paid-months(要求作为付费订阅者的月数)、--since-min..--since-max(距上次订阅的月数范围)、--wait-months(向同一客户展示优惠之间的间隔)。由于生成的 SDK 中 WinBackOfferPriceInlineCreate 缺少 territory 和 subscriptionPricePoint 关系,挽回优惠的创建请求体需要手动编码。
订阅优惠码(3 级层级结构)
第 1 级 — 优惠码
asc subscription-offer-codes list --subscription-id <SUB_ID>
asc subscription-offer-codes create --subscription-id <SUB_ID> \
--name "SUMMER2026" \
--duration ONE_MONTH --mode FREE_TRIAL --periods 1 \
--eligibility NEW --eligibility LAPSED \
--offer-eligibility STACKABLE \
--price USA=spp-usa --price JPN=spp-jpn \
--free-territory BRA \
[--auto-renew true|false]
asc subscription-offer-codes update --offer-code-id <OC> --active false
asc subscription-offer-codes prices list --offer-code-id <OC> # per-territory pricing (read-only)
价格仅在创建时设置一次(之后 prices 为只读;详情请参阅 IAP 技能中的说明)。使用 --auto-renew false 可创建不续期的一次性优惠;此时 ASC 仅接受 --mode FREE_TRIAL。
--eligibility(可重复)∈ NEW、LAPSED、WIN_BACK、PAID_SUBSCRIBER。--offer-eligibility ∈ STACKABLE、INTRODUCTORY、SUBSCRIPTION_OFFER。
第 2 级 — 自定义可兑换码
asc subscription-offer-code-custom-codes list --offer-code-id <OC>
asc subscription-offer-code-custom-codes create --offer-code-id <OC> \
--custom-code "SUMMER2026" --number-of-codes 1000 [--expiration-date 2026-12-31]
asc subscription-offer-code-custom-codes update --custom-code-id <CC> --active false
第 3 级 — 一次性使用代码批次
asc subscription-offer-code-one-time-codes list --offer-code-id <OC>
asc subscription-offer-code-one-time-codes create --offer-code-id <OC> \
--number-of-codes 5000 --expiration-date 2026-12-31 [--environment production|sandbox]
asc subscription-offer-code-one-time-codes update --one-time-code-id <OTC> --active false
# Download the CSV of redemption codes (raw String — not JSON):
asc subscription-offer-code-one-time-codes values --one-time-code-id <OTC>
--environment 默认为 production。Sandbox 批次使用 Sandbox 测试账户兑换(上限约为每季度 10,000 个);production 批次使用正式账户兑换(上限约为每季度 150,000 个)。每个 SubscriptionOfferCode 都会通过 productionCodeCount / sandboxCodeCount 报告两种环境下的使用情况,每个一次性使用代码行都带有 environment,可用于筛选。
REST 等效项:
GET /api/v1/subscription-offer-codes/{offerCodeId}/one-time-codes
POST /api/v1/subscription-offer-codes/{offerCodeId}/one-time-codes # body: {numberOfCodes, expirationDate, environment?}
PATCH /api/v1/subscription-offer-code-one-time-codes/{oneTimeCodeId} # body: {isActive: false}
订阅审核屏幕截图(单例)
asc subscription-review-screenshot get --subscription-id <SUB_ID> # empty data:[] when none
asc subscription-review-screenshot upload --subscription-id <SUB_ID> --file ./review.png
asc subscription-review-screenshot delete --screenshot-id <RS> # suppressed while AWAITING_UPLOAD
上传使用 ASC 的预留 → 分块上传 → 使用 MD5 提交协议。
CAEOAS 支持的操作
SubscriptionGroup 提供:
{
"affordances": {
"createLocalization": "asc subscription-group-localizations create --group-id <ID> --locale en-US --name <name>",
"createSubscription": "asc subscriptions create --group-id <ID> --name <name> --product-id <id> --period ONE_MONTH",
"delete": "asc subscription-groups delete --group-id <ID>",
"listLocalizations": "asc subscription-group-localizations list --group-id <ID>",
"listSubscriptions": "asc subscriptions list --group-id <ID>",
"update": "asc subscription-groups update --group-id <ID> --reference-name <name>"
}
}
Subscription 除现有键之外,还提供:
{
"createPromotionalOffer": "asc subscription-promotional-offers create --subscription-id <ID> ...",
"delete": "asc subscriptions delete --subscription-id <ID>",
"getReviewScreenshot": "asc subscription-review-screenshot get --subscription-id <ID>",
"listPromotionalOffers": "asc subscription-promotional-offers list --subscription-id <ID>",
"listVersions": "asc subscriptions versions list --subscription-id <ID>",
"listWinBackOffers": "asc win-back-offers list --subscription-id <ID>",
"update": "asc subscriptions update --subscription-id <ID> --name <name>"
}
仅当 state == READY_TO_SUBMIT 时才能执行 submit。SubscriptionSubmission 提供 unsubmit。SubscriptionLocalization 提供 update + delete。SubscriptionGroupLocalization 提供 update + delete。仅当 territory != nil 时,SubscriptionPricePoint 才提供 setPrice。SubscriptionPromotionalOffer 提供 delete + listPrices。WinBackOffer 提供 update + delete + listPrices。仅当 assetState.isComplete || hasFailed 时,SubscriptionReviewScreenshot 才提供 delete。仅当 isActive == true 时,*OfferCode* 自定义码和一次性码才提供 deactivate。
解析 App ID
请参阅 project-context.md — 在询问用户或运行 asc apps list 之前,先检查 .asc/project.json。
典型工作流
APP_ID=$(cat .asc/project.json 2>/dev/null | jq -r '.appId // empty')
# 1. Group + tier + group-localization
GROUP_ID=$(asc subscription-groups create --app-id "$APP_ID" --reference-name "Premium" \
| jq -r '.data[0].id')
asc subscription-group-localizations create --group-id "$GROUP_ID" --locale en-US \
--name "Premium Plans" --custom-app-name "Premium App"
SUB_ID=$(asc subscriptions create --group-id "$GROUP_ID" --name "Monthly Premium" \
--product-id "com.app.monthly" --period ONE_MONTH | jq -r '.data[0].id')
asc subscription-localizations create --subscription-id "$SUB_ID" --locale en-US \
--name "Monthly Premium" --description "Unlock everything"
# 2. Per-territory pricing
USA_PP=$(asc subscriptions price-points list --subscription-id "$SUB_ID" --territory USA \
| jq -r '.data[] | select(.customerPrice == "9.99") | .id')
asc subscriptions prices set --subscription-id "$SUB_ID" --territory USA --price-point-id "$USA_PP"
# 3. Review screenshot + submit (first-time subscription: with the app version instead,
# `asc versions submit --version-id "$VERSION_ID" --with-products`)
asc subscription-review-screenshot upload --subscription-id "$SUB_ID" --file ./review.png
asc subscriptions submit --subscription-id "$SUB_ID"
# 4. Promotional offer with per-territory pricing
asc subscription-promotional-offers create --subscription-id "$SUB_ID" \
--name "Loyalty25" --offer-code loyalty25 \
--duration THREE_MONTHS --mode PAY_AS_YOU_GO --periods 3 \
--price USA=$USA_PP
# 5. Win-back campaign
asc win-back-offers create --subscription-id "$SUB_ID" \
--reference-name "Lapsed Q4" --offer-id lapsedQ4 \
--duration ONE_MONTH --mode FREE_TRIAL --periods 1 \
--paid-months 3 --since-min 1 --since-max 6 --wait-months 2 \
--start-date 2026-04-01 --end-date 2026-12-31 \
--priority HIGH --promotion-intent USE_AUTO_GENERATED_ASSETS
# 6. Offer code + one-time redemption batch
OC_ID=$(asc subscription-offer-codes create --subscription-id "$SUB_ID" \
--name "SUMMER2026" --duration ONE_MONTH --mode FREE_TRIAL --periods 1 \
--eligibility NEW --eligibility LAPSED --offer-eligibility STACKABLE \
| jq -r '.data[0].id')
asc subscription-offer-code-one-time-codes create --offer-code-id "$OC_ID" \
--number-of-codes 5000 --expiration-date 2026-12-31
# Distribute the codes:
asc subscription-offer-code-one-time-codes values --one-time-code-id <OTC_ID> > codes.csv
状态语义
SubscriptionState 提供语义布尔值:
| 布尔值 | 状态为以下值时为 True |
|---|---|
isEditable | MISSING_METADATA、REJECTED、DEVELOPER_ACTION_NEEDED |
isPendingReview | WAITING_FOR_REVIEW、IN_REVIEW |
isApproved / isLive | APPROVED |
SubscriptionCustomerEligibility ∈ NEW、LAPSED、WIN_BACK、PAID_SUBSCRIBER。
SubscriptionOfferEligibility ∈ STACKABLE、INTRODUCTORY、SUBSCRIPTION_OFFER。
WinBackOfferPriority ∈ HIGH、NORMAL。WinBackOfferPromotionIntent ∈ NOT_PROMOTED、USE_AUTO_GENERATED_ASSETS。
SubscriptionReviewScreenshot.AssetState 提供 isComplete 和 hasFailed。
JSON 输出中会省略值为 nil 的可选字段。PATCH 响应(更新命令)会返回父级 ID 为 "" 的资源,因为 ASC 的 PATCH 响应不包含父级 ID——如果需要父级,请通过 list 重新获取。
参考
完整的领域模型和 REST 详情,请参阅 docs/features/iap-subscriptions.md 和 iap-subscriptions/ 子文档(生命周期、定价、优惠码、群组本地化、促销优惠、挽回优惠、审核资源)。