アプリ内課金(In-App Purchase)は個人開発アプリの収益化において欠かせない機能ですが、Rorkで実装する際に「テスト決済が通らない」「商品が見つからないエラーが出る」「本番環境では動くのにSandboxで失敗する」といった問題に直面することがよくあります。
IAPが動かないときに起きる主な症状
まず、どのような症状が出ているかを確認しましょう。症状によって原因が異なります。
- SKErrorDomain / SKErrorUnknown: StoreKitの汎用エラー。設定ミスや環境問題が原因
- 商品情報が取得できない(products配列が空になる): App Store ConnectとのProduct ID不一致
- "Cannot connect to iTunes Store": ネットワーク問題またはSandbox環境の不具合
- RevenueCatの
CustomerInfoが常に空: API Keyの設定ミスまたは初期化タイミングの問題 - "This In-App Purchase has already been bought": Sandboxアカウントの購入履歴が残っている
- 本番では動くがSandboxでは失敗する: Sandboxアカウントの設定問題
症状をメモしてから、以下の原因分析へ進んでください。
原因の分析:12パターンのエラー原因
パターン1: Product IDの不一致
最も多い原因です。App Store Connectに登録したProduct IDと、コード内で使用しているIDが一文字でも違うと商品を取得できません。
パターン2: App Store ConnectのIAP商品が「審査中」または「未承認」
商品を登録しただけでは使えません。ステータスが「有効」になっている必要があります。
パターン3: Sandboxテスターアカウントの設定ミス
iPhoneの設定でSandboxテスターアカウントを正しく設定していないと、Sandboxでの購入ができません。
パターン4: RevenueCatのAPIキーの誤り
RCPublicKey(公開キー)とSecret Keyを混同している、またはプラットフォーム(iOS/Android)のキーを逆に設定しているケースがあります。
パターン5: アプリのBundle IDの不一致
App Store ConnectのBundle IDと、Rork/Expoのapp.jsonのBundle IDが一致していないとIAPは動作しません。
パターン6: In-App Purchase機能が有効化されていない
Xcodeプロジェクトや、Rork Maxのビルド設定でIn-App Purchase Capabilityが有効になっていないケースがあります。
パターン7: Sandbox購入履歴のリセットが必要
Sandboxアカウントで一度購入すると、同じアカウントでの再購入テストが「すでに購入済み」となります。定期購読の場合は有効期限が短縮されますが、買い切り商品はリセットが必要です。
パターン8: ネットワーク通信の問題
テスト端末がVPN接続中、または特定のWi-Fiネットワーク下では、App Storeへの接続に失敗することがあります。
パターン9: RevenueCatの初期化タイミング
RevenueCatのconfigure()をアプリ起動のタイミングより遅く呼び出していると、最初の購入時にエラーになることがあります。
パターン10: EASビルドとローカルビルドの差異
expo buildではなくeas buildを使用していない場合、CapabilityやEntitlementsが正しく設定されないことがあります。
パターン11: コード署名の問題
Provisioning ProfileにIn-App Purchase Capabilityが含まれていないと、実機テストでエラーになります。
パターン12: App Store Connectの銀行口座・契約未設定
有料アプリやIAPを販売するには、App Store Connectで有料アプリの契約と銀行口座の設定が完了している必要があります。Sandboxテストは可能ですが、商品ステータスが「有効」にならない場合はこれが原因のことがあります。
解決手順:Step by Step
Step 1: App Store ConnectのIAP設定を確認する
1. App Store Connect(https://appstoreconnect.apple.com)にログイン
2. 対象アプリ → App内課金 → 対象商品を選択
3. ステータスが「有効」になっているか確認
4. Product IDをコピーしてメモしておく(コピー&ペーストで確認)
ステータスが「未完成」の場合は、必要な情報(スクリーンショット、説明文)を追加してください。
Step 2: Product IDをコードと照合する
Rorkが生成するコードのProduct IDと、App Store ConnectのProduct IDを完全一致させます。
// ✅ 正しい例: App Store Connectと完全一致させる
const PRODUCT_IDS = {
monthly: 'com.yourcompany.yourapp.monthly', // ← そのままコピー&ペースト
yearly: 'com.yourcompany.yourapp.yearly',
lifetime: 'com.yourcompany.yourapp.lifetime',
};
// ❌ よくある間違い(スペースや大文字が混入している)
const PRODUCT_IDS_WRONG = {
monthly: 'com.yourcompany.yourapp.Monthly', // 大文字のM
};Step 3: Sandboxテスターアカウントを確認する
1. iPhoneの「設定」→「App Store」→「Sandboxアカウント」
2. テスター専用のApple IDが設定されているか確認
3. 設定されていない場合は、App Store Connectで作成したテスターのメールとパスワードを入力
重要: 本番のApple IDをSandboxテストに使うことはできません。必ず専用のSandboxテスターアカウントを作成してください。
Step 4: RevenueCatの初期化を修正する
RevenueCatを使っている場合、初期化はアプリ起動の最初に行います。
// App.tsx または index.js の最上位で初期化する
import Purchases from 'react-native-purchases';
// ✅ 正しい初期化タイミング(アプリ起動時)
useEffect(() => {
const initializePurchases = async () => {
// iOS用公開キー("appl_"で始まるキー)を使う
await Purchases.configure({
apiKey: 'appl_xxxxxxxxxxxxxxxxxxxxxxxx',
});
// ユーザーIDを設定(任意だが推奨)
if (userId) {
await Purchases.logIn(userId);
}
};
initializePurchases();
}, []); // 依存配列は空にする(一度だけ実行)
// ❌ よくある間違い: コンポーネントのレンダリング内で呼び出す
// Purchases.configure(...) ← これはNGStep 5: 商品情報の取得をデバッグする
商品が取得できているか、ログで確認します。
import Purchases from 'react-native-purchases';
const fetchProducts = async () => {
try {
const offerings = await Purchases.getOfferings();
if (offerings.current === null) {
// Offeringsが設定されていない場合
console.log('No current offering found. Check RevenueCat dashboard.');
return;
}
console.log('Available packages:', offerings.current.availablePackages);
// packages配列が空の場合はApp Store ConnectのProduct IDを確認
} catch (error) {
console.error('Error fetching offerings:', error);
// エラーの詳細を確認してトラブルシューティングへ
}
};Step 6: Bundle IDの一致を確認する
# app.jsonのbundleIdentifierを確認
cat app.json | grep bundleIdentifier
# 出力例(App Store ConnectのBundle IDと完全一致している必要がある)
# "bundleIdentifier": "com.yourcompany.yourapp"App Store ConnectのBundle IDと一致していない場合は、app.jsonを修正してから再ビルドします。
Step 7: Sandbox購入履歴をリセットする
買い切り商品が「すでに購入済み」になってしまった場合は、Sandboxアカウントの購入履歴をリセットします。
1. App Store Connect → ユーザーとアクセス → Sandbox → テスター
2. 対象のSandboxアカウントを選択
3. 「購入の消去」をクリック
または、新しいSandboxテスターアカウントを作成してテストします。
確認方法:解決できたかを検証する
修正後は以下の手順で動作確認を行います。
1. Sandbox環境での購入フローを通しでテスト
① 商品一覧が表示される → Product IDが正しく取得されている
② 購入ボタンをタップ → Sandboxの確認ダイアログが表示される
③ 購入完了 → コンテンツが解放される
④ アプリを再起動 → 購入状態が維持されている(リストア機能の確認)
2. RevenueCatダッシュボードで確認
RevenueCatダッシュボード → Customers → 該当ユーザーを検索
→ Transactions に Sandbox購入が表示されていれば成功
3. ログでエラーがないか確認
// デバッグ用ログを有効化
Purchases.setLogLevel(LOG_LEVEL.DEBUG);
// コンソールに詳細なRevenueCatログが出力される予防策:再発防止のベストプラクティス
IAPエラーを未然に防ぐために、以下を実践してください。
1. 開発初期にIAP設定を完了させる
- App Store Connectへの商品登録・Bundle ID設定は、開発の最初期に行う
- Product IDはスプレッドシートで管理し、コードにはコピー&ペーストで入力する
2. Sandboxテスターアカウントを複数用意する
- 購入履歴のリセット用に最低2つのSandboxアカウントを作成しておく
- テスターメールとパスワードはチームで共有し、メモしておく
3. RevenueCatのオファリング設定を先に完成させる
- コードを書く前に、RevenueCatダッシュボードでオファリング・パッケージの設定を完了させる
- Product IDの入力後に「Save」ボタンを押し忘れないように注意する
4. テスト端末のVPNを無効化する
- テスト中はVPNをオフにする習慣をつける
5. EASビルドで本番同等の環境でテストする
# Sandboxテスト用ビルド(本番環境に最も近い設定)
eas build --platform ios --profile previewエミュレーターではなく、実機でテストすることを強くお勧めします。
アフィリエイトリンク:関連書籍
StoreKitの基本から応用まで丁寧に解説されています。
全体を振り返って
RorkアプリのIAP設定エラーは、そのほとんどが設定の不一致や初期化タイミングの問題です。本記事のチェックポイントを順に確認することで、多くの場合は解決できます。
重要なポイントをまとめると:
- Product IDはコピー&ペーストで完全一致させる
- Sandboxテスターアカウントは本番Apple IDと分離させる
- RevenueCatはアプリ起動の最初に初期化する
- EASビルドで実機テストを行う
- App Store Connectの商品ステータスが「有効」になっているか確認する
アプリ内課金の実装をさらに深掘りしたい方は、Rork Max StoreKit 2 実装ガイドやRevenueCatサブスクリプション収益化ガイドもあわせてご覧ください。