Langsung ke konten

iOS App Store Review Guidelines for IAP

Untuk mendapatkan persetujuan aplikasi Anda di App Store memerlukan perhatian cermat terhadap pedoman Apple, terutama saat menerapkan pembelian dalam aplikasi dan langganan. Panduan ini mencakup semua yang perlu Anda ketahui untuk lulus review pada pengajuan pertama Anda.

iOS App Store Review Process

Apple memerlukan pengungkapan harga yang sangat jelas sebelum pembelian apa pun:

Elemen yang Harus Ada:

  • Tampilkan harga pastinya sebelum tombol pembelian
  • Tampilkan frekuensi penagihan (misalnya, “$9.99/bulan”)
  • Nyatakan dengan jelas apa yang diperoleh pengguna untuk uang mereka
  • Tunjukkan kapan penagihan akan terjadi

Penolakan Umum:

“Harga langganan harus jelas dan terbuka.”

:::caution Konsistensi Harga Semua harga harus cocok di:

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

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

Pengungkapan yang Diperlukan:

  • Semua tingkat langganan yang tersedia ditampilkan bersama
  • Perbandingan fitur yang jelas per tingkat
  • Tidak ada pengaturan default ke tingkat premium melalui trik UI
  • Instruksi pembatalan yang mudah ditemukan

UI Design Dos and Don'ts

Contoh UI yang Sesuai:

import { NativePurchases } from '@capgo/native-purchases';
function SubscriptionScreen() {
return (
<div>
<h2>Pilih Paket Anda</h2>
{/* Tampilkan semua tingkat dengan setara */}
<PlanCard
title="Basic"
price="$4.99/bulan"
features={['Feature A', 'Feature B']}
/>
<PlanCard
title="Premium"
price="$9.99/bulan"
features={['All Basic', 'Feature C', 'Feature D']}
highlighted={false} // Jangan paksa premium
/>
{/* Info pembatalan yang jelas */}
<Text>
Batalkan kapan saja di Settings > Subscriptions.
Tidak ada pengembalian dana untuk periode parsial.
</Text>
</div>
);
}

Implementasi 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.');
}
}
// Tambahkan tombol "Restore Purchases" yang terlihat
<Button onClick={restorePurchases}>
Pulihkan Pembelian
</Button>

1. Aplikasi Crash atau Fungsionalitas Rusak

Section titled “1. Aplikasi Crash atau Fungsionalitas Rusak”

Mengapa Gagal:

  • Aplikasi crash saat diluncurkan
  • Alur pembelian gagal diselesaikan
  • Fitur yang ditampilkan di tangkapan layar tidak berfungsi

Pencegahan:

  • Uji pada perangkat nyata (bukan hanya simulator)
  • Uji semua alur langganan dari awal hingga akhir
  • Verifikasi validasi kwitansi berfungsi
  • Periksa penanganan kesalahan jaringan

Mengapa Gagal:

  • Tangkapan layar menampilkan fitur yang tidak ada di build saat ini
  • Deskripsi menyebutkan fungsionalitas yang tidak ada
  • Harga di metadata berbeda dari harga dalam aplikasi

Daftar Periksa Metadata

Pencegahan:

// Dokumentasikan dengan tepat apa yang ada di setiap tingkat
const SUBSCRIPTION_FEATURES = {
basic: ['Tanpa iklan', 'Sinkronisasi cloud', 'Tema dasar'],
premium: ['Tanpa iklan', 'Sinkronisasi cloud', 'Semua tema', 'Dukungan prioritas']
};
// Gunakan ini di aplikasi Anda DAN deskripsi App Store

Mengapa Gagal:

  • Meminta kamera/lokasi/kesehatan tanpa penjelasan
  • Permintaan izin tersembunyi beberapa layar dalam
  • Deskripsi izin yang vague atau generic

Pencegahan:

Perbarui Info.plist Anda dengan penjelasan yang jelas:

<key>NSCameraUsageDescription</key>
<string>Akses kamera diperlukan untuk memindai barcode produk untuk upgrade langganan cepat.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Lokasi membantu kami menampilkan konten lokal yang relevan dalam langganan Premium Anda.</string>

Mengapa Gagal:

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

Contoh Panduan Deskripsi

Panduan Deskripsi Tambahan

Pencegahan:

  • Bersifat spesifik dan faktual dalam deskripsi
  • Hindari superlatif tanpa bukti
  • Jangan tekan pengguna dengan kelangkaan palsu

Mengapa Gagal:

  • Tidak ada penyebutan tentang cara membatalkan
  • Tombol pembatalan disembunyikan atau dikaburkan
  • Proses pembatalan multi-langkah tanpa alur native Apple

Pencegahan:

// Selalu beritahu pengguna tentang pembatalan
function SubscriptionInfo() {
return (
<div>
<h3>Cara Membatalkan</h3>
<ol>
<li>Buka Pengaturan iPhone</li>
<li>Ketuk nama Anda di bagian atas</li>
<li>Ketuk Langganan</li>
<li>Pilih aplikasi ini dan ketuk Batalkan</li>
</ol>
<p>Atau kelola langsung di aplikasi App Store.</p>
<Button onClick={openSubscriptionManagement}>
Kelola Langganan di Pengaturan
</Button>
</div>
);
}
async function openSubscriptionManagement() {
// Tautan langsung ke manajemen langganan iOS
await NativePurchases.showManageSubscriptions();
}

Apple telah membuat persyaratan privasi jauh lebih ketat pada 2025.

Untuk Setiap Izin:

  1. Mengapa Anda membutuhkannya (kasus penggunaan spesifik)
  2. Kapan akan digunakan
  3. Bagaimana data disimpan/dibagikan
  4. Apakah opsional atau diperlukan
async function requestCameraPermission() {
// Tampilkan penjelasan SEBELUM meminta
await showDialog({
title: 'Akses Kamera',
message: 'Kami memerlukan akses kamera untuk membiarkan Anda memindai barcode untuk pencarian produk cepat. Foto Anda tidak pernah diunggah atau disimpan.',
buttons: ['Tidak Sekarang', 'Izinkan']
});
// Kemudian minta izin
const result = await Camera.requestPermissions();
return result.camera === 'granted';
}

Pastikan label privasi App Store Anda secara akurat mencerminkan:

  • Pengumpulan riwayat pembelian
  • Alamat email (untuk kwitansi)
  • ID perangkat (untuk pencegahan penipuan)
  • Data penggunaan (untuk analitik)

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

Daftar Periksa Pra-Pengajuan

  1. Uji Semua Alur Pembelian

    • Beli setiap tingkat langganan
    • Uji uji coba gratis
    • Verifikasi penawaran pengenalan diterapkan dengan benar
    • Uji pulihkan pembelian
    • Verifikasi Berbagi Keluarga (jika diaktifkan)
    • Uji pada beberapa perangkat
  2. Verifikasi Konsistensi Harga

    • Periksa metadata App Store cocok dengan harga dalam aplikasi
    • Verifikasi semua mata uang benar
    • Konfirmasi durasi uji coba gratis cocok dengan deskripsi
    • Periksa istilah penawaran pengenalan akurat
  3. Tinjau Semua Salinan

    • Hapus teks placeholder
    • Verifikasi klaim dapat diuji
    • Periksa tata bahasa dan ejaan
    • Pastikan deskripsi cocok dengan build saat ini
    • Hapus penyebutan pesaing
  4. Uji Izin

    • Minta hanya izin yang diperlukan
    • Tampilkan penjelasan yang jelas sebelum meminta
    • Uji alur “Tolak” (aplikasi harus tetap berfungsi)
    • Verifikasi deskripsi Info.plist jelas
  5. Siapkan Akun Tes

    • Buat akun tes sandbox
    • Dokumentasikan kredensial login di Catatan Ulasan Aplikasi
    • Verifikasi akun tes memiliki langganan aktif
    • Uji bahwa 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 menggambarkan fitur
    • Rating usia cocok dengan konten
    • Kebijakan privasi dapat diakses dalam aplikasi
  7. Tulis Catatan Ulasan Terperinci

    Akun Tes:
    Email: reviewer@test.com
    Password: TestPass123!
    Instruksi Pengujian:
    1. Masuk dengan akun tes di atas
    2. Ketuk tombol "Upgrade to Premium"
    3. Pilih langganan "Monthly Premium"
    4. Lengkapi pembelian (tanpa biaya di sandbox)
    5. Verifikasi fitur premium terbuka
    Catatan: Harga langganan ditampilkan dengan jelas sebelum pembelian.
    Instruksi pembatalan ada di Settings > Account.

Garis Waktu Ulasan App Store

Ulasan Standar: 24-48 jam Periode Puncak: 3-5 hari (rilis liburan App Store) Akhir Pekan: Tidak ada ulasan diproses Ulasan Dipercepat: Tersedia untuk perbaikan bug kritis (minta melalui App Store Connect)

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

  • Berikan label jelas untuk konten yang dihasilkan AI
  • Jelaskan bagaimana AI digunakan
  • Dokumentasikan tindakan keselamatan konten

2. Kejelasan Langganan yang Ditingkatkan

  • Perbandingan rencana berdampingan diperlukan
  • Tidak ada “pola gelap” yang menyembunyikan opsi yang lebih murah
  • Jalur downgrade/upgrade yang jelas

3. Intensifikasi Privasi

  • Penegakan Bagian 5.1.1 meningkat
  • Pengawasan lebih pada pembenaran pengumpulan data
  • Persyaratan lebih ketat untuk aplikasi anak-anak
  • Pengajuan modular sekarang diperbolehkan (perbarui halaman produk secara independen)
  • Acara dalam aplikasi dapat diajukan secara terpisah
  • Penegakan UI langganan yang menyesatkan lebih ketat
  • Panduan baru tentang aplikasi cryptocurrency/NFT

Praktik Terbaik untuk Plugin Native Purchases

Section titled “Praktik Terbaik untuk Plugin Native Purchases”

Implementasikan Penanganan Kesalahan yang Tepat

Section titled “Implementasikan Penanganan Kesalahan yang Tepat”
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,
});
// Sukses
await validateReceiptOnServer(transaction.receipt);
showSuccess('Langganan diaktifkan!');
unlockFeatures();
} catch (error: any) {
// Tangani kasus kesalahan spesifik
if (error.code === 'USER_CANCELLED') {
// Pengguna membatalkan - jangan tampilkan kesalahan
console.log('Pembelian dibatalkan oleh pengguna');
} else if (error.code === 'PAYMENT_PENDING') {
showInfo('Pembayaran tertunda. Silakan periksa kembali nanti.');
} else if (error.code === 'PRODUCT_ALREADY_PURCHASED') {
// Pulihkan sebagai gantinya
await NativePurchases.restorePurchases();
} else {
// Tampilkan kesalahan yang ramah pengguna
showError('Tidak dapat menyelesaikan pembelian. Silakan coba lagi.');
}
}
}
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 ? 'Memproses...' : 'Berlangganan Sekarang'}
</button>
);
}
function SubscriptionTerms() {
return (
<div className="terms">
<p>
Langganan secara otomatis diperbaharui kecuali dibatalkan paling lambat 24 jam
sebelum akhir periode saat ini.
</p>
<p>
Akun Anda akan dikenakan biaya untuk pembaruan dalam 24 jam sebelum
akhir periode saat ini.
</p>
<p>
Langganan dapat dikelola oleh pengguna dan pembaruan otomatis dapat
dimatikan di Pengaturan Akun setelah pembelian.
</p>
<p>
<a href="/terms">Syarat Layanan</a> |
<a href="/privacy">Kebijakan Privasi</a>
</p>
</div>
);
}
  1. Baca penolakan dengan hati-hati

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

    • Jangan hanya patch - perbaiki akar penyebabnya
    • Uji perbaikan secara ekstensif
    • Dokumentasikan apa yang Anda ubah
  3. Respons di Pusat Resolusi

    Terima kasih atas masukan Anda. Saya telah mengatasi masalahnya:
    Masalah: Harga langganan tidak jelas di awal
    Perbaikan: Menambahkan tampilan harga eksplisit pada layar pemilihan
    langganan yang menunjukkan "$9.99/bulan" sebelum tombol pembelian. Juga menambahkan
    instruksi pembatalan di layar yang sama.
    Perubahan ada dalam pengajuan ini dan dapat diuji menggunakan
    akun tes yang disediakan.
  4. Ajukan kembali dengan cepat

    • Pengajuan ulang biasanya ditinjau lebih cepat
    • Biasanya dalam 24 jam

Jika Anda percaya penolakan tidak benar:

Proses Klarifikasi App Store

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

Contoh Permintaan Dokumen

Jika Anda masih mengalami masalah:

Kesulitan dengan ulasan aplikasi atau memerlukan bantuan personal? Pesan panggilan konsultasi dengan tim kami untuk dukungan khusus dengan:

  • Tinjauan dan optimisasi implementasi IAP
  • Persiapan ulasan App Store dan strategi
  • Tinjauan daftar periksa pengajuan
  • Resolusi penolakan dan banding
  • Pengujian dan validasi lengkap

Para ahli kami telah berhasil membantu ratusan aplikasi lulus ulasan!