メインコンテンツへスキップ

IAPに関するiOS App Storeの審査ガイドライン

GitHub

App Storeでのアプリ承認を得るには、Appleのガイドライン、特にアプリ内課金やサブスクリプションの実装に関する規定に細心の注意を払う必要があります。このガイドでは、初回提出で審査を通過するために必要な情報を網羅しています。

iOS App Storeの審査プロセス

App Store Connectの設定を完了する

「App Store Connectの設定完了」セクション

Appleが購入フローの審査を開始する前に、アプリ自体のレコードが完全に作成されていることを確認してください:

  • 他の依存関係用の プライバシーポリシーURL App Store Connectにて
  • 他の依存関係用の サポートURL ユーザーの実際の連絡先に繋がるもの
  • 次の 年齢制限(Age Rating) アプリを公開可能にするためのアンケート
  • 追加 App Reviewの連絡先詳細 および明確なレビュアー向けメモ
  • ログインが必要な場合は、以下を提供してください: 審査中に期限切れにならないデモ用アカウント
ポリシーおよびサポートリンクを含むApp Storeのメタデータ

実際のスクリーンショットを用意する

「適切なスクリーンショットの準備」セクション
  • 審査中の実際のビルドから最新のスクリーンショットを使用してください
  • iPhoneの場合、 1290 x 2796 (6.7インチ) が最も標準的なサイズです
  • iPad対応アプリの場合は、iPad用のスクリーンショットもアップロードしてください
  • 現在承認されている主なiPadサイズは以下の通りです: 2064 x 2752 (13インチ) および 2048 x 2732 (12.9インチ)
  • iPad対応を偽装するためにiPhoneのスクリーンショットを無理に引き伸ばさないこと

Appleのレビュアーが実際に辿る手順を、実機で実行してください:

  • TestFlightから最新のビルドをインストールする
  • 提出予定のレビュー用アカウントでサインインする
  • 隠しジェスチャーやデバッグメニューを使わずにペイウォールまで到達する
  • 購入、復元、サブスクリプション管理のフローを完了させる
  • 権限が拒否された場合でもアプリが正しく動作するか確認する

価格表示の透明性(重要)

「価格の透明性(重要)」セクション

Appleは、購入前に極めて明確な価格表示を求めています:

必須要素:

  • 購入ボタンの前に正確な価格を表示
  • 請求頻度を表示(例:「$9.99/month」)
  • 支払った料金で何が得られるかを明記
  • 課金が発生するタイミングを明示

よくあるリジェクト理由:

「サブスクリプションの価格設定は、明確かつ事前に提示されている必要があります。」

:::caution 価格の一貫性 以下のすべての場所で価格を一致させる必要があります:

  • App Storeのメタデータ記載内容
  • アプリ内の購入画面
  • サブスクリプション管理画面

ストア掲載価格($4.99)とアプリ内価格($5.99)にわずか$1の差があるだけでも、自動的にリジェクトの対象となります。 :::

サブスクリプションプランの提示

「サブスクリプションプランの提示」セクション

必須の開示事項:

  • 利用可能なすべてのサブスクリプションプランを併記
  • プランごとの機能比較を明確に表示
  • UIの工夫によるプレミアムプランへの自動選択を避ける
  • 解約方法を分かりやすい場所に記載

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>

却下される理由:

  • 起動時にアプリがクラッシュする
  • 購入フローが完了しない
  • スクリーンショットに写っている機能が動作しない

対策:

  • 実機でテストする(シミュレーターだけでなく)
  • すべてのサブスクリプションフローをE2Eでテストする
  • レシート検証が機能することを確認する
  • ネットワークエラーのハンドリングを確認する

却下される理由:

  • スクリーンショットに現在のビルドに含まれない機能が写っている
  • 説明文に存在しない機能が記載されている
  • メタデータの価格とアプリ内価格の不一致

メタデータのチェックリスト

対策:

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

却下される理由:

  • 根拠のない「世界No.1アプリ」などの主張
  • 隠れた制限がある「無制限」機能
  • 偽の緊急性を煽る手法(「残り2枠!」など)

説明ガイドラインの例

説明ガイドラインの詳細

対策:

  • 説明は具体的かつ事実に即したものにする
  • 根拠のない最上級表現は避ける
  • 偽の限定感でユーザーを煽らない

5. 解約プロセスの不透明さ

「5. 隠された解約プロセス」セクション

却下される理由:

  • 解約方法の記載がない
  • 解約ボタンが隠れている、または見えにくい
  • Apple標準のフローではない、複雑な解約手順

対策:

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

Appleは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年現在、不正確なプライバシーラベルはリジェクトの一般的な原因となっています。データ収集内容を慎重に監査してください。

提出前のチェックリスト

  1. すべての購入フローをテストする

    • 各サブスクリプションプランを購入する
    • 無料トライアルをテストする
    • 初回限定特典が正しく適用されるか確認する
    • 購入情報の復元をテストする
    • ファミリー共有を確認する(有効な場合)
    • 複数のデバイスでテストする
  2. 価格の一貫性を確認する

    • App Storeのメタデータとアプリ内価格が一致するか確認する
    • すべての通貨が正しいか確認する
    • 無料トライアルの期間が説明と一致するか確認する
    • 初回限定特典の条件が正確か確認する
  3. コピーの全確認

    • プレースホルダーの削除
    • 主張内容の検証可能性を確認
    • 文法とスペルのチェック
    • 説明文と現在のbuildの一致を確認
    • 競合他社の記載を削除
  4. 権限のテスト

    • 必要な権限のみをリクエスト
    • リクエスト前に明確な説明を表示
    • 「拒否」フローのテスト(アプリが動作すること)
    • Info.plistの説明が明確か確認
  5. テストアカウントの準備

    • 審査中に有効なレビュー用アカウントを作成する
    • App Review情報の欄にログイン情報を記載する
    • レビュアーがペイウォールに到達し、購入フローを完了できるか確認する
    • 必要に応じて、Notes欄に追加のアカウントやアプリ固有の切り替え方法を記載する
  6. メタデータの確認

    • スクリーンショットが現在の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 の休日リリース時) 週末: レビューは行われません 優先レビュー: 重大なバグ修正に利用可能(App Store Connectから申請)

App Store Connectで表示される主なステータス:

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

1. サブスクリプションの明瞭性

  • プランの並列比較が必須
  • 安価なオプションを隠す「ダークパターン」は禁止
  • ダウングレード/アップグレードパスの明確化

2. メタデータの正確性

  • スクリーンショットはレビュー対象のビルドと一致させること
  • iPad対応が有効な場合はiPad用のスクリーンショットが必須
  • サポートURLとプライバシーポリシーは申請前に公開しておくこと

3. プライバシーとレビュー詳細の品質

  • プライバシー開示内容はSDKの実際の収集データと一致させること
  • App Reviewの連絡先とメモは初回申請時にすべて記入すること
  • デモ用認証情報はレビュー期間中ずっと有効であること

4. 申請の準備状況

  • Appleは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)
    • Appleが何を問題視しているかを正確に把握する
  2. 問題を徹底的に修正する

    • 表面的な修正ではなく、根本原因を解決する
    • 修正内容を広範囲にテストする
    • 変更内容を記録しておく
  3. 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. 速やかに再提出

    • 再提出は通常、審査が早くなります
    • 通常24時間以内

リジェクトが誤っていると思う場合:

App Store の明確化プロセス

  1. App Store Connectで「異議申し立て」をクリック
  2. 明確な証拠を提示してください:
    • ガイドラインに準拠していることを示すスクリーンショット
    • 特定のガイドラインへの参照
    • 要件を満たしていることの説明
  3. プロフェッショナルで事実に基づいた内容にする
  4. 機能が見つけにくい場合はテストアカウントを記載する

書類の請求例

問題が解決しない場合は:

アプリの審査でお困りですか?個別のアシスタンスが必要な場合もこちら。 チームとの相談を予約する 以下の項目に関する専用サポート:

  • IAP実装のレビューと最適化
  • App Store審査の準備と戦略
  • 提出前チェックリストの確認
  • リジェクトへの対応と異議申し立て
  • テストと検証の完了

当社のエキスパートが、数百ものアプリの審査通過を支援してきました!

IAPについてはiOS App Store Review Guidelinesを確認してください

「IAPに関するiOS App Store Review Guidelinesを継続して活用する」セクション

使用している場合 IAPに関するiOS App Store Review Guidelines ストアの承認と配信を計画するには、これを次と連携させてください: @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. の使用」のネイティブ機能については