I’m having an issue where Product.products(for:) returns an empty array in sandbox testing, even though my subscriptions appear fully configured in App Store Connect.
Setup:
iOS app using StoreKit 2 (async/await)
Two auto-renewable subscriptions configured
Both subscriptions show “Ready to Submit” status
Pricing set for all regions
Localization complete (English US)
Review screenshots uploaded
Review notes added
7-day free trial configured
Testing Environment:
Real device (iPhone, iOS 18+)
TestFlight build uploaded AFTER subscriptions marked Ready to Submit
Sandbox tester account logged in via Settings → Developer → Sandbox Apple Account
Cleared purchase history multiple times
What I See:
🛒 Fetching IAP products...
🛒 ✅ Products loaded: 0
🛒 ❌ No products found
What I’ve Tried:
Verified Product IDs match exactly (character-for-character)
Clean builds and fresh TestFlight installs
Multiple sandbox account sign-out/sign-in cycles
Cleared sandbox purchase history
Waited 24+ hours after metadata completion
Same StoreKit 2 code works in another app with non-consumable IAP
Code Sample:
private let productIDs = [
"com.myapp.monthly",
"com.myapp.yearly"
]
func loadProducts() async {
do {
let products = try await Product.products(for: productIDs)
print("Products loaded: \(products.count)")
} catch {
print("Failed: \(error.localizedDescription)")
}
}
Questions:
Is there additional propagation time needed for auto-renewable subscriptions vs non-consumables?
Are there any hidden metadata requirements beyond what shows in App Store Connect?
Has anyone experienced this where subscriptions simply never propagate to sandbox?
Any help appreciated. Already submitted a support case to Apple but looking for community insights.
Topic:
App Store Distribution & Marketing
SubTopic:
App Store Connect