Skip to main content
Upgrade offers prompt eligible subscribers to switch from shorter billing cycles (e.g., monthly) to longer ones (e.g., annual) at a savings. The SDK handles proration for existing web checkout subscribers and shows Apple cancel instructions for StoreKit-to-web migrations.

SwiftUI Modifier

The simplest way to present an upgrade offer is the .upgradeOffer() modifier:
@State private var showUpgradeOffer = false

Button("See Upgrade Options") {
    showUpgradeOffer = true
}
.upgradeOffer(
    isPresented: $showUpgradeOffer,
    productId: "premium_monthly",
    userId: currentUser.id
) { result in
    switch result {
    case .upgraded:
        showConfirmation("You've been upgraded!")
    case .declined:
        break
    case .dismissed:
        break
    }
}

Programmatic API

For more control over when and how offers are presented:
let result = await ZeroSettle.shared.presentUpgradeOffer(
    productId: "premium_monthly",
    userId: currentUser.id
)
// result is UpgradeOffer.Result: .upgraded, .declined, or .dismissed
The productId parameter specifies the user’s current product. The SDK fetches the configured upgrade target from the dashboard automatically.

Headless API

Fetch the upgrade offer configuration without presenting any UI. Use this to build a custom upgrade experience or to check eligibility before showing your own prompt.
let config = try await ZeroSettle.shared.fetchUpgradeOfferConfig(
    productId: "premium_monthly",
    userId: currentUser.id
)

if config.available, let target = config.targetProduct {
    // Show your own upgrade UI
    print("Save \(config.savingsPercent ?? 0)% by switching to \(target.name)")
} else {
    // User is not eligible — config.reason explains why
    print("Not eligible: \(config.reason?.description ?? "unknown")")
}
The config includes the current product, target product, savings percentage, proration details, and display copy — everything you need to render a custom offer.

Results

ResultDescription
upgraded / UpgradedUser accepted the offer and the upgrade was executed
declined / DeclinedUser explicitly declined the offer
dismissed / DismissedUser dismissed the sheet without acting

Upgrade Types

The SDK handles two upgrade scenarios automatically:
TypeDescription
web_to_webUser has an existing web checkout subscription. The SDK modifies the Stripe subscription in place with proration — the user pays the difference immediately and switches to the new billing cycle.
storekit_to_webUser has a StoreKit subscription. The SDK creates a new web checkout subscription and shows Apple cancel instructions so the user can stop their App Store billing.
The upgrade type is determined automatically based on the user’s current entitlement source. No code changes needed.

Dashboard Configuration

Upgrade offers are configured entirely from the ZeroSettle dashboard:
  • Upgrade paths — Map source products to target products (e.g., monthly → annual)
  • Messaging — Customize the title, body, CTA, and dismiss text. Use {savings_percent} and {target_name} template variables for dynamic copy
  • Minimum subscription age — Only show offers to users who have been subscribed for a minimum number of days
  • StoreKit migration messaging — Separate body text and cancel instructions for users migrating from Apple billing
Configure upgrade paths and messaging from the ZeroSettle dashboard. No code changes needed to update targeting or copy.

Next Steps