subscription-paywall

subscription-paywall is a skill for Claude Code, Codex from wangjianqi/AppStore. It costs 38 tokens per session (2,105 once invoked), scanned A, original, MIT.

An iOS subscription and paywall guide built around StoreKit 2, Apple’s framework for in-app purchases. It covers subscription products, checking paid access, optional server verification, and a reusable subscription manager.

In plain words
What is it for?
Use it when adding monthly or yearly subscriptions, displaying a paywall, checking current entitlements, tracking expiration dates, and handling purchase transactions.
Why use it?
It gives you a defined way to track purchases and decide whether a user has active paid access instead of piecing those checks together yourself.

Skill for Claude CodeCodex

Written for no agent in particular: nothing here depends on one.

Good fit Use it when adding monthly or yearly subscriptions, displaying a paywall, checking current entitlements, tracking expiration dates, and handling purchase transactions.

Compare 6 skills from other repositories ↓
Install with agentmods
npx agentmods add skills/wangjianqi/appstore/08-subscription-paywall
Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

Any agent
npx skills add wangjianqi/AppStore --skill 08-subscription-paywall
Clone the repo
git clone --depth 1 https://github.com/wangjianqi/AppStore

Made for: Claude Code, Codex.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for subscription-paywall

README.md
[![agentmods](https://agentmods.dev/badge/skills/wangjianqi/appstore/08-subscription-paywall.svg)](https://agentmods.dev/skills/wangjianqi/appstore/08-subscription-paywall)
Your own site
<a href="https://agentmods.dev/skills/wangjianqi/appstore/08-subscription-paywall"><img src="https://agentmods.dev/badge/skills/wangjianqi/appstore/08-subscription-paywall.svg" alt="Measured on agentmods" height="20"></a>
Per session 38 Skills are progressive disclosure: only the name and description are preloaded; the body loads when the skill is used.
When invoked 2,105 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. A grade says what 26 rules found in the file — not that it is safe.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.00038 $0.02105
Opus 5 $0.00019 $0.01052
Sonnet 5 $0.00008 $0.00421
Haiku 4.5 $0.00004 $0.00211

Measured 8d ago against content hash 688914921d1b, method: parsed. Prices are Anthropic first-party input rates as of 2026-09-08, from the pricing page.

Security

Grade A, and why

subscription-paywall scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 8d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

ios-claude-skills/08-subscription-paywall/SKILL.md · 293 lines

How it starts

The opening of the file, as written. The whole thing — 293 lines — stays where its author put it; the contents beside it link to each section on GitHub.

订阅 & Paywall

技术栈

  • StoreKit 2(iOS 15+)
  • 产品配置:App Store Connect → Subscriptions
  • 本地权益验证:Transaction.currentEntitlements
  • 服务端验证(可选):JWS Transaction 发送到后端校验

订阅产品结构

enum SubscriptionProduct: String, CaseIterable {
    case monthly  = "com.app.subscription.monthly"
    case yearly   = "com.app.subscription.yearly"
}

extension SubscriptionProduct {
    var displayName: String {
        switch self {
        case .monthly: return "月度会员"
        case .yearly: return "年度会员"
        }
    }

    var pricePerMonth: String {
        switch self {
        case .monthly: return "按月付费"
        case .yearly: return "按年付费(省 40%)"
        }
    }
}

SubscriptionManager 完整封装

import StoreKit

final class SubscriptionManager {
    static let shared = SubscriptionManager()

    private(set) var isPro: Bool = false
    private(set) var activeSubscription: SubscriptionProduct?
    private(set) var expirationDate: Date?

    var onEntitlementChanged: ((Bool) -> Void)?

    private var transactionListener: Task<Void, Never>?

    private init() {
        transactionListener = listenForTransactions()
        Task { await checkEntitlement() }
    }

    deinit {
        transactionListener?.cancel()
    }

    func loadProducts() async throws -> [Product] {
        let productIDs = SubscriptionProduct.allCases.map(\.rawValue)
        return try await Product.products(for: productIDs)
    }

    func purchase(_ product: Product) async throws -> Bool {
        let result = try await product.purchase()

        switch result {
        case .success(let verification):
            let transaction = try checkVerification(verification)
            await transaction.finish()
            await updateEntitlement(transaction)
            return true
        case .userCancelled:
            return false
        case .pending:
            return false
        @unknown default:
            return false
        }
    }

    func restorePurchases() async {
        try? await AppStore.sync()
        await checkEntitlement()
    }

    func checkEntitlement() async {
        var isSubscribed = false
        var latestTransaction: StoreKit.Transaction?

        for await result in Transaction.currentEntitlements {
            if case .verified(let transaction) = result {
                if transaction.productType == .autoRenewable,
                   transaction.revocationDate == nil {
                    isSubscribed = true
                    if latestTransaction == nil || transaction.expirationDate ?? .distantPast > latestTransaction?.expirationDate ?? .distantPast {
                        latestTransaction = transaction
                    }
                }
            }
        }

        isPro = isSubscribed
        if let transaction = latestTransaction {
            activeSubscription = SubscriptionProduct(rawValue: transaction.productID)
            expirationDate = transaction.expirationDate
        }
        onEntitlementChanged?(isPro)
    }

    private func listenForTransactions() -> Task<Void, Never> {
        Task.detached { [weak self] in
            for await result in Transaction.updates {
                if case .verified(let transaction) = result {
                    await transaction.finish()
                    await self?.updateEntitlement(transaction)
                }
            }
        }
    }

    private func updateEntitlement(_ transaction: StoreKit.Transaction) async {
        isPro = transaction.revocationDate == nil
        activeSubscription = SubscriptionProduct(rawValue: transaction.productID)
        expirationDate = transaction.expirationDate
        onEntitlementChanged?(isPro)
    }

    private func checkVerification(_ result: VerificationResult<StoreKit.Transaction>) throws -> StoreKit.Transaction {
        switch result {
        case .unverified(_, let error):
            throw error
        case .verified(let transaction):
            return transaction
        }
    }
}

Read the full file on GitHub · 293 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 8d ago First seen · 293 lines · 38 tokens per session scan A 688914921d1b

Subscribe to this mod's changes

subscription-paywall is a skill published in the GitHub repository wangjianqi/AppStore (11 stars, last pushed 3mo ago), licensed MIT. It adds 38 tokens to every session and 2,105 once invoked, about $0.0002 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.

Related

Other skills, from other repositories

user-journey-tracking

Track user journeys with intent context and friction signals. Use when instrumenting onboarding, checkout, or any multi-step flow where you need to understand WHY users fail.

nexus-labs-automation/mobile-observability · 39 tokens

onesub

Use this skill when the user wants to add in-app purchases (subscriptions, consumables, or non-consumables) to a React Native / Expo mobile app. onesub is the open-source server side of react-native-iap — one line of Express middleware validates Apple StoreKit 2 and Google Play Billing receipts. Pair it with the…

jeonghwanko/onesub · 0 tokens

storekit

In-app purchases and subscriptions on iOS/iPadOS/macOS with StoreKit 2 (iOS 26 era) — fetch products with Product.products(for:), buy with Product.purchase and switch on PurchaseResult (.success/.pending/.userCancelled), always unwrap VerificationResult (.verified/.unverified), gate access from…

TalissonVitorino/kmp-ios-skills · 242 tokens

ipaship-audit

Use when auditing iOS/Android app submissions for compliance with Apple App Store Review Guidelines or Google Play Developer Policies. Scan .ipa, .apk, or .zip files against official store policies, generate structured compliance reports, and identify violations with remediation steps.

atharvnaik1/ipaship-audit · 57 tokens

storekit

Implement, review, or improve in-app purchases and subscriptions using StoreKit 2. Use when building paywalls with SubscriptionStoreView or ProductView, processing transactions with Product and Transaction APIs, verifying entitlements, handling purchase flows (consumable, non-consumable, auto-renewable), implementing…

JordanCoin/ios-skills-collection · 110 tokens

ax-storekit

StoreKit 2 in-app purchases, subscriptions, transactions.

Kasempiternal/axiom-v2 · 16 tokens