Langsung ke konten

iOS App Store Pedoman Peninjauan untuk IAP

Agar aplikasi Anda disetujui di App Store memerlukan perhatian yang cermat terhadap pedoman Apple, terutama saat menerapkan pembelian dalam aplikasi dan langganan. Panduan ini mencakup semua yang perlu Anda ketahui agar dapat lulus tinjauan pada kiriman pertama Anda.

iOS App Store Proses Peninjauan

Apple memerlukan pengungkapan harga yang jelas sebelum pembelian apa pun:

Elemen yang Harus Dimiliki:

  • Tampilkan harga pastinya sebelum tombol pembelian
  • Tampilkan frekuensi penagihan (mis., “$9,99/bulan”)
  • Nyatakan dengan jelas apa yang diperoleh pengguna dari uang mereka
  • Tunjukkan kapan tagihan akan terjadi

Penolakan Umum:

“Harga berlangganan harus jelas dan dimuka.”

:::hati-hati Konsistensi Harga Semua harga harus cocok di:

  • App Store daftar metadata
  • Layar pembelian dalam aplikasi
  • Layar manajemen langganan

Bahkan perbedaan $1 antara listingan toko ($4,99) dan aplikasi ($5,99) akan memicu penolakan otomatis. :::

Pengungkapan yang Diperlukan:

  • Semua tingkatan berlangganan yang tersedia ditampilkan bersama
  • Perbandingan fitur per tingkat yang jelas
  • Tidak ada default otomatis ke tingkat premium melalui trik UI
  • Petunjuk pembatalan yang mudah ditemukan

Anjuran dan Larangan Desain UI

Contoh UI yang Sesuai:

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

Penerapan yang Diperlukan:

Setiap aplikasi dengan IAP harus menyediakan cara bagi pengguna untuk memulihkan pembelian sebelumnya tanpa menghubungi dukungan.

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>

Mengapa Gagal:

  • Aplikasi mogok saat diluncurkan
  • Alur pembelian gagal diselesaikan
  • Fitur yang ditampilkan pada tangkapan layar tidak berfungsi

Pencegahan:

  • Uji pada perangkat nyata (bukan hanya simulator)
  • Uji semua aliran langganan dari ujung ke ujung
  • Verifikasi validasi tanda terima berfungsi
  • Periksa penanganan kesalahan jaringan

Mengapa Gagal:

  • Tangkapan layar menunjukkan fitur yang tidak ada dalam versi saat ini
  • Deskripsi menyebutkan fungsionalitas yang tidak ada
  • Harga dalam metadata berbeda dengan harga dalam aplikasi

Daftar Periksa Metadata

Pencegahan:

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

Mengapa Gagal:

  • Meminta kamera/lokasi/kesehatan tanpa penjelasan
  • Permintaan izin mengubur beberapa layar dalam-dalam
  • Deskripsi izin yang tidak jelas atau umum

Pencegahan:

Perbarui Info.plist Anda dengan penjelasan yang jelas:

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

Mengapa Gagal:

  • Klaim seperti “aplikasi #1 di dunia” tanpa bukti
  • Fitur “Tidak Terbatas” yang memiliki batasan tersembunyi
  • Taktik urgensi palsu (“Hanya tersisa 2 tempat!”)

Contoh Pedoman Deskripsi

Pedoman Deskripsi Tambahan

Pencegahan:

  • Bersikaplah spesifik dan faktual dalam deskripsi
  • Hindari superlatif tanpa bukti
  • Jangan menekan pengguna dengan kelangkaan palsu

Mengapa Gagal:

  • Tidak disebutkan cara membatalkan
  • Tombol pembatalan disembunyikan atau dikaburkan
  • Proses pembatalan multi-langkah tanpa alur asli Apple

Pencegahan:

// 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();
}
```## Privasi & Penggunaan Data (Bagian 5.1.1)
Apple telah memperketat persyaratan privasi secara signifikan pada tahun 2025.
### Pengungkapan yang Diperlukan
**Untuk Setiap Izin:**
1. Mengapa Anda membutuhkannya (kasus penggunaan tertentu)
2. Kapan akan digunakan
3. Bagaimana data disimpan/dibagikan
4. Apakah itu opsional atau wajib
### Contoh: Alur Izin yang Benar
```typescript
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';
}

Pastikan label privasi App Store Anda mencerminkan secara akurat:

  • Koleksi riwayat pembelian
  • Alamat email (untuk tanda terima)
  • ID Perangkat (untuk pencegahan penipuan)
  • Data penggunaan (untuk analitik)

Label privasi yang tidak akurat adalah alasan penolakan yang umum pada tahun 2025. Audit pengumpulan data Anda dengan cermat.

Daftar Periksa Pra-Pengiriman

  1. Uji Semua Alur Pembelian

    • Beli setiap tingkat langganan
    • Uji uji coba gratis
    • Pastikan penawaran perkenalan berlaku dengan benar
    • Uji pengembalian pembelian
    • Verifikasi Keluarga Berbagi (jika diaktifkan)
    • Uji pada beberapa perangkat
  2. Verifikasi Konsistensi Harga

    • Periksa kecocokan metadata App Store dengan harga dalam aplikasi
    • Pastikan semua mata uang sudah benar
    • Konfirmasikan durasi uji coba gratis sesuai dengan deskripsi
    • Periksa apakah ketentuan penawaran perkenalan sudah akurat
  3. Tinjau Semua Salinan

    • Hapus teks placeholder
    • Verifikasi klaim dapat diuji
    • Periksa tata bahasa dan ejaan
    • Pastikan deskripsi sesuai dengan versi saat ini
    • Hapus penyebutan pesaing
  4. Izin Tes

    • Minta hanya izin yang diperlukan
    • Tunjukkan penjelasan yang jelas sebelum meminta
    • Uji aliran “Tolak” (aplikasi seharusnya tetap berfungsi)
    • Pastikan deskripsi Info.plist jelas
  5. Siapkan Akun Tes

    • Buat akun pengujian kotak pasir
    • Dokumen kredensial login di Catatan Tinjauan Aplikasi
    • Verifikasi akun uji memiliki langganan aktif
    • Uji apakah pengulas dapat menyelesaikan alur pembelian
  6. Periksa Metadata

    • Tangkapan layar cocok dengan UI saat ini
    • Video pratinjau aplikasi (jika ada) menunjukkan versi saat ini
    • Deskripsi secara akurat menjelaskan fitur
    • Peringkat usia cocok dengan konten
    • Kebijakan privasi dapat diakses dalam aplikasi
  7. Tulis Catatan Tinjauan Rinci

    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.

App Store Garis Waktu Peninjauan

Ulasan Standar: 24-48 jam Periode Puncak: 3-5 hari (App Store rilis hari libur) Akhir pekan: Tidak ada ulasan yang diproses Peninjauan yang Dipercepat: Tersedia untuk perbaikan bug penting (permintaan melalui App Store Connect)

1. Pengungkapan Fungsi AI Jika aplikasi Anda menggunakan AI untuk fitur apa pun, Anda harus:

  • Beri label yang jelas pada konten yang dihasilkan AI
  • Jelaskan bagaimana AI digunakan
  • Dokumentasikan langkah-langkah keamanan konten

2. Kejelasan Langganan yang Ditingkatkan

  • Diperlukan perbandingan rencana berdampingan
  • Tidak ada “pola gelap” yang menyembunyikan opsi yang lebih murah
  • Hapus jalur downgrade/upgrade

3. Intensifikasi Privasi

  • Penegakan Pasal 5.1.1 ditingkatkan
  • Pengawasan lebih cermat terhadap justifikasi pengumpulan data
  • Persyaratan yang lebih ketat untuk aplikasi anak-anak

Yang Berubah dari tahun 2024- Pengiriman modular sekarang diperbolehkan (perbarui halaman produk secara mandiri)

Section titled “Yang Berubah dari tahun 2024- Pengiriman modular sekarang diperbolehkan (perbarui halaman produk secara mandiri)”
  • Acara dalam aplikasi dapat dikirimkan secara terpisah
  • Penegakan yang lebih ketat terhadap UI langganan yang menyesatkan
  • Panduan baru tentang aplikasi cryptocurrency/NFT
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. Baca penolakan dengan cermat

    • Perhatikan pedoman spesifik yang dikutip (misalnya, 3.1.1, 5.1.1)
    • Pahami dengan tepat apa yang ditandai Apple
  2. Perbaiki masalah ini secara menyeluruh

    • Jangan hanya menambal – memperbaiki akar permasalahan
    • Uji perbaikannya secara ekstensif
    • Dokumentasikan apa yang Anda ubah
  3. Respon di Pusat Resolusi

    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. Kirim ulang segera

    • Pengiriman ulang biasanya ditinjau lebih cepat
    • Biasanya dalam waktu 24 jam

Jika Anda yakin penolakan tersebut salah:

App Store Proses Klarifikasi

  1. Klik “Banding” di App Store Connect
  2. Berikan bukti yang jelas:
    • Tangkapan layar menunjukkan kepatuhan
    • Referensi pedoman khusus
    • Penjelasan tentang bagaimana Anda memenuhi persyaratan
  3. Bersikap profesional dan faktual
  4. Sertakan akun pengujian jika fungsinya sulit ditemukan

Contoh Permintaan Dokumen

Jika Anda masih mengalami masalah:

Berjuang dengan peninjauan aplikasi atau butuh bantuan yang dipersonalisasi? Pesan panggilan konsultasi dengan tim kami untuk mendapatkan dukungan khusus dengan:

  • Tinjauan dan optimalisasi implementasi IAP
  • App Store meninjau persiapan dan strategi
  • Tinjauan daftar periksa penyerahan
  • Resolusi penolakan dan banding
  • Selesaikan pengujian dan validasi

Pakar kami telah berhasil membantu ratusan aplikasi lolos peninjauan!