メインコンテンツまでスキップ

エラーリファレンス

このページは、AppCoins iOS SDK が返しうるすべてのエラーコードの完全なリファレンスであり、ネイティブの Swift インターフェースと Unity IAP v5 連携の両方を対象としています。各エラーについて、その意味、よくある原因、推奨される対処方法を記載しています。


Swift のエラー(AppCoinsSDKError

Swift SDK がスローするエラーはすべて AppCoinsSDKError 型です。この列挙型には 6 つのケースがあります。

networkError

SDK が行ったネットワークリクエストが、レスポンスを受け取る前に失敗しました。

よくある原因:

  • デバイスがインターネットに接続されていない。
  • Aptoide の課金サーバーに一時的に到達できなかった。
  • リクエストがタイムアウトした。

対処方法:

  1. SDK のメソッドを呼び出す前に接続状態を確認します(例: NWPathMonitor)。
  2. 一時的な障害に対して、指数バックオフによる再試行を実装します。
  3. 「接続を確認して再試行してください」といったメッセージをユーザーに表示します。
do {
let products = try await Product.products()
} catch let error as AppCoinsSDKError {
if case .networkError(let description) = error {
print("Network error: \(description)")
// Show retry UI
}
}

systemError

AppCoins の内部システムエラーが発生した、またはサーバーが予期しないレスポンスを返しました。

よくある原因:

  • ユーザー操作や接続状態に起因しない SDK 内部の障害。
  • Aptoide 課金サーバーからの予期しない、または不正な形式のレスポンス。

対処方法:

  1. 診断のために説明文の全体をログに記録します。
  2. 短い待機時間をおいて、操作を 1 回再試行します。
  3. セッションをまたいでエラーが続く場合は、記録した説明文を添えて Aptoide サポートに報告してください。
if case .systemError(let description) = error {
print("System error: \(description)")
}

notEntitled

ホストアプリケーションに、SDK がウォレット情報の保存に必要とする Keychain Sharing のエンタイトルメントがありません。

よくある原因:

  • Keychain Sharing 機能がターゲットに追加されていない。
  • キーチェーングループが com.aptoide.appcoins-wallet 以外の値(例えばアプリ自身のバンドル識別子)に設定されている。

対処方法:

  1. Xcode でターゲットを選択し、Signing & Capabilities タブを開きます。
  2. + をクリックして Keychain Sharing 機能を追加します。
  3. Keychain Groups の一覧で、既存のエントリを com.aptoide.appcoins-wallet に正確に置き換えます。
  4. クリーンしてから再ビルドします。
⚠️
キーチェーングループは、接頭辞も接尾辞も付けずに com.aptoide.appcoins-wallet である必要があります。Xcode がチーム ID やバンドル識別子を自動入力する場合がありますが、そのエントリは削除し、上記の値を手動で入力してください。
if case .notEntitled = error {
// Configuration error — cannot be recovered at runtime.
// Fix in Xcode Signing & Capabilities.
print("Missing Keychain Sharing entitlement.")
}

productUnavailable

要求された SKU が見つからないか、現在購入できない状態です。

よくある原因:

  • コード内の SKU 識別子が、Aptoide Connect で定義されたものと完全に一致していない。
  • アプリが Aptoide Connect でまだ審査・承認されていない。
  • 商品が Aptoide Connect で無効化されている。

対処方法:

  1. Aptoide Connect を開き、SKU 識別子が 1 文字単位で一致していることを確認します(大文字と小文字は区別されます)。
  2. アプリが Aptoide Connect で提出・承認済みであることを確認します。審査を通過するまで商品を照会することはできません。
  3. 商品が有効であり、アーカイブされていないことを確認します。
if case .productUnavailable(let description) = error {
print("Product unavailable: \(description)")
}

purchaseNotAllowed

現在の状況では、ユーザーによる購入が許可されていません。

よくある原因:

  • デバイスでペアレンタルコントロールが有効になっており、購入が制限されている。
  • ユーザーのアカウントに地域制限があり、この購入ができない。
  • スクリーンタイムやその他の制限プロファイルがアプリ内購入をブロックしている。

対処方法: このエラーはアプリ側では解決できません。現在の状況では購入が許可されていない旨のメッセージを表示し、デバイスの制限設定を確認するようユーザーに案内してください。

if case .purchaseNotAllowed(let description) = error {
// Inform the user — nothing the app can do programmatically.
print("Purchase not allowed: \(description)")
}

unknown

上記のいずれのカテゴリにも該当しないエラーが発生しました。

対処方法:

  1. 診断のために、エラーが返した説明文をログに記録します。
  2. 一時的な障害として扱い、ユーザーが再試行できるようにします。
  3. エラーが継続的に発生する場合は、説明文の全体を添えて Aptoide サポートに報告してください。
if case .unknown(let description) = error {
print("Unknown error: \(description)")
}

Unity のエラー(AppCoinsSDKError の Unity IAP へのマッピング)

Unity IAP v5 連携では、AppCoins のエラーが標準的な Unity IAP の失敗理由に変換されます。以下の表に完全な対応関係を示します。

AppCoins のエラーUnity IAP の理由対象
productUnavailableProductFetchFailureReason.ProductsUnavailableOnProductsFetchFailed
networkErrorProductFetchFailureReason.ProviderUnavailableOnProductsFetchFailed
productUnavailablePurchaseFailureReason.ProductUnavailableOnPurchaseFailed
purchaseNotAllowedPurchaseFailureReason.PaymentDeclinedOnPurchaseFailed
notEntitledPurchaseFailureReason.PaymentDeclinedOnPurchaseFailed
systemErrorPurchaseFailureReason.UnknownOnPurchaseFailed
unknownPurchaseFailureReason.UnknownOnPurchaseFailed

Unity IAP v5 での購入失敗の処理:

_controller.OnPurchaseFailed += OnPurchaseFailed;

private void OnPurchaseFailed(FailedOrder order)
{
switch (order.FailureReason)
{
case PurchaseFailureReason.UserCancelled:
// User dismissed the payment sheet — no action needed.
break;

case PurchaseFailureReason.ProductUnavailable:
// SKU not found in Aptoide Connect — check your product configuration.
Debug.LogError("Product unavailable: " + order.Details);
break;

case PurchaseFailureReason.PaymentDeclined:
// Parental controls, region restriction, or missing Keychain entitlement.
// Show the user a message; check Xcode entitlements if this is unexpected.
Debug.LogError("Payment declined: " + order.Details);
break;

default:
// Transient or unknown failure — allow retry.
Debug.LogError($"Purchase failed ({order.FailureReason}): {order.Details}");
break;
}
}

Unity IAP v5 での商品取得失敗の処理:

_controller.OnProductsFetchFailed += OnProductsFetchFailed;

private void OnProductsFetchFailed(ProductFetchFailed failure)
{
Debug.LogError("Products fetch failed: " + failure.FailureReason);
foreach (var product in failure.FailedFetchProducts)
Debug.LogError("Failed to fetch product: " + product.id);
}

検証エラー

Swift — VerificationResult.unverified

購入が成功すると、SDK はローカルで署名チェックを実行します。署名を検証できない場合、結果は .unverified(transaction, error) になります。

case .success(let verificationResult):
switch verificationResult {
case .verified(let purchase):
// Signature check passed — safe to grant the item.
try await purchase.finish()

case .unverified(let purchase, let verificationError):
// Signature check failed. Decide based on your business logic:
// Option A (lenient): grant the item anyway and finish.
// try await purchase.finish()
// Option B (strict): do NOT finish — Aptoide will refund after 24 hours.
print("Unverified purchase: \(verificationError)")
}
⚠️
未検証のトランザクションに対して purchase.finish() を呼び出さない場合、その購入は 24 時間後に自動的に返金されます。リリース前に、この点を考慮したビジネスロジックを実装してください。

Unity — レシート内の verificationResult フィールド

PendingOrder に付随するレシートは JSON 文字列です。Payload フィールドを解析すると verificationResult が見つかり、値は "verified" または "unverified" のいずれかです。

private void OnPurchasePending(PendingOrder order)
{
// The receipt is a JSON string: { "Store": "...", "TransactionID": "...", "Payload": "..." }
// Parse Payload to inspect verificationResult.
string receipt = order.Info.Receipt;

// Forward the receipt to your backend for Remote Check validation (optional).
// Then decide whether to grant and confirm:
GiveItemToUser(order);
_controller.ConfirmPurchase(order); // Consumes the purchase.
}

Remote Check によるサーバーサイド検証を使用していて、サーバーが unverified を返した場合は、アイテムを付与せずに購入をタイムアウトさせる(ユーザーには返金されます)という選択も可能です。アイテムを付与する場合は、ConfirmPurchase を呼び出して直ちに消費してください。


実行時の障害として現れる設定や構成の問題については、トラブルシューティングガイド を参照してください。