Feature · Paywall · Conversion
Intro offers
Free trials and discounted intro periods ("$0.99 first month, then $9.99/month") dramatically lift trial conversion. Stubkit supports three intro-related concerns: catalog configuration, eligibility checking, and render-side display on paywalls.
1. Configure on the product
Every product can have intro_price_cents, intro_period_days, intro_periods_count. The first two are self-explanatory; the third lets you do "first 3 months at $4.99" (count = 3, period_days = 30).
await stubkitAdmin.createProduct({
app_id: 'taskpomo',
product_id: 'pro_monthly',
platform: 'ios',
price_usd_cents: 999,
intro_price_cents: 99, // $0.99
intro_period_days: 30,
intro_periods_count: 1,
});The Apple catalog sync auto-populates intro fields from App Store Connect where available. Google Play's equivalent (base plans with offer tags) is not auto-synced yet — set manually.
2. Eligibility check
Pass ?user_id= to the public offerings endpoint. Stubkit checks whether the user has any prior subscription on this app and returns intro_eligible: boolean.
GET /v1/offerings/taskpomo/default?user_id=user-123
{
"intro_eligible": true,
"products": [
{
"product_id": "pro_monthly",
"price_usd_cents": 999,
"intro_price_cents": 99,
"intro_period_days": 30,
...
}
]
}A user is considered eligible when they have no prior subscription for that app — mirrors Apple's StoreKiteligibility model. Family-shared rows don't disqualify (a family member who later buys their own is still eligible).
3. Render in paywall
The SDK's getOffering() returns the intro fields when present. Show the intro price when intro_eligible, the full price otherwise:
const offering = await stubkit.getOffering('default');
const product = offering.products[0];
const displayPrice = offering.intro_eligible && product.intro_price_cents
? formatPrice(product.intro_price_cents, offering.display_currency)
: formatPrice(product.price_usd_cents, offering.display_currency);
// Show something like:
// "Try Pro — $0.99 for your first month, then $9.99/month"Detection in webhooks
Apple notifications with offerType === 1 (introductory offer) set subscriptions.intro_active = 1. Analytics can split trial-to-paid conversion rate between intro vs. full-price purchases via this flag.