You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TestFlight中In-App Purchase无法使用导致应用被苹果审核驳回的问题排查求助

Troubleshooting Your TestFlight IAP Failure

Hey Joseph, let's walk through the most common issues that could be blocking your In-App Purchase from working in TestFlight—since it worked in Xcode local testing, the problem is almost certainly tied to how TestFlight interacts with App Store Connect and your app's production-ready configuration.

1. Double-Check App Store Connect IAP Setup

Even though your IAP shows "Ready to Submit," a few easy-to-miss details could break things:

  • Confirm your code's [my IAP identifier] matches the exact Product ID in App Store Connect (case-sensitive, no extra spaces or typos).
  • In your app's App Store Connect page, go to App Information and make sure the "Use In-App Purchase" checkbox is enabled. This is a common oversight!
  • Verify your IAP's Availability settings: it should be set to your test region (or "All Territories")—TestFlight respects geographic restrictions for IAPs.
  • Ensure your TestFlight build is linked to the IAP: if you added the IAP after uploading your build, reupload a new build to sync the association.

2. Fix StoreKit Configuration for TestFlight

This is likely the biggest culprit:

  • When testing real IAPs in TestFlight, you must set StoreKit Configuration to "None" in Xcode's build settings. The Configuration.storekit file is only for local Xcode testing—it forces the app to use mock data instead of connecting to Apple's real Sandbox servers.
  • After changing this setting, recompile and upload a fresh build to TestFlight—old builds will retain the incorrect configuration.

3. Correct Payment Queue Observer Setup

Your code adds the observer only when initiating a purchase, which can cause missed callbacks:

  • Add the payment queue observer as soon as your scene loads, not just when the user taps "buy." Add this to your Menu scene:
    override func didMove(to view: SKView) {
        super.didMove(to: view)
        SKPaymentQueue.default().add(self)
    }
    
  • Also, clean up the observer when the scene is destroyed to avoid memory leaks:
    override func willMove(from view: SKView) {
        super.willMove(from: view)
        SKPaymentQueue.default().remove(self)
    }
    

This ensures you catch all transaction states, even if there are pending transactions from previous test attempts.

4. Use a Sandbox Tester Account

TestFlight IAPs require a dedicated Sandbox test account—you can't use your personal Apple ID:

  • Create a Sandbox tester in App Store Connect under Users and Access > Sandbox Testers.
  • On your test device, sign out of the App Store (Settings > [Your Name] > Media & Purchases > Sign Out), then launch the TestFlight app and sign in with the Sandbox tester credentials when prompted to make a purchase.

5. Log Detailed Error Messages

Your current code only prints "Failed" without context—add error logging to pinpoint issues:

case .failed:
    SKPaymentQueue.default().finishTransaction(transaction)
    if let error = transaction.error as? SKError {
        print("Purchase failed: \(error.localizedDescription) | Code: \(error.code.rawValue)")
    } else {
        print("Purchase failed with unknown error")
    }

Common error codes like SKError.productNotFound (mismatched Product ID) or SKError.paymentNotAllowed (Sandbox account issue) will immediately tell you what's wrong.

6. Reupload a Fresh Build

After fixing any configuration or code issues, upload a new build to TestFlight. Old builds sometimes don't sync changes to Capabilities or IAP associations, so a fresh upload ensures all settings are applied correctly.

Start with the StoreKit Configuration fix and Sandbox account check—those are the most frequent causes of TestFlight IAP failures. Once you add the error logging, you'll have concrete details if you hit any remaining snags.

内容的提问来源于stack exchange,提问作者Joseph

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 01:47:34