跳过内容

iOS App Store Review Guidelines for IAP

GitHub

在 App Store 上发布应用程序需要仔细遵循 Apple 的指南,特别是在实现内购和订阅功能时。这个指南涵盖了您需要知道的所有内容,以便在第一次提交时通过审核。

iOS App Store Review 流程

在提交之前

在提交之前

添加

  • Add a 隐私政策链接 在 App Store Connect 中
  • 添加一个 支持链接 该链接指向用户的真实联系方式
  • 完成 年龄等级 context: Solution page app examples section. Role: Short UI label or navigation item. Seen in: component solutions/SolutionAppExample.astro. Message key `solution_app_examples_rating` (Solution App Examples Rating).
  • 问卷以便应用程序可以发布 添加 应用程序评论联系方式
  • 并清晰的评论者注释 __CAPGO_KEEP_0__
苹果会将支持网站视为一个真正的联系方式,而不是一个占位符。它应该包含用户可以联系您以报告应用问题、反馈和功能请求的真实联系方式。

应用商店列表元数据,包含政策和支持链接

准备真实截图
  • 标题:准备真实截图
  • 使用当前截图,从实际正在审查的构建中获取 1290 x 2796 对于iPhone来说
  • (6.7英寸)是最简单的默认尺寸
  • 如果您的应用程序支持iPad,请上传iPad截图 2064 x 2752 (13寸)和 2048 x 2732 (12.9寸)
  • 不拉伸iPhone截图来假装iPad支持

在TestFlight中模拟评审流程

模拟评审流程

在真机上模拟Apple将遵循的确切路径:

  • 从TestFlight安装最新版本
  • 使用您计划提供的评审账户登录
  • 在没有隐藏手势或调试菜单的情况下到达付费墙
  • 完成购买、恢复和订阅管理流程
  • 验证如果权限被拒绝,应用程序仍然正确运行

内购要求

《内购需求》

价格透明度(关键)

《价格透明度(关键)》

苹果要求在任何购买之前,清晰地显示价格:

必须包含的元素:

  • 在购买按钮之前显示精确价格
  • 显示账单频率(例如,“每月 $9.99”)
  • 清晰地说明用户为钱得到什么
  • 指出费用何时发生

常见的拒绝原因:

“订阅价格必须清晰明了。”

:::caution 价格一致性 所有价格必须在以下地方一致:

  • App Store 元数据列表
  • 内购屏幕
  • 订阅管理屏幕

即使是 $1 的差异(如 $4.99 的商店列表和 $5.99 的应用)也会触发自动拒绝。

必需的披露:

  • 所有可用的订阅等级一起显示
  • 每个等级的功能清晰比较
  • 不通过 UI trick 自动跳转到高级等级
  • 易于找到取消订阅的指示

UI 设计规范和禁忌

付费墙支持恢复购买和法律链接

遵守规范的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>
);
}

必需的实现:

每个使用IAP的应用程序都必须为用户提供恢复之前购买的方法,而不必联系支持。

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>

为什么会失败:

  • 应用程序在启动时会崩溃
  • 购买流程无法完成
  • 截图中显示的功能无法正常工作

预防措施:

  • 在真实设备上测试(而不是仅使用模拟器)
  • 测试所有订阅流程的完整性
  • 验证收据验证功能
  • 检查网络错误处理

2. 元数据不匹配

标题:2. 元数据不匹配

为什么会失败:

  • 截图显示当前版本中没有的功能
  • 描述提到了不存在的功能
  • 元数据中的价格与应用内价格不一致

元数据检查清单

预防措施:

// 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

为什么会失败:

  • 未提供解释的摄像头/位置/健康数据请求
  • 权限请求深藏在多个屏幕中
  • 模糊或通用的权限描述

预防措施:

更新您的 Info.plist 以清晰的说明方式

权限复制太模糊,无法通过审核 权限复制有更清晰的说明
<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>

为什么会失败:

  • 没有证据的说法,如“世界上最受欢迎的应用”
  • 没有明显限制的“无限”功能
  • 假的紧迫性策略(“仅剩下2个位置!”)

描述指南示例

额外的描述指南

预防措施:

  • 在描述中要具体、事实
  • 避免在描述中使用无证据的超级词
  • 不要用假的稀缺性来胁迫用户

5. 隐藏的取消流程

标题:5. 隐藏的取消流程

为什么会失败:

  • 没有说明如何取消
  • 取消按钮被隐藏或遮挡
  • 没有使用苹果原生的流程的多步取消流程

预防措施:

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

隐私和数据使用(第 5.1.1 节)

第 5.1.1 节标题:隐私和数据使用

苹果在 2025 年严格了隐私要求。

对于每个权限:

  1. 为什么需要它(具体用例)
  2. 何时使用
  3. 数据如何存储/共享
  4. 是否可选或必需

示例:正确的权限流程

标题:示例:正确的权限流程
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';
}

隐私营养标签

标题:隐私营养标签

确保您的App Store隐私标签准确反映:

  • 购买历史收集
  • 电子邮件地址(用于收据)
  • 设备ID(用于欺诈防御)
  • 使用数据(用于分析)

不准确的隐私标签是2025年拒绝理由之一。请仔细检查您的数据收集。

提交前检查清单

Pre-提交清单

Pre-提交清单

  1. 测试所有购买流程

    • 购买每个订阅等级
    • 测试免费试用
    • 验证引导价正确
    • 测试恢复购买
    • 验证家庭共享(如果启用)
    • 测试多台设备
  2. 验证价格一致性

    • 检查App Store元数据与内购价格匹配
    • 验证所有货币正确
    • 确认试用期限与描述相符
    • 检查引导性优惠条款是否准确
  3. 复核所有文案

    • 移除占位文本
    • 验证声明是否可测试
    • 检查语法和拼写
    • 确保描述与当前版本匹配
    • 移除竞争对手提及
  4. 测试权限

    • 只请求必要权限
    • 在请求之前显示清晰的说明
    • 测试“拒绝”流程(应用程序仍应正常工作)
    • __CAPGO_KEEP_0__
  5. 确保 Info.plist 描述清晰

    • __CAPGO_KEEP_1__
    • 准备测试账户
    • 创建一个在审查期间有效的评论账户
    • 在 App Review 信息中记录登录凭证
  6. 验证审查者可以访问付费墙并完成购买流程

    • 如果需要,请在 Notes 字段中包含额外账户或应用特定 switch
    • 检查元数据
    • 截图与当前 UI 匹配
    • 支持 URL 包含真实联系方式
    • 隐私政策 URL 已填写
    • 功能描述准确地描述了特性
    • 隐私政策在应用内和商店列表中都可访问
  7. 写详细的评论笔记

    Contact:
    Name: Jane Developer
    Email: review@yourapp.com
    Phone: +1 555-0100
    Test Account:
    Email: reviewer@test.com
    Password: TestPass123!
    This account does not expire during review.
    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.

App Store 评论时间线

标准审查: 24-48小时 高峰期: 3-5天(App Store节日发布) 周末: 无评论处理 加速审核: 可用于关键bug修复(通过App Store Connect提出请求)

App Store Connect中您可能会看到的常见状态:

  • Waiting for Review
  • In Review
  • Pending Developer Release
  • Rejected

2026年提交焦点

2026年提交焦点

当前重点领域

当前重点领域

1. 订阅清晰度

  • 横向比较计划要求
  • 不使用“黑暗模式”隐藏更便宜的选项
  • 清晰的降级/升级路径

2. 元数据准确性

  • 截图必须与正在审查的构建匹配
  • 如果启用了iPad支持,则需要iPad截图
  • 支持URL和隐私政策应在提交前已上线

3.隐私和审查详细信息质量

  • 隐私披露必须与您的SDK实际收集的内容匹配
  • 应用审查联系信息和备注应在第一次提交时完整
  • 演示凭证必须在整个审查窗口内保持有效

4.提交准备就绪

  • 苹果更新最低 SDK 要求周期性地,因此在上传发布版本之前确认当前截止日期
  • TestFlight 是最安全的地方来验证在提交之前的准确审阅路径

原生购买插件最佳实践

原生购买插件最佳实践

正确处理错误

正确处理错误
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. 仔细阅读拒绝原因

    • 注意被引用具体的指南(例如,3.1.1,5.1.1)
    • 了解苹果标记的准确问题
  2. 彻底修复问题

    • 不要仅仅修复问题 - 修复根本原因
    • 对修复进行广泛测试
    • 记录您所做的更改
  3. 应答中心解释

    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. 及时重新提交

    • 重新提交通常会更快
    • 通常在24小时内

如果您认为拒绝是错误的:

App Store 澄清流程

  1. 点击 App Store Connect 的“申诉”
  2. 提供清晰的证据:
    • 显示符合要求的截图
    • 具体指南的参考
    • 如何满足要求的说明
  3. 专业和事实
  4. 如果功能难以找到,请包含测试账户

请求文档示例

额外资源

额外资源

帮助

帮助

如果您仍然遇到问题:

需要专家帮助?

需要专家帮助?

在应用程序评论或需要个人化帮助时遇到困难? 与我们的团队预约一次咨询电话 为以下内容提供专门的支持:

  • IAP 实现的审查和优化
  • App Store 审核准备和策略
  • 提交清单审查
  • 拒绝解决方案和申诉
  • 我们的专家已经成功帮助了数百个应用程序通过审核!

继续从 iOS App Store Review Guidelines for IAP

标题为“继续从 iOS App Store Review Guidelines for IAP”

如果您正在使用

iOS App Store Review Guidelines for IAP iOS App Store Review Guidelines for IAP 为了计划商店审批和分发,连接它与 使用@capgo/native-purchases 对于在使用@capgo/native-purchases中的原生能力 @capgo/capacitor-in-app-review 对于在@capgo/capacitor-in-app-review中的实现细节 使用@capgo/capacitor-in-app-review 对于在使用@capgo/capacitor-in-app-review中的原生能力 @capgo/capacitor-native-market 对于在@capgo/capacitor-native-market中的实现细节,和 使用@capgo/capacitor-native-market 对于在使用@capgo/capacitor-native-market中的原生能力