コンテンツにジャンプ

__CAPGO_KEEP_1__

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

  1. 署名されたAndroidアプリバンドルを作成

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

    保管 versionCode アップロードごとに増加し、Play App Signingを使用する場合はアップロードキーを安全に保存してください。

    Androidアプリバンドルフロー

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

    まだ開発者アカウントを持っていない場合は、 Play Consoleへの登録。次に、 ホーム>アプリ作成で言語、アプリ/ゲームの種類、無料/有料の設定、サポートメール、必要な申告を承認してください。

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

    Play Consoleでアプリを作成する

  3. アプリのコンテンツとストアリストの作成

    生産レビュー前に、必要なPlay Consoleの申告を完了してください。

    • プライバシーポリシー
    • 広告
    • アプリケーションへのアクセス
    • 対象読者とコンテンツ
    • コンテンツの評価
    • データの安全性
    • __CAPGO_KEEP_0__
  4. Play-インストールされたテストトラックを実行

    開始 内部テスト 高速なQAのために。開発者アカウントが個人アカウントで、2023年11月13日以降に作成されている場合、また、以下の条件を満たす場合、閉鎖テストも完了する必要があります。 閉鎖テスト 12日以上の連続した日数で、少なくとも12人のテスト参加者がオプトインしている場合、生産アクセスが許可される。

    Play Console内での内部テスト

  5. 請求金額のエンドツーエンドの検証

    Google Playからアプリをインストールし、ローカルにエクスポートされたAPKではなく。次に、以下を確認する。

    • Playから正しく製品が読み込まれる
    • 購入シートには ライセンステスター用の 購入テスト
    • ライセンスのバナー
    • ライセンスが購入された後、エンタイトルメントがアンロックされる

購入後の復元とサブスクリプション管理フローの動作

Google Play Billing Requirements

__CAPGO_KEEP_0__

__CAPGO_KEEP_1__

デジタル商品やサービスを利用する場合、 Google Playの請求システムを使用する必要があります。 デジタル商品 (Google Play請求必須):

プレミアム機能のサブスクリプション

  • インゲーム通貨またはクレジット
  • デジタルコンテンツ (eブック、音楽、動画)
  • ゲームアップグレードとパワーアップ
  • アプリのアンロックとプレミアム階層
  • 物理商品 (Google Play請求不可):

物理商品やサービスを利用する場合、

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

:::note サブスクリプション設定 Play Consoleで、Androidサブスクリプションを使用するために現在の サブスクリプション -> 基本プラン -> 提供 モデルを設定します。 In 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>
);
}

Before a subscription auto-renews, Google requires:

  • Clear notification that renewal will occur
  • Reminder of the price
  • Easy access to cancellation

If you sell the same entitlement on multiple platforms, keep the product naming, billing period, included benefits, and renewal language aligned so users are not surprised.

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

Playストアリストにリンク

  1. PlayコンソールにプライバシーポリシーURLを追加

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

    • __CAPGO_KEEP_0__
    • ユーザーデータを収集する前に表示
    • ユーザーに簡単にわかりやすく表示

実装例:

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
  • 決済情報の取り扱い
  • __CAPGO_KEEP_0__データ収集

Data Safetyのセクションは法的拘束力があります。不正確な申告はアプリの削除につながる可能性があります。

Google Playレビューはバイナリだけではありません。生産用のリリース前に、以下の申告を完了してください。 ポリシーとプログラム > アプリ内コンテンツ.

最小限の内容を注意深く確認してください:

  • プライバシーポリシー: Play ConsoleのパブリックURL、必要に応じてインストール内エントリポイント
  • 広告: アプリが広告を含むかどうかを宣言する
  • アプリへのアクセス: レビュー担当者にアクセス可能なクレデンシャルまたはテストパスを提供する必要があります。
  • Target audience and content : アプリの実際の対象者に合わせたコンテンツを提供する必要があります。
  • Content ratings : IARCの質問紙を完了して、アプリが未評価としてマークされないようにする必要があります。
  • Data Safety : 正確にデータの収集、共有、セキュリティの実践を宣言する必要があります。

一般的な却下理由

一般的な却下理由

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

なぜ失敗するのか:

  • アプリ内にプライバシーポリシーへのリンクがない
  • プライバシーポリシーへのアクセスができない
  • データ収集の透明性が欠けている
  • データセキュリティセクションの不正確さ

予防:

  • プレイストアリストイングにプライバシーポリシーを追加する
  • アプリ設定内にリンクを含める
  • データセキュリティセクションを正確に記入する
  • 新しいデータ収集を追加する際にポリシーを更新する

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

簡単なキャンセル

キャンセルのセクション

ユーザーは次のことができる必要があります:

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

実装:

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

必要な披露:

  • __CAPGO_KEEP_0__ はいつ有効になる?
  • 期間終了までユーザーはアクセスを維持できる?
  • 部分的な返金は利用可能?
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日以内 最初の生産レビュー: 初回リリースよりも速い場合もありますが、請求やポリシーに関する質問が生じた場合は長くなる場合があります アップデート: 初回リリースよりも速い場合もありますが、依然としてレビューされます Appeals: 計画期間を数日間とし、正確な修正とレビュアー指示を提供する

:::tip Rolling Reviews AppleやGoogleと異なり、Googleはアプリを継続的にレビューします。アプリはレビュー期間中いつでも公開される可能性があり、固定時間ではなくいつでも公開される可能性があります。 :::

提出前にテスト

テスト前

ライセンステスト

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

    • Play Consoleにアクセス
    • 設定 > ライセンステスト
    • 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. テストアカウントで購入する際の確認メッセージ:
    • テストアカウントで購入する場合
    • 「テスト購入」通知が表示される
    • 実際の課金は発生しません

内部テストとクローズドテスト

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

リリース前の段階で

  1. 「内部テスト」 内部テスト用に迅速なQAを行うか、または クローズドテスト Create an internal testing track for fast QA or a closed testing track より広範なテストのためにトラッキング
  2. __CAPGO_KEEP_0__を署名したものをアップロードし .aab テストリリースを公開する
  3. テスターのメールアドレスを追加し、オプトインリンクを共有する
  4. Google Playからビルドをインストールするようにテスターに指示する
  5. PlayでインストールされたビルドでGoogle Play Billingの購入フローの全体的な動作を検証する
  6. あなたの個人開発者アカウントが2023年11月13日以降に作成された場合、少なくとも14日間連続して閉鎖テストにオプトインしたテスターが12人以上いるようにして、生産環境の申請前に保証する

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を使用していません
  • 誤解を招くサブスクリプション条項
  • 非表示のコスト

__CAPGO_KEEP_0__データ保護方針:

  • __CAPGO_KEEP_0__プライバシーポリシーが欠落している
  • データセーフティの宣言が不正確
  • 過剰な権限
  1. 違反通知を確認する

    • __CAPGO_KEEP_0__を参照してください
    • 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の内容の宣言、テストトラックの設定を組み合わせる必要がある場合です。個別のアシスタンスが必要な場合:

Capgoのチームとコンサルタントカールを予約してください __CAPGO_KEEP_0__

  • Playストアのレビュー準備を完了する
  • テストトラックの設定とテスターの募集
  • IAPの実装レビュー
  • データの安全性とプライバシーの適合性
  • 却下のトラブルシューティングとアピール
  • Playストアへのアプリの提出プロセスを完了する

Capgoの専門家は、現在の要件を乗り越えるために、成功したPlayストアの提出を数百のアプリを導きました。Capgoの専門家はあなたも導くことができます。

__CAPGO_KEEP_0__

If you are using Android Play Store レビュー ガイドラインの IAP の部分から続けてください to plan security and compliance, connect it with IAP の Android Play Store レビュー ガイドラインの部分を使用している場合、セキュリティとコンプライアンスの計画に役立つため、@capgo/native-purchases を接続する必要があります native capability in @capgo/native-purchases について 暗号化 暗号化の実装詳細について 法的合致 法的合致の実装詳細について Capgo セキュリティ スキャナー Capgo セキュリティ スキャナーの製品ワークフローについて Capgo セキュリティ Capgo セキュリティの製品ワークフローについて