コンテンツにジャンプ

Android Play Store IAP ガイドライン

GitHub

Google PlayへのAndroidアプリの承認には、特にインアプリ購入やサブスクリプションを含むアプリの場合、Googleのポリシーへの準拠が必要です。このガイドでは、承認を通過するために必要なすべての内容をカバーしています。

  1. 署名済みAndroidアプリバンドルを作成する

    新しいGoogle Playアプリは、Androidアプリバンドル(.aab)としてアップロードする必要があります。デバッグAPKをサイドロードするのではなく。

    アップロードの versionCode アップロードの回数が増え、Playアプリ署名を使用する場合はアップロードキーを安全に保管してください。

    Androidアプリバンドルフロー

  2. Playコンソールでアプリレコードを作成する

    開発者アカウントがまだない場合は Play Consoleの登録. Then, in Home > アプリの作成, choose the language, app/game type, free/paid status, support email, and accept the required declarations.

    無料/有料の設定を慎重に選択してください。Googleは有料アプリを無料に変更することを許可していますが、無料で提供されたアプリは有料に戻すことはできません。

    Play Consoleでアプリを作成

  3. アプリの内容とストアのリスト

    生産レビュー前に、以下のPlay Consoleの申告を完了してください:

    • プライバシーポリシー
    • 広告
    • アプリへのアクセス
    • 対象読者とコンテンツ
    • __CAPGO_KEEP_0__
    • コンテンツ評価
    • __CAPGO_KEEP_0__
  4. データセキュリティ

    __CAPGO_KEEP_0__ 許可されたセンシティブパーミッションの宣言 __CAPGO_KEEP_0__ Play-インストールテストトラックを実行 __CAPGO_KEEP_0__

    内部テスト

  5. __CAPGO_KEEP_0__

    Google Playからアプリをインストールし、ローカルでエクスポートされたAPKではなく、

    • Playから正しく製品が読み込まれる
    • 購入シートに テスト購入 ライセンステスター用のバナー
    • 購入後にエンタイトルメントがアンロックされる
    • 購入、再購入、サブスクリプション管理フローの機能が正常に動作する

Google Play Billing Requirements

「Google Play Billing Requirements」

必須の課金システム

「必須の課金システム」

デジタル商品やサービスに対しては 必須 Google Playの課金システムを使用する必要があります:

デジタル商品 (Google Play Billingを使用する必要があります):

  • プレミアム機能のサブスクリプション
  • アプリ内通貨またはクレジット
  • デジタルコンテンツ (ebook、音楽、動画)
  • ゲームのアップグレードとパワーアップ
  • アプリのアンロックとプレミアム階層

物理商品 (Google Play Billingを使用できない):

  • 実物の商品
  • 現実世界のサービス
  • 非営利団体への一時的な寄付

:::note サブスクリプションの設定 Google Play Consoleで、現在のサブスクリプションを使用してAndroidのサブスクリプションを設定します。 サブスクリプション -> 基本プラン -> 提供 モデル。 native-purchases、基本プランIDをパスする planIdentifier. :::

import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
// Ensure billing is available on the device
const { isBillingSupported } = await NativePurchases.isBillingSupported();
if (!isBillingSupported) throw new Error('Google Play Billing not available');
// Fetch subscription products (Store data is required—never hardcode pricing)
const { products } = await NativePurchases.getProducts({
productIdentifiers: ['premium_monthly', 'premium_yearly'],
productType: PURCHASE_TYPE.SUBS,
});
// Plan identifiers are the Base Plan IDs you create in Google Play Console
const transaction = await NativePurchases.purchaseProduct({
productIdentifier: 'premium_monthly',
planIdentifier: 'monthly-plan', // REQUIRED on Android, ignored on iOS
productType: PURCHASE_TYPE.SUBS,
});
console.log('Purchase token for server validation:', transaction.purchaseToken);

Google Playでは、購入前にすべてのコストを明確に開示することを義務付けられています。

必要な要素:

  • ユーザーのローカル通貨での正確な価格
  • 請求頻度(月額、年額など)
  • サブスクリプションに含まれるもの
  • 導入オファーの合計コスト
  • 課金が発生する時期

UI設計のベストプラクティス

適合するUIの例

function SubscriptionCard({ product }) {
return (
<div className="subscription-card">
<h3>{product.title}</h3>
{/* Show intro offer if available */}
{product.introductoryPrice && (
<div className="intro-offer">
<p className="intro-price">{product.introductoryPriceString}</p>
<p className="intro-period">
for {product.introductoryPricePeriod}
</p>
</div>
)}
{/* Regular price */}
<div className="regular-price">
<p className="price">{product.priceString}</p>
<p className="period">per {product.subscriptionPeriod}</p>
</div>
{/* Clear description */}
<p>{product.description}</p>
{/* Renewal terms */}
<p className="terms">
Renews automatically. Cancel anytime in Google Play.
</p>
<button onClick={() => handlePurchase(product)}>
Subscribe Now
</button>
</div>
);
}

サブスクリプションが自動更新される前に、Googleは以下の要件を満たす必要があります:

  • 自動更新の再発行の通知をクリアする
  • 価格の催促
  • キャンセルへの簡単なアクセス

プラットフォーム間の価格明確性

セクション「プラットフォーム間の価格明確性」

複数のプラットフォームで同じエンタイトルメントを販売する場合、製品名、請求期間、付与された利益、更新の言語を同期して、ユーザーが驚かないようにしてください。

価格は税金、ローカル通貨、またはストアの経済学によって異なる場合がありますが、購入UIはそれらの差異を隠すことはできず、Google Playが請求する更新コストと異なる再発行コストを暗示することはできません。

アプリ内課金を含むアプリがある場合、必ずしも:

  1. Play Store リストにリンク

    • Play Console にプライバシーポリシーの URL を追加
    • パブリックにアクセス可能
    • アプリの言語と同じでなければなりません
  2. アプリ内でリンク

    • ユーザーデータを収集する前に表示
    • 簡単に発見できるように
    • 実装の例:

例の実装:

function SettingsScreen() {
const openPrivacyPolicy = () => {
window.open('https://yourapp.com/privacy', '_blank');
};
const openTerms = () => {
window.open('https://yourapp.com/terms', '_blank');
};
return (
<div>
<h2>Settings</h2>
<button onClick={openPrivacyPolicy}>
Privacy Policy
</button>
<button onClick={openTerms}>
Terms of Service
</button>
<button onClick={() => NativePurchases.manageSubscriptions()}>
Manage Subscriptions
</button>
</div>
);
}

Google Playでは、データセキュリティセクションで詳細な説明が必要です。

IAPアプリの場合、次のように宣言してください。

  • 購入履歴の収集
  • 請求書のためのメールアドレス
  • デバイスID(詐欺防止のため)
  • 決済情報の取り扱い
  • 分析データの収集

データセキュリティセクションは法的拘束力があります。誤った宣言はアプリの削除につながる可能性があります。

アプリのコンテンツの宣言

App Content Declarations

Google Playのレビューは、バイナリだけに焦点を当てるのではなく、製品リリース前にPolicy and programs > App contentの申告を完了する必要があります。 最低限、注意深くレビューするものは次のとおりです。.

プライバシーポリシー

  • : Play Consoleで公開するパブリックURL、プラス、必要に応じてインアプリエントリポイント広告
  • : アプリが広告を含む場合に宣言するアプリアクセス
  • : レビューアーにワーキングクレデンシャルまたは明確なテストパスを提供するか、ゲートされたスクリーンがあれば対象読者とコンテンツ
  • : アプリの実際の読者と一致させる__CAPGO_KEEP_0__
  • コンテンツ評価: IARC 問い合わせ書を完了して、アプリが未評価のマークされないようにします
  • データセキュリティ: 正確に収集、共有、セキュリティの実践を宣言する

1. 正しくない請求実装の欠如

1. 未正しく設定された請求処理

なぜ失敗するのか:

  • Google Play Billing を使用していない
  • 古い請求 API を使用している
  • サブスクリプションのカスタム支払いソリューションを実装している

防止策:

// ✅ Correct: Use native-purchases (uses Google Play Billing)
await NativePurchases.purchaseProduct({
productIdentifier: 'premium_monthly',
planIdentifier: 'monthly-plan',
productType: PURCHASE_TYPE.SUBS,
});
// ❌ Wrong: Custom payment processor for subscriptions
// await CustomPayment.charge(user, 9.99);

2. 不明確な価格設定または非表示のコスト

2. 不明確な価格設定または非表示のコスト

なぜ失敗するのか:

  • 購入をクリックする前に価格が表示されていない
  • 事前には非公開の追加料金が表示されていない
  • 不明確なサブスクリプション条項

対策:

function PurchaseScreen({ product }) {
return (
<div>
{/* Show ALL costs upfront */}
<h2>Premium Subscription</h2>
<div className="pricing">
<p className="price">{product.priceString}/month</p>
<p className="taxes">Taxes may apply based on location</p>
</div>
<div className="features">
<h3>Includes:</h3>
<ul>
<li>Ad-free experience</li>
<li>Unlimited cloud storage</li>
<li>Priority support</li>
</ul>
</div>
<div className="terms">
<p>
Subscription renews automatically unless cancelled at least
24 hours before the end of the current period.
</p>
<p>
Manage or cancel in Google Play Subscriptions.
</p>
</div>
<button onClick={handlePurchase}>
Start Subscription
</button>
</div>
);
}

3. デリケートなサブスクリプションパターン

セクション「3. デリケートなサブスクリプションパターン」

なぜ失敗するのか:

  • プレミアムオプションの事前選択
  • 安価な代替案を隠す
  • キャンセルを難しくする
  • 偽の緊急性(「残り3つ」)

説明のベストプラクティス

マーケティングガイドライン

対策:

  • すべてのサブスクリプション枠を同等に表示する
  • キャンセルを明確かつアクセスしやすくする
  • カウントダウンタイマーや偽の不足感を避ける
  • 高額なオプションを押し付ける暗黙のパターンを避ける

なぜ失敗するのか:

  • 購入時にアプリがクラッシュする
  • 商品が読み込まれない
  • 購入確認画面が表示されない
  • プレミアム機能が購入後にロックされない
  • サイドロードされたビルドでのみテストが行われましたが、Playストアでインストールされたテストトラックではありません。

対策:

import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
// Comprehensive testing before submission
async function testPurchaseFlow() {
try {
// 1. Test product loading
const { products } = await NativePurchases.getProducts({
productIdentifiers: ['premium_monthly', 'premium_yearly'],
productType: PURCHASE_TYPE.SUBS,
});
console.log('✓ Products loaded:', products.length);
// 2. Test purchase flow
const transaction = await NativePurchases.purchaseProduct({
productIdentifier: 'premium_monthly',
planIdentifier: 'monthly-plan',
productType: PURCHASE_TYPE.SUBS,
});
console.log('✓ Purchase completed', transaction.transactionId);
// 3. Verify entitlements
const { purchases } = await NativePurchases.getPurchases({
productType: PURCHASE_TYPE.SUBS,
});
if (
purchases.some(
(purchase) =>
purchase.productIdentifier === 'premium_monthly' &&
['PURCHASED', '1'].includes(purchase.purchaseState ?? '') &&
purchase.isAcknowledged,
)
) {
console.log('✓ Premium features unlocked');
}
// 4. Test restore
await NativePurchases.restorePurchases();
console.log('✓ Restore works');
} catch (error) {
console.error('✗ Test failed:', error);
}
}

なぜ失敗するのか:

  • アプリ内にプライバシーポリシーへのリンクがない
  • プライバシーポリシーへのアクセスができない
  • データ収集が明らかになっていない
  • データセーフティのセクションが不正確

対策:

  • プライバシーポリシーをPlayストアのアプリ詳細に追加する
  • アプリ設定にリンクを含める
  • データセーフティセクションを正確に埋める
  • 新しいデータ収集を追加するときにポリシーを更新する

Googleの代替課金プログラムは地域によって異なり、変更される可能性があります。標準のGoogle Play Billing以外のものを使用したい場合は、実装前にPlay Consoleで市場の適格性、必要なAPI、披露言語を確認してください。

簡単なキャンセル

Easy Cancellation

ユーザーは以下のことができる必要があります。

  • アクティブなサブスクリプションを簡単に表示できる
  • サポートに連絡することなくキャンセルできる
  • キャンセルが有効になる時期を理解できる

実装:

import { NativePurchases } from '@capgo/native-purchases';
function ManageSubscriptionButton() {
const openManagement = async () => {
try {
// Opens Google Play subscription management
await NativePurchases.manageSubscriptions();
} catch (error) {
// Fallback to direct URL
const playStoreUrl = 'https://play.google.com/store/account/subscriptions';
window.open(playStoreUrl, '_blank');
}
};
return (
<button onClick={openManagement}>
Manage Subscription in Google Play
</button>
);
}

キャンセル グレード ペリオド

キャンセル グレード ペリオド

必要な披露:

  • キャンセルが有効になる時期はいつですか?
  • ユーザーは期間終了までアクセスを維持できますか?
  • パーセンテージ返金は利用可能ですか?
function CancellationInfo() {
return (
<div className="cancellation-info">
<h3>Cancellation Policy</h3>
<ul>
<li>Cancel anytime in Google Play</li>
<li>Access continues until end of billing period</li>
<li>No refunds for partial periods</li>
<li>Resubscribe anytime to regain access</li>
</ul>
<button onClick={() => NativePurchases.manageSubscriptions()}>
Manage in Google Play
</button>
</div>
);
}

提出前にチェックリスト

  1. 請求処理の確認

    • Google Play Billing (native-purchasesを使用)の利用
    • すべてのPlay Consoleで作成されたサブスクリプション製品
    • ベースプランとオファーが正しく設定されている
    • 製品が有効化され、公開されている
    • すべての対象国で価格が設定されている
  2. 購入フローのテスト

    • ライセンステストアカウントを作成する
    • Playテストトラックからビルドをインストールする
    • 各サブスクリプション階層をテストする
    • 製品が正しくロードされることを確認する
    • 購入の完了をテストする
    • 購入の テスト購入 バナーが表示されることを確認する
    • プレミアム機能がアンロックされることを確認する
    • サブスクリプションの復元をテストする
    • 複数のデバイスでテストする
  3. すべてのコピーを確認する

    • 購入前に価格が明確に表示されます。
    • すべての料金は事前に明らかです。
    • サブスクリプションの条件は明確です。
    • キャンセルプロセスが説明されています。
    • 誤解を招く主張はありません。
  4. アプリのコンテンツとプライバシー

    • プライバシーポリシーはPlay Consoleにリンクされています。
    • プライバシーポリシーはアプリ内でアクセス可能です。
    • 広告の申告が完了しました。
    • アプリがゲートされた場合のアプリへのアクセス方法が追加されます。
    • データセーフティのセクションは正確に完了しました。
    • 許可された権限は説明と文書化されています。
  5. コンテンツ レーティングとアクセス対象者

    • 全コンテンツ レーティングの質問書を完了する
    • ターゲット アクセス対象者とコンテンツ セクションを完了する
    • 実際のコンテンツとレーティングが一致するようにする
    • 質問書にイン アプリ 購入を宣言する
  6. ストア リストを準備する

    • アプリの説明が正確である
    • 短い説明は 80 文字以内である
    • フル ディスクの説明は 4000 文字以内である
    • 少なくとも 2 つの電話画面のスクリーンショットをアップロードする
    • 1024x500 の特徴グラフィックをアップロードする
    • スクリーンショットは現在のバージョンを表示する
    • すべての必要なアセットがアップロードされました。

新しい個人アカウントの生産アクセス: 通常、7日以内に申請後に適用されます。 初回の生産レビュー: コンテキスト: Capgo Builder / ネイティブクラウドビルド製品ページ。役割: 短いUIラベルまたはナビゲーションアイテム。メッセージキー `native_build_builder_credit_first` (ネイティブビルドビルダークレジットファースト)。 よくあるのは数日、あるいは請求またはポリシーに関する質問が生じた場合に長くなることもあります。 アップデート: 初回リリースよりも速い場合もありますが、依然としてレビューされます。 アピール:

数日間を計画し、正確な修正とレビューユーザーの指示を提供してください。

テストの前に提出

「テストの前に提出」

ライセンステスト

「ライセンステスト」
  1. テストアカウントを追加:

    • プレイコンソールに移動
    • 設定 > ライセンステスト
    • テスト用にGmailアカウントを追加
  2. テスト環境でテスト:

import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
// Test purchases with license test account
async function testInSandbox() {
const { isBillingSupported } = await NativePurchases.isBillingSupported();
if (!isBillingSupported) {
console.error('Billing not supported in this environment');
return;
}
// Fetch products (returns test pricing when using a license tester)
const { products } = await NativePurchases.getProducts({
productIdentifiers: ['premium_monthly'],
productType: PURCHASE_TYPE.SUBS,
});
console.log('Test products:', products);
// Make test purchase (no charge)
const transaction = await NativePurchases.purchaseProduct({
productIdentifier: 'premium_monthly',
planIdentifier: 'monthly-plan',
productType: PURCHASE_TYPE.SUBS,
});
console.log('Test purchase complete:', transaction.transactionId);
}
  1. テストバナーを検証:
    • テストアカウントで購入する場合
    • 購入通知 “Test purchase” が表示されるはずです。
    • 実際の課金は発生しません。

内部テストとクローズドテストのトラック

「内部テストとクローズドテストのトラック」のセクション

本番リリース前のステップ

  1. プロダクションリリース前のステップとして 内部テスト用の 迅速なQAのための内部テスト用のトラック より広範なテストのための クローズドテスト用のトラック
  2. 署名されたテスト用のリリースをアップロードし、公開する .aab テスト用のリリースを署名し、公開する
  3. Google Play Store のレビュー
  4. テスターに Google Play からビルドをインストールさせる
  5. Play インストール済みのビルドで Google Play Billing の購入フローが端端に機能することを確認する
  6. 2023 年 11 月 13 日以降に個人開発者アカウントが作成された場合は、少なくとも 12 人のテスターを 14 日間続けてクローズド テストにオプティンさせて、生産用に申請する前に実施する必要があります。

Google Play Billing の検証のために、サイドロードされたデバッグ ビルドは、Play インストール済みのテスト ビルドの代わりにはなりません。

ネイティブ購入のベスト プラクティス

ネイティブ購入のベスト プラクティス

すべての購入状態を処理する

すべての購入状態を処理する
import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
async function handlePurchase(productId: string, planIdentifier?: string) {
try {
setLoading(true);
const transaction = await NativePurchases.purchaseProduct({
productIdentifier: productId,
planIdentifier,
productType: planIdentifier ? PURCHASE_TYPE.SUBS : PURCHASE_TYPE.INAPP,
});
console.log('Purchase token:', transaction.purchaseToken ?? transaction.receipt);
// Success - check entitlements from the store
const { purchases } = await NativePurchases.getPurchases({
productType: planIdentifier ? PURCHASE_TYPE.SUBS : PURCHASE_TYPE.INAPP,
});
const isOwned = purchases.some(
(purchase) =>
purchase.productIdentifier === productId &&
(purchase.purchaseState === 'PURCHASED' || purchase.purchaseState === '1') &&
purchase.isAcknowledged,
);
if (isOwned) {
unlockPremiumFeatures();
showSuccess('Premium activated!');
}
} catch (error: any) {
// Handle specific error cases
switch (error.code) {
case 'USER_CANCELLED':
// User backed out - no error needed
console.log('Purchase cancelled');
break;
case 'ITEM_ALREADY_OWNED':
// They already own it - restore instead
showInfo('You already own this! Restoring...');
await NativePurchases.restorePurchases();
break;
case 'ITEM_UNAVAILABLE':
showError('This subscription is currently unavailable. Please try again later.');
break;
case 'NETWORK_ERROR':
showError('Network error. Please check your connection and try again.');
break;
default:
showError('Purchase failed. Please try again.');
console.error('Purchase error:', error);
}
} finally {
setLoading(false);
}
}

購入を復元する実装

購入を復元する実装
import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
function RestorePurchasesButton() {
const [loading, setLoading] = useState(false);
const handleRestore = async () => {
setLoading(true);
try {
await NativePurchases.restorePurchases();
const { purchases } = await NativePurchases.getPurchases({
productType: PURCHASE_TYPE.SUBS,
});
const hasSubscription = purchases.some(
(purchase) => purchase.productType === 'subs' && purchase.isAcknowledged,
);
if (hasSubscription) {
unlockPremiumFeatures();
showSuccess('Subscriptions restored!');
return;
}
// Check one-time unlocks if needed
const { purchases: iaps } = await NativePurchases.getPurchases({
productType: PURCHASE_TYPE.INAPP,
});
const hasInApp = iaps.some((purchase) => purchase.productIdentifier === 'premium_unlock');
if (hasInApp) {
unlockPremiumFeatures();
showSuccess('Previous purchases restored!');
return;
}
showInfo('No previous purchases found.');
} catch (error) {
showError('Failed to restore purchases. Please try again.');
} finally {
setLoading(false);
}
};
return (
<button onClick={handleRestore} disabled={loading}>
{loading ? 'Restoring...' : 'Restore Purchases'}
</button>
);
}

サブスクリプションのステータスを確認

「サブスクリプションのステータスを確認」のセクション
import { NativePurchases, PURCHASE_TYPE } from '@capgo/native-purchases';
async function checkSubscriptionStatus() {
try {
const { purchases } = await NativePurchases.getPurchases({
productType: PURCHASE_TYPE.SUBS,
});
const subscription = purchases.find(
(purchase) =>
purchase.productIdentifier === 'premium_monthly' &&
(purchase.purchaseState === 'PURCHASED' || purchase.purchaseState === '1') &&
purchase.isAcknowledged,
);
if (!subscription) {
showPaywall();
return;
}
console.log('Subscription active:', {
productId: subscription.productIdentifier,
expiresAt: subscription.expirationDate,
willRenew: subscription.willCancel === false,
purchaseToken: subscription.purchaseToken,
});
unlockPremiumFeatures();
} catch (error) {
console.error('Failed to check subscription:', error);
}
}

支払いポリシー:

  • Google Play Billing を使用していない
  • 誤解を招くサブスクリプションの条件
  • 非表示のコスト

ユーザー データ ポリシー:

  • プライバシー ポリシーが欠落している
  • データ セーフティの申告が不正確
  • 許可が過剰
  1. 違反通知を確認する

    • 特定のポリシーを読む
    • Googleがフラグした内容を理解する
    • 提供された例を確認する
  2. 問題を修正する

    • 根本原因を解決する
    • テストを徹底的に行う後、修正
    • すべての変更を文書化する
  3. 申し立てを提出する (必要に応じて)

    説明と申し立てのプロセス

    Subject: Policy Violation Appeal - [App Name]
    Dear Google Play Review Team,
    I have received notification that my app violates [Policy X.Y].
    I have made the following changes to comply:
    1. [Specific change made]
    2. [Specific change made]
    3. [Specific change made]
    The updated version [version number] addresses all concerns raised.
    Test account for verification:
    Email: test@example.com
    Password: TestPass123
    Thank you for your consideration.

    ドキュメントの例を要求する

  4. 再提出またはアップデート

    • 修正したバージョンをアップロードする
    • 再提出を申し立てる
    • Play Consoleでステータスを監視する

Play Storeのレビューをナビゲートすることは複雑です。特に、請求の合致、Appのコンテンツの宣言、テストトラックの設定を組み合わせる必要がある場合です。個別のアシスタンスが必要な場合:

本のカスタマイズカレンダーを予約してください のための助けが必要です:

  • Play Storeのレビュー準備が完了しました
  • テスト用トラックの設定とテスターの募集
  • IAP実装のレビュー
  • データの安全性とプライバシーへの準拠
  • 却下のトラブルシューティングと申し立て
  • アプリの完全な提出プロセス

Capgoの専門家は、成功したPlayストアの提出を数百のアプリを導き、現在の要件を導くのに役立ちます。

Native Purchasesドキュメントのレビュー

Android Play StoreレビューのガイドラインのIAPから続けて

セクション「Android Play StoreレビューのガイドラインのIAPから続けて」

使用している場合 Android Play StoreレビューのガイドラインのIAP セキュリティとコンプライアンスを計画するために、@__CAPGO_KEEP_0__/native-purchasesを使用 native capabilityの@capgo/native-purchasesの使用 for the native capability in Using @capgo/native-purchases, 暗号化の実装詳細 暗号化 適合性 適合性 Capgo セキュリティ スキャナー Capgo セキュリティ スキャナー Capgo セキュリティ for the product workflow in Capgo Security.