Passer au contenu

iOS Application Store Review Guidelines for IAP

Getting your Application approved on the Application Store requires careful attention to Apple’s guidelines, especially when implementing in-Application purchases and subscriptions. This Guide covers everything you need to know to pass review on your first submission.

iOS Application Store Review Process

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 Utilisateurs get for their money
  • Indicate when charges will occur

Common Rejection:

“Subscription pricing must be clear and upfront.”

:::Attention Price Consistency All prices must match across:

  • Application Store metadata listing
  • In-Application purchase screens
  • Subscription management screens

Even a $1 discrepancy between store listing ($4.99) and Application ($5.99) will trigger automatic rejection. :::

Required Disclosures:

  • All Disponible subscription tiers displayed together
  • Clear comparison of Fonctionnalités per tier
  • No auto-defaulting to premium tiers through UI tricks
  • Easy-to-locate cancellation instructions

UI Design Dos and Don'ts

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>
);
}

Required Implementation:

Every Application with IAP must provide a way for Utilisateurs to restore Précédent purchases without contacting Support.

import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
async function restorePurchases() {
try {
await NativePurchases.restorePurchases();
const { purchases } = await NativePurchases.getPurchases({
productType: PURCHASE_TYPE.SUBS,
});
const activeSub = purchases.find(
(purchase) => purchase.isActive && purchase.expirationDate,
);
if (activeSub) {
unlockPremiumFeatures();
showMessage('Purchases restored successfully!');
return;
}
const { purchases: iaps } = await NativePurchases.getPurchases({
productType: PURCHASE_TYPE.INAPP,
});
const hasIap = iaps.some((purchase) => purchase.productIdentifier === 'premium_unlock');
showMessage(
hasIap ? 'Premium purchase restored!' : '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>

1. Application Crashes or Broken Functionality

Section titled “1. Application Crashes or Broken Functionality”

Why It Fails:

  • Application crashes on launch
  • Purchase flow fails to Terminé
  • Fonctionnalités shown in screenshots don’t work

Prevention:

  • Test on real Appareils (not just simulators)
  • Test all subscription flows end-to-end
  • Verify receipt validation works
  • Vérifier network Erreur handling

Why It Fails:

  • Screenshots show Fonctionnalités not in current Construction
  • Description mentions functionality that doesn’t exist
  • Pricing in metadata differs from in-Application pricing

Metadata Checklist

Prevention:

// Document exactly what's in each tier
const 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 description

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>

Why It Fails:

  • Claims like “#1 Application in world” without proof
  • “Unlimited” Fonctionnalités that have hidden limits
  • Fake urgency tactics (“Only 2 spots left!”)

Description Guidelines Exemples

Additional Description Guidelines

Prevention:

  • Be specific and factual in descriptions
  • Avoid superlatives without evidence
  • Don’t pressure Utilisateurs with fake scarcity

Why It Fails:

  • No mention of how to Annuler
  • Cancellation button hidden or obscured
  • Multi-step cancellation process without Apple’s Natif flow

Prevention:

// Always inform users about cancellation
function 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 Utilisation (Section 5.1.1)

Section titled “Privacy & Data Utilisation (Section 5.1.1)”

Apple has significantly tightened privacy requirements in 2025.

For Every Permission:

  1. Why you need it (specific use case)
  2. When it will be used
  3. How data is stored/shared
  4. Whether it’s optional or required
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';
}

Ensure your Application Store privacy labels accurately reflect:

  • Purchase history collection
  • Email addresses (for receipts)
  • Appareil IDs (for fraud prevention)
  • Utilisation data (for Analyse)

Inaccurate privacy labels are a common rejection reason in 2025. Audit your data collection carefully.

Pre-Submission Checklist

  1. 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 Appareils
  2. Verify Pricing Consistency

    • Vérifier Application Store metadata matches in-Application prices
    • Verify all currencies are correct
    • Confirm free trial durations match descriptions
    • Vérifier introductory offer terms are accurate
  3. Review All Copy

    • Retirer placeholder text
    • Verify claims are testable
    • Vérifier grammar and spelling
    • Ensure descriptions match current Construction
    • Retirer competitor mentions
  4. Test Permissions

    • Request only necessary permissions
    • Show clear explanations before requesting
    • Test “Deny” flows (Application should still work)
    • Verify Info.plist descriptions are clear
  5. Prepare Test Compte

    • Créer sandbox Test Compte
    • Document Connexion credentials in Application Review Notes
    • Verify Test Compte has Actif subscription
    • Test that reviewer can Terminé purchase flow
  6. Vérifier Metadata

    • Screenshots match current UI
    • Application preview video (if any) shows current Version
    • Description accurately describes Fonctionnalités
    • Age rating matches content
    • Privacy policy is accessible in-Application
  7. Write Detailed Review Notes

    Test Account:
    Email: reviewer@test.com
    Password: TestPass123!
    Testing Instructions:
    1. Log in with test account above
    2. Tap "Upgrade to Premium" button
    3. Select "Monthly Premium" subscription
    4. Complete purchase (no charge in sandbox)
    5. Verify premium features unlock
    Note: Subscription pricing is clearly shown before purchase.
    Cancellation instructions are in Settings > Account.

Application Store 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)

Soumettre early in the week to avoid weekend delays. Monday submissions typically get reviewed by Wednesday.

1. AI Functionality Disclosure If your Application uses AI for any Fonctionnalités, 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/Mise à niveau paths

3. Privacy Intensification

  • Section 5.1.1 enforcement increased
  • More scrutiny on data collection justification
  • Stricter requirements for children’s apps
  • Modular submissions now allowed (Mise à jour product pages independently)
  • In-Application events can be submitted separately
  • Stricter enforcement of misleading subscription UIs
  • Nouveau guidance on cryptocurrency/NFT apps
import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
async function handlePurchase(productId: string) {
try {
const transaction = await NativePurchases.purchaseProduct({
productIdentifier: productId,
productType: PURCHASE_TYPE.SUBS,
});
// Success
await validateReceiptOnServer(transaction.receipt);
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.');
}
}
}
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>
);
}
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>
);
}
  1. Read the rejection carefully

    • Remarque the specific guideline cited (e.g., 3.1.1, 5.1.1)
    • Understand exactly what Apple flagged
  2. Fix the Problème thoroughly

    • Don’t just patch - fix root cause
    • Test the fix extensively
    • Document what you changed
  3. Respond in Resolution Center

    Thank you for your feedback. I have addressed the issue:
    Issue: Subscription pricing not clear upfront
    Fix: Added explicit pricing display on subscription selection
    screen showing "$9.99/month" before purchase button. Also added
    cancellation instructions on the same screen.
    The changes are in this submission and can be tested using the
    provided test account.
  4. Resubmit promptly

    • Resubmissions are typically reviewed faster
    • Usually within 24 hours

If you believe the rejection is incorrect:

Application Store Clarification Process

  1. Click “Appeal” in Application Store Connect
  2. Provide clear evidence:
    • Screenshots showing compliance
    • References to specific guidelines
    • Explanation of how you meet requirements
  3. Be professional and factual
  4. Include Test Compte if functionality is hard to find

Request for Documents Exemple

If you’re still having issues:

Struggling with Application review or need personalized assistance? Book a consultation call with our team for dedicated Support with:

  • IAP implementation review and optimization
  • Application Store review preparation and strategy
  • Submission checklist review
  • Rejection resolution and appeals
  • Terminé Test and validation

Our experts have successfully helped hundreds of apps pass review!