iOS App Store Review Guidelines for IAP
Este contenido aún no está disponible en tu idioma.
Getting your app approved on the App Store requires careful attention to Apple’s guidelines, especially when implementing in-app purchases and subscriptions. This guide covers everything you need to know to pass review on your first submission.

In-App Purchase Requirements
Pricing Transparency (Critical)
Apple requires crystal-clear pricing disclosure before any purchase:
Must-Have Elements:
- Display exact price before purchase button
- Show billing frequency (e.g., “$9.99/month”)
- Clearly state what users get for their money
- Indicate when charges will occur
Common Rejection:
“Subscription pricing must be clear and upfront.”
:::caution Price Consistency All prices must match across:
- App Store metadata listing
- In-app purchase screens
- Subscription management screens
Even a $1 discrepancy between store listing ($4.99) and app ($5.99) will trigger automatic rejection. :::
Subscription Plan Presentation
Required Disclosures:
- All available subscription tiers displayed together
- Clear comparison of features per tier
- No auto-defaulting to premium tiers through UI tricks
- Easy-to-locate cancellation instructions

Example of Compliant UI:
import { NativePurchases } from '@capgo/native-purchases';
function SubscriptionScreen() { return ( <div> <h2>Choose Your Plan</h2>
{/* Show all tiers equally */} <PlanCard title="Basic" price="$4.99/month" features={['Feature A', 'Feature B']} /> <PlanCard title="Premium" price="$9.99/month" features={['All Basic', 'Feature C', 'Feature D']} highlighted={false} // Don't force premium />
{/* Clear cancellation info */} <Text> Cancel anytime in Settings > Subscriptions. No refunds for partial periods. </Text> </div> );}Restore Purchases
Required Implementation:
Every app with IAP must provide a way for users to restore previous purchases without contacting support.
import { NativePurchases } from '@capgo/native-purchases';
async function restorePurchases() { try { const { customerInfo } = await NativePurchases.restorePurchases();
if (customerInfo.activeSubscriptions.length > 0) { showMessage('Purchases restored successfully!'); unlockPremiumFeatures(); } else { showMessage('No previous purchases found.'); } } catch (error) { showError('Failed to restore purchases. Please try again.'); }}
// Add a visible "Restore Purchases" button<Button onClick={restorePurchases}> Restore Purchases</Button>Common Rejection Reasons
1. App Crashes or Broken Functionality
Why It Fails:
- App crashes on launch
- Purchase flow fails to complete
- Features shown in screenshots don’t work
Prevention:
- Test on real devices (not just simulators)
- Test all subscription flows end-to-end
- Verify receipt validation works
- Check network error handling
2. Metadata Mismatches
Why It Fails:
- Screenshots show features not in current build
- Description mentions functionality that doesn’t exist
- Pricing in metadata differs from in-app pricing

Prevention:
// Document exactly what's in each tierconst SUBSCRIPTION_FEATURES = { basic: ['Ad-free', 'Cloud sync', 'Basic themes'], premium: ['Ad-free', 'Cloud sync', 'All themes', 'Priority support']};
// Use these in both your app AND App Store description3. Missing Permission Explanations
Why It Fails:
- Requesting camera/location/health without explanation
- Permission requests buried multiple screens deep
- Vague or generic permission descriptions
Prevention:
Update your Info.plist with clear explanations:
<key>NSCameraUsageDescription</key><string>Camera access is needed to scan product barcodes for quick subscription upgrades.</string>
<key>NSLocationWhenInUseUsageDescription</key><string>Location helps us show relevant local content in your Premium subscription.</string>4. Misleading Marketing
Why It Fails:
- Claims like “#1 app in world” without proof
- “Unlimited” features that have hidden limits
- Fake urgency tactics (“Only 2 spots left!”)


Prevention:
- Be specific and factual in descriptions
- Avoid superlatives without evidence
- Don’t pressure users with fake scarcity
5. Hidden Cancellation Process
Why It Fails:
- No mention of how to cancel
- Cancellation button hidden or obscured
- Multi-step cancellation process without Apple’s native flow
Prevention:
// Always inform users about cancellationfunction SubscriptionInfo() { return ( <div> <h3>How to Cancel</h3> <ol> <li>Open iPhone Settings</li> <li>Tap your name at the top</li> <li>Tap Subscriptions</li> <li>Select this app and tap Cancel</li> </ol>
<p>Or manage directly in the App Store app.</p>
<Button onClick={openSubscriptionManagement}> Manage Subscription in Settings </Button> </div> );}
async function openSubscriptionManagement() { // Direct link to iOS subscription management await NativePurchases.showManageSubscriptions();}Privacy & Data Usage (Section 5.1.1)
Apple has significantly tightened privacy requirements in 2025.
Required Disclosures
For Every Permission:
- Why you need it (specific use case)
- When it will be used
- How data is stored/shared
- Whether it’s optional or required
Example: Proper Permission Flow
async function requestCameraPermission() { // Show explanation BEFORE requesting await showDialog({ title: 'Camera Access', message: 'We need camera access to let you scan barcodes for quick product lookup. Your photos are never uploaded or stored.', buttons: ['Not Now', 'Allow'] });
// Then request permission const result = await Camera.requestPermissions(); return result.camera === 'granted';}Privacy Nutrition Labels
Ensure your App Store privacy labels accurately reflect:
- Purchase history collection
- Email addresses (for receipts)
- Device IDs (for fraud prevention)
- Usage data (for analytics)
Inaccurate privacy labels are a common rejection reason in 2025. Audit your data collection carefully.
Pre-Submission Checklist

-
Test All Purchase Flows
- Buy each subscription tier
- Test free trials
- Verify introductory offers apply correctly
- Test restore purchases
- Verify Family Sharing (if enabled)
- Test on multiple devices
-
Verify Pricing Consistency
- Check App Store metadata matches in-app prices
- Verify all currencies are correct
- Confirm free trial durations match descriptions
- Check introductory offer terms are accurate
-
Review All Copy
- Remove placeholder text
- Verify claims are testable
- Check grammar and spelling
- Ensure descriptions match current build
- Remove competitor mentions
-
Test Permissions
- Request only necessary permissions
- Show clear explanations before requesting
- Test “Deny” flows (app should still work)
- Verify Info.plist descriptions are clear
-
Prepare Test Account
- Create sandbox test account
- Document login credentials in App Review Notes
- Verify test account has active subscription
- Test that reviewer can complete purchase flow
-
Check Metadata
- Screenshots match current UI
- App preview video (if any) shows current version
- Description accurately describes features
- Age rating matches content
- Privacy policy is accessible in-app
-
Write Detailed Review Notes
Test Account:Email: reviewer@test.comPassword: TestPass123!Testing Instructions:1. Log in with test account above2. Tap "Upgrade to Premium" button3. Select "Monthly Premium" subscription4. Complete purchase (no charge in sandbox)5. Verify premium features unlockNote: Subscription pricing is clearly shown before purchase.Cancellation instructions are in Settings > Account.
Review Timeline

Standard Review: 24-48 hours Peak Periods: 3-5 days (App Store holiday releases) Weekends: No reviews processed Expedited Review: Available for critical bug fixes (request via App Store Connect)
2025 Guideline Updates
New Requirements
1. AI Functionality Disclosure If your app uses AI for any features, you must:
- Clearly label AI-generated content
- Explain how AI is used
- Document content safety measures
2. Enhanced Subscription Clarity
- Side-by-side plan comparisons required
- No “dark patterns” that hide cheaper options
- Clear downgrade/upgrade paths
3. Privacy Intensification
- Section 5.1.1 enforcement increased
- More scrutiny on data collection justification
- Stricter requirements for children’s apps
What Changed from 2024
- Modular submissions now allowed (update product pages independently)
- In-app events can be submitted separately
- Stricter enforcement of misleading subscription UIs
- New guidance on cryptocurrency/NFT apps
Best Practices for Native Purchases Plugin
Implement Proper Error Handling
import { NativePurchases } from '@capgo/native-purchases';
async function handlePurchase(productId: string) { try { const { customerInfo } = await NativePurchases.purchaseProduct({ productIdentifier: productId });
// Success showSuccess('Subscription activated!'); unlockFeatures();
} catch (error: any) { // Handle specific error cases if (error.code === 'USER_CANCELLED') { // User cancelled - don't show error console.log('Purchase cancelled by user'); } else if (error.code === 'PAYMENT_PENDING') { showInfo('Payment is pending. Please check back later.'); } else if (error.code === 'PRODUCT_ALREADY_PURCHASED') { // Restore instead await NativePurchases.restorePurchases(); } else { // Show user-friendly error showError('Unable to complete purchase. Please try again.'); } }}Display Loading States
function PurchaseButton({ productId }: { productId: string }) { const [loading, setLoading] = useState(false);
const handlePurchase = async () => { setLoading(true); try { await NativePurchases.purchaseProduct({ productIdentifier: productId }); } finally { setLoading(false); } };
return ( <button onClick={handlePurchase} disabled={loading}> {loading ? 'Processing...' : 'Subscribe Now'} </button> );}Show Terms Clearly
function SubscriptionTerms() { return ( <div className="terms"> <p> Subscription automatically renews unless cancelled at least 24 hours before the end of the current period. </p> <p> Your account will be charged for renewal within 24 hours prior to the end of the current period. </p> <p> Subscriptions may be managed by the user and auto-renewal may be turned off in Account Settings after purchase. </p> <p> <a href="/terms">Terms of Service</a> | <a href="/privacy">Privacy Policy</a> </p> </div> );}If Your App Gets Rejected
Steps to Resolve
-
Read the rejection carefully
- Note the specific guideline cited (e.g., 3.1.1, 5.1.1)
- Understand exactly what Apple flagged
-
Fix the issue thoroughly
- Don’t just patch - fix root cause
- Test the fix extensively
- Document what you changed
-
Respond in Resolution Center
Thank you for your feedback. I have addressed the issue:Issue: Subscription pricing not clear upfrontFix: Added explicit pricing display on subscription selectionscreen showing "$9.99/month" before purchase button. Also addedcancellation instructions on the same screen.The changes are in this submission and can be tested using theprovided test account. -
Resubmit promptly
- Resubmissions are typically reviewed faster
- Usually within 24 hours
Appeal Process
If you believe the rejection is incorrect:

- Click “Appeal” in App Store Connect
- Provide clear evidence:
- Screenshots showing compliance
- References to specific guidelines
- Explanation of how you meet requirements
- Be professional and factual
- Include test account if functionality is hard to find

Additional Resources
- Apple App Store Review Guidelines
- In-App Purchase Guidelines
- Subscriptions Best Practices
- App Store Connect Help
Support
If you’re still having issues:
- Review the Native Purchases documentation
- Check common troubleshooting issues
- Contact Apple Developer Support for guideline clarifications
Need Expert Help?
Struggling with app review or need personalized assistance? Book a consultation call with our team for dedicated support with:
- IAP implementation review and optimization
- App Store review preparation and strategy
- Submission checklist review
- Rejection resolution and appeals
- Complete testing and validation
Our experts have successfully helped hundreds of apps pass review!