Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Subscription Disclosure

ASecurity

Detects missing or obscured subscription disclosure elements on paywall screens, enforcing Guideline 3.1.2(c) requirements for auto-renewal terms, trial end dates, and actual price.

18 stars
0 votes
0 copies
0 views
Added 9/20/2026
developmentswiftbashreactangularapi

Works with

api

Security Analysis

A100/100

Scanned 9/20/2026

Install to Claude Code

$npx -y skills add cruisediary/apple-app-review-skills --skill subscription-disclosure --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Subscription Disclosure?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Subscription Disclosure
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/cruisediary-subscription-disclosure/badge)](https://www.skillsdirectory.com/skills/cruisediary-subscription-disclosure)

More formats (shields.io, HTML) on the badges page.

Download with Pro
Files
SKILL.md
---
name: subscription-disclosure
description: >-
  Detects missing or obscured subscription disclosure elements on paywall screens, enforcing Guideline 3.1.2(c) requirements for auto-renewal terms, trial end dates, and actual price.
---

# Skill: Subscription Disclosure
<!-- SEO: subscription auto-renewal disclosure free trial paywall price billing period cancellation Guideline 3.1.2 iOS App Store rejection -->

## Purpose
Detects missing or obscured subscription disclosure elements (auto-renewal, trial end terms, cancellation instructions, actual price) on paywall screens, enforcing Guideline 3.1.2(c).

## Apple Guideline
- **Primary:** 3.1.2(c) — Business: Payments — Subscriptions: Disclosure Requirements
- **Related:** 3.1.2(a), 3.1.2(b)
- **Reference:** `references/guidelines/3-business.md`

## Real-World Rejection Cases
- **Case:** Paywall shows "50% OFF" prominently — actual billing amount ($9.99/month) shown in 10pt gray text below fold — rejected
  **Source:** https://developer.apple.com/forums/thread/127616
  **Root cause:** 3.1.2(c) requires billed amount shown clearly and conspicuously — size/color/placement must not obscure it; discounts shown without clear pricing are a known rejection trigger

- **Case:** Free trial paywall shows "Try free for 7 days" with no mention of what happens after trial — rejected
  **Source:** RevenueCat Community (https://community.revenuecat.com/general-questions-7/rejected-due-to-guideline-3-1-2-business-payments-subscriptions-4775)
  **Root cause:** Must clearly state amount billed after trial ends and when billing starts

- **Case:** App rejected for subscription auto-renewal not disclosed — "billed amount not clearly displayed"
  **Source:** blog.wenhaofree.com/en/posts/articles/app-store-guideline-3-1-2-subscription-fix/
  **Root cause:** Auto-renewable subscription purchase flow must state renewal continues until cancelled

- **Case:** Paywall had no links to Privacy Policy or Terms of Use — reviewer required legal doc links before purchase could proceed — rejected under 3.1.2(c)
  **Source:** AngularCorp blog (angularcorp.com/en-us/blog/guideline-3-1-2)
  **Root cause:** Subscription paywalls must include accessible links to Privacy Policy and Terms of Use; reviewers verify these links exist and are functional before approving

- **Case:** Paywall showed price as "from $1.67/month" calculated from an annual plan — reviewer expected to be billed $1.67/month but actual charge was $19.99/year — rejected
  **Source:** AppFollow (appfollow.io/blog/app-store-rejection-reasons)
  **Root cause:** If billing is annual, the displayed price must be the annual amount or clearly labeled as "billed annually at $X"; showing only the monthly equivalent without disclosing actual charge is a known rejection pattern

## Trigger
Invoke on any iOS/macOS project with subscription or in-app purchase paywalls.

## Inputs
| Name | Type | Default | Description |
|------|------|---------|-------------|
| `project_root` | path | cwd | iOS/macOS project root |
| `shared_context` | object | nil | Pre-collected context from appstore-full-audit Phase 1 |

## Actions

### Phase 1: Context Collection
*Skip this phase if `shared_context` is provided.*

1. `Glob` `**/*Paywall*` or `**/*Subscription*` or `**/*Premium*` or `**/*Pricing*` — locate paywall and subscription UI files.
2. `Glob` `**/*.swift` — collect all Swift source files for broader search.

### Phase 2: Checks

Search primarily in paywall/subscription view files (`*Paywall*`, `*Subscription*`, `*Premium*`, `*Pricing*`). Fall back to all `**/*.swift` if no dedicated files found.

1. **Auto-renewal disclosure**
   `Grep` pattern `"auto-renew"|"automatically renew"|"renews automatically"|"auto renew"|"recurring"` in subscription/paywall files.
   If absent → 🔴 CRITICAL. Every auto-renewable subscription paywall must disclose that the subscription renews automatically until cancelled.

2. **Trial end disclosure**
   `Grep` pattern `"after.*trial|trial ends|then.*per|after.*free|billed after|charged after"` in subscription/paywall files.
   If a free trial is offered but this disclosure is absent → 🔴 CRITICAL. Users must know what they will be charged when the trial ends.

3. **Cancellation information**
   `Grep` pattern `"cancel anytime"|"cancelable"|"Cancel in Settings"|"manage.*subscription"|"cancell"` in subscription/paywall files.
   If absent → 🟠 HIGH. Instructions for cancellation must be accessible from the subscription UI.

4. **Actual price display**
   `Grep` pattern `displayPrice|localizedPrice|priceLocale|price\.formatted|priceString` in subscription/paywall files.
   If absent → 🔴 CRITICAL. The actual billed price must be displayed, not only a discount label. Must use StoreKit's localized price APIs to show the correct price for the user's region.

5. **Discount without price**
   `Grep` pattern `"% off"|"save.*%"|"discount"|"OFF"` in subscription/paywall files.
   If found, verify `displayPrice|localizedPrice` also present in same file → 🟠 HIGH if price display absent. Showing a discount without the absolute price is a known rejection pattern.

6. **Billing period disclosure**
   `Grep` pattern `subscriptionPeriod|subscription_period|billingPeriod|"per month"|"per year"|"monthly"|"annually"|"weekly"` in subscription/paywall files.
   If absent → 🟠 HIGH. Billing frequency must be clearly stated alongside the price.

7. **Family Sharing disclosure (Guideline 3.1.2(d))**
   `Grep` pattern `isFamilyShareable|familyShared|familySharable` in `**/*.swift`.
   If Family Sharing is enabled on any subscription product: verify a disclosure is present on the paywall such as "Shareable with up to 5 family members" → 🟡 MEDIUM if absent. Guideline 3.1.2(d) requires communicating Family Sharing eligibility to users before purchase.

### Phase 3: Output
Collect all findings from Phase 2 and build the prioritised findings list below. Include file paths and line numbers. Omit tiers with no findings.

## Output Format

```
## Subscription Disclosure — Findings

### 🔴 CRITICAL — Guaranteed rejection
- [ ] TODO: Add auto-renewal disclosure text to paywall — e.g., "Subscription automatically renews unless cancelled" — `PaywallView.swift` — Guideline 3.1.2(c)
- [ ] TODO: Add post-trial billing disclosure — state what amount is charged after the free trial ends — `SubscriptionView.swift:45` — Guideline 3.1.2(c)
- [ ] TODO: Display actual localized price using displayPrice or localizedPrice — price absent from paywall UI — `PremiumView.swift` — Guideline 3.1.2(c)

### 🟠 HIGH — Very likely rejection
- [ ] TODO: Add cancellation instructions — e.g., "Cancel anytime in iPhone Settings > Subscriptions" — `PaywallView.swift` — Guideline 3.1.2(c)
- [ ] TODO: Show actual monthly price alongside "50% OFF" discount label — discount without price is a rejection pattern — `PaywallView.swift:88` — Guideline 3.1.2(c)
- [ ] TODO: Display billing period (monthly/annually/weekly) next to the price — `SubscriptionView.swift:34` — Guideline 3.1.2(c)

### 🟡 MEDIUM — Possible rejection
- [ ] TODO: Verify disclosure text is visually conspicuous — not in small gray font below the fold — manual UI review required

### 🟢 LOW — Best practice
- [ ] TODO: Follow Apple's subscription UI guidelines — use clear, high-contrast disclosure text near the CTA button, not in footnotes
```

## Tools Used
`Glob`, `Grep`, `Read`

## Constraints
- Read-only. No file edits.
- No network calls.
- Skip Phase 1 if `shared_context` is provided by orchestrating agent.
- Works on Swift, Objective-C, React Native, Flutter projects.

## Quick Commands

Run these in your project root to check manually:

```bash
# Check for auto-renewal disclosure text
!grep -rn "auto-renew\|automatically renew\|renews automatically" . --include="*.swift" -i

# Check for trial disclosure
!grep -rn "after.*trial\|trial ends\|then.*per\|free trial" . --include="*.swift" -i

# Check for actual price display (not just discount)
!grep -rn "displayPrice\|localizedPrice\|priceLocale\|price\b" . --include="*.swift" | grep -v "//"

# Check for discount-only display (missing actual price)
!grep -rn "% off\|save.*%\|discount" . --include="*.swift" -i
```

## Swift Anti-Pattern Reference
`examples/swift/SubscriptionPatterns.swift`

## Detection Steps

1. **Find target files**
   - Glob: `**/*.swift`, `**/*.m`, `**/*.storyboard`, `**/*.xib`, `**/*.strings`

2. **Search for rejection patterns**
   - Grep `freeTrialPeriod\|trialPeriod\|free.*[Tt]rial\|freeTrial` — trial UI elements
   - Grep `subscriptionPrice\|priceLocale\|localizedPrice\|displayPrice` — price display
   - Grep `autoRenew\|auto-renew\|automatically renews\|autoRenewing` — renewal disclosure text
   - Grep `%.*off\|[Dd]iscount\|[Ss]ave.*%` — discount claims

3. **Determine verdict**
   - Trial UI found + no `autoRenew`/`automatically renews` text near it → 🟠 HIGH (Guideline 3.1.2(c))
   - Discount percentage shown + no actual billed amount displayed → 🟠 HIGH
   - `localizedPrice` displayed + renewal terms present → 🟢 pass

4. **Report**
   - File path + line of trial/discount UI without disclosure
   - Fix: Add "Then [price]/[period], cancel anytime" text directly below the CTA; show actual price alongside any discount percentage

Attribution

cruisediarycruisediary
View sourceMore from cruisediary →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

284972 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2222 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

10311 votes

Pentest

PTES-aligned adversarial security audit for backend, frontend, and mobile applications. Produces a CVSS-scored Hacker Report with verified PoCs and phased remediation.

5491 votes
View all in development →