Search code examples
iosswiftin-app-purchase

No payment sheet displayed when testing App Store Promotion In-App Purchase


I'm running into a problem when testing my implementation of App Store Promotions (In-App Purchases offered directly on an app's product page).

According to the documentation, we're supposed to do the following:

  1. Construct a system URL that looks like this, filling in our own bundleId and productIdentifier: itms-services://?action=purchaseIntent&bundleId=com.example.app&productIdentifier=product_name
  2. Send the link to the device.
  3. Open the link on the device.

As far as I understand, this should do two things: 1) the app should open automatically, and 2) the system should show the payment sheet so the transaction can be completed.

However, while my app does open automatically when I tap on the system URL link, no payment sheet is displayed.

Now, I have already implemented the required SKPaymentTransactionObserver method, as described here. The following method should be invoked when the app opens, but is not:

class StoreObserver: NSObject, SKPaymentTransactionObserver, SKProductsRequestDelegate {
    func paymentQueue(_ queue: SKPaymentQueue, shouldAddStorePayment payment: SKPayment, for product: SKProduct) -> Bool {
        //This is not running. Why not?
        return true
    }
}

What am I doing wrong? Why isn't my paymentQueue(_:shouldAddStorePayment:for:) method being called when the system opens the app?

Thank you for your help.


Solution

  • As it turns out, I had neglected to add/remove the observer at app launch/termination, as described here.

    import UIKit
    import StoreKit
    
    class AppDelegate: UIResponder, UIApplicationDelegate {
                    ....
        // Attach an observer to the payment queue.
        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
            SKPaymentQueue.default().add(iapObserver)
            return true
        }
    
        // Called when the application is about to terminate.
        func applicationWillTerminate(_ application: UIApplication) {
            // Remove the observer.
            SKPaymentQueue.default().remove(iapObserver)
        }
                    ....
    }
    

    Adding this to my application solved the problem; the payment sheet is now correctly presented.