Skip to main content
ZeroSettle provides three campaign types to grow and retain subscribers. All are configured from the ZeroSettle dashboard with built-in analytics — no app update required to change targeting, messaging, or pricing.

Migration Campaigns (Switch & Save)

Migration campaigns help you move existing StoreKit or Play Store subscribers to web checkout at a discount. This eliminates platform fees on future renewals while giving users a lower price.

Configuration

Enable migration campaigns on the dashboard and configure:
FieldDescription
Product IDThe web checkout product to offer
Discount %Percentage off the web price (0-100%)
Min subscription daysMinimum days subscribed before eligibility (default 30)
Rollout %Percentage of eligible users who see the campaign (0-100%, for gradual rollout)
Eligible product IDsWhich store product IDs qualify for migration
TitleCampaign heading — supports {{discount}} template variable
MessageCampaign body text — supports {{discount}} template variable
CTA textButton text — supports {{discount}} template variable

SDK Integration

The SDK returns campaign data in ProductCatalog.config.migration. Use the built-in ZSMigrateTipView for a drop-in UI, or read the data to build your own:
let catalog = try await ZeroSettle.shared.fetchProducts(userId: user.id)

if let migration = catalog.config?.migration {
    // Show migration prompt to eligible users
    print("\(migration.title): \(migration.discountPercent)% off")
}
After a successful migration purchase, track the conversion:
try await ZeroSettle.shared.trackMigrationConversion(userId: user.id)

Analytics

The dashboard tracks migration campaign performance:
MetricDescription
ImpressionsNumber of times the campaign was shown
ConversionsNumber of users who completed the migration
Conversion rateConversions / impressions

SDK Integration

See Switch & Save for the full migration UI integration guide.

Upgrade Offers

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

Configuration

Enable upgrade offers on the dashboard and configure:
FieldDescription
Upgrade pathsList of from_product_id to to_product_id mappings
Eligible product IDsWhich products qualify for upgrade offers
Min subscription daysMinimum days subscribed before eligibility (default 0)
TitleOffer heading — supports {savings_percent} and {target_name} template variables
BodyOffer body text — supports {savings_percent} and {target_name} template variables
CTA textAccept button text
Dismiss textDecline button text
StoreKit bodySeparate body text for users migrating from Apple billing
StoreKit cancel instructionsInstructions shown to Apple subscribers for cancelling their App Store subscription

SDK Integration

Present the upgrade offer using a SwiftUI modifier or the programmatic API:
@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, .dismissed:
        break
    }
}

Analytics

MetricDescription
ImpressionsNumber of times the upgrade offer was shown
Upgrades completedNumber of users who accepted the upgrade
Conversion rateUpgrades / impressions

SDK Integration

See Upgrade Offers for the full SDK integration guide.

Promotions

Promotional pricing lets you offer discounts on any product. Promotions are configured per-product on the dashboard and surfaced automatically in the SDK product data.

Configuration

FieldDescription
Display nameLabel shown to users (e.g., “Launch Sale”)
Typepercent_off, fixed_amount, or free_trial
Promotional priceThe discounted price during the promotion
ExpirationOptional expiry date — no expiration means the promotion runs indefinitely

Accessing Promotions

Active promotions are returned alongside product data. No separate fetch is needed:
if let promo = product.promotion {
    print("\(promo.displayName): \(promo.promotionalPrice.formatted)")
}
Promotions surface automatically in SDK product data. Create, update, or end promotions from the dashboard at any time — no code change required.