storebound/skills/store-subscriptions/SKILL.md
CRT b63f2fdfbc Store operations: TestFlight wait / expire, IAP review submissions, listing pulls, release notes per language, offers, custom product pages, in-app events, reports, triage, keyword ranks, AdAttributionKit scan
- apple testflight wait --build N (progress, timeout, exit 0/1/7) and expire --keep N | --older-than D (dry run, asks)
- apple iap-submit: IAP / subscription / group versions into a review submission; first of a type only with the app
  version (--with-version), --no-submit keeps the draft; read-only MCP plan
- apple listing pull, play listing pull (diff, --write), catalog pull (config proposal, never rewritten)
- whats-new --languages / check / apply: one file per language, agent or hook translation, per-store limits
- apple offer-codes, win-back, promoted, preorder; Play pre-registration as a guide (no API)
- apple cpp and apple events: list, create, upload, submit (asks)
- reports: Apple sales / finance, Play earnings / sales into .storebound/reports with summary and CSV
- triage: TestFlight crash / feedback and Play error reports grouped by signature, device, OS
- aso rank: iTunes Search API ranks and competitors, rate limited
- ads scan: AdAttributionKit / SKAdNetwork Info.plist and source checks
- tests against recorded, sanitized answers; skills, README, CHANGELOG
2026-10-11 23:58:17 +08:00

66 lines
5.7 KiB
Markdown

---
name: store-subscriptions
description: Set up auto-renewable subscriptions on the App Store and Google Play from one config - Apple subscription groups, levels, localizations, equalized prices with overrides and a price CSV, introductory offers, promotional offers, offer codes and custom codes; Play subscriptions with base plans, regional prices, intro and developer-chosen offers; first submission with a version, the disclosure Apple 3.1.2 and Play's subscription policy require, Terms of Use (EULA) links, price changes and the catalog parity report. Use when the user sells subscriptions, adds a free trial, changes subscription prices, or gets a 3.1.2 / subscription policy rejection.
---
# Subscriptions on both stores
CLI: `storebound apple subscriptions`, `storebound play subscriptions` (both `--dry` first; they print the plan and
ask before writing), `storebound catalog diff` (read-only parity of the whole catalog), `storebound validate`.
Config: `subscriptions: [{ name, listings, subscriptions: [{ id, period, level, usd, overrides, listings, intro,
offers, offerCodes, reviewScreenshot, basePlanId, gracePeriod, platforms }] }]`, `app.termsUrl`.
## Model
- **Apple**: a subscription group per product line (people hold one subscription per group); `level` 1 = highest
service (upgrades and downgrades follow it). Prices: the USA price point for `usd`, its equalizations for every
territory, then `overrides` and rows from `--csv store/prices.csv` (same CSV as `storebound prices`, rows with a
future `start_date` become scheduled price changes). `preserveCurrentPrice` is always true: existing subscribers keep
their price; raising it for them is a separate, consent-bound step in App Store Connect.
- **Google Play**: no groups. Each entry is a Play subscription with one auto-renewing base plan (`basePlanId`
default from the period: monthly, yearly, ...), prices from `convertRegionPrices` + overrides + CSV. A base plan price
change applies to new subscribers; existing ones keep their price until you run a price migration in the Console.
- **Intro offer** (`intro`): free trial, pay as you go (`periods` at `usd`), or pay up front. Apple: per territory,
first-time subscribers of the group. Play: an offer for people who never had this subscription (pay as you go is a
relative discount, so it follows every regional price).
- **Promotional offers** (`offers`, Apple + Play): Apple promotional offers (your server signs them at purchase
time); Play offers with an offer tag and no acquisition targeting (your app decides who sees them).
- **Offer codes** (`offerCodes`, Apple): a campaign (eligibility NEW / EXISTING / EXPIRED, replace or stack with the
intro offer). Custom codes are created only with `--codes` from a terminal that confirms (anyone with the code can
redeem it). One-time-use codes: the owner generates them in App Store Connect. **Play promo codes have no API**:
Play Console > Monetize > Promo codes.
## Steps
1. Prerequisites: Apple Paid Applications agreement, banking and tax; Play payments profile and a build with the
billing library on a track.
2. `storebound check` (limits: Apple name 30 / description 45; Play description 200, up to 4 benefits).
3. `storebound apple subscriptions --dry` and `storebound play subscriptions --dry`; read the plan with the owner; then
run them in a terminal (they ask). Through MCP (no terminal) they only create what is new; price changes of
existing subscriptions wait for the owner.
4. Review screenshot of the paywall per subscription (`reviewScreenshot`), uploaded by `apple subscriptions`.
5. **First subscriptions go with an app version** (and a new group with at least one of its subscriptions):
`storebound apple iap-submit --with-version --dry` plans one review submission with the app version, the
subscription versions and the group version; the owner runs it without `--dry` (it asks, and submitting it submits
the app), or adds `--no-submit` and presses "Submit for Review" in App Store Connect. Details and the exact limits:
store-iap-setup skill, step 3.
5b. **Win-back offers** for lapsed subscribers (`winBack` on a subscription, `storebound apple win-back`) once the
subscription is approved: app-store-promotion skill.
6. `storebound validate` (states, localizations, group names, review screenshots, active Play base plans, terms URL)
and `storebound catalog diff` (both stores against the config, prices per region).
## Disclosure (review checks it)
- Purchase screen: plan name, length, **full renewal price per period as the most prominent price**, what is included,
trial length and what is charged after it, how to cancel, Restore Purchases, links to the **Terms of Use** and the
**Privacy Policy** (Apple 3.1.2 and "Clearly describing subscriptions",
https://developer.apple.com/app-store/subscriptions/; Google Play subscriptions policy,
https://support.google.com/googleplay/android-developer/answer/9900533).
- Metadata: the Terms of Use link in the App Store description, or a custom EULA in App Information > License
Agreement; the privacy policy URL field (`storebound apple listing`). `validate` warns when a description has no
Terms link. 3.1.2(a): a subscription must give ongoing value and last at least 7 days.
- Review notes: where the paywall is, that the demo account can buy in the sandbox (`review-access`).
## Gotchas
- A product id, a billing period or a subscription's group cannot change; make a new id.
- Apple applies one introductory offer per customer per group; offers cannot be edited, only replaced.
- Account deletion does not cancel a subscription: say so (`account-deletion`).
- Unverified (no live account during development): free promotional offers and offer codes are sent with
territories but no price point; check the first run in App Store Connect.