In-App purchase codes not working
The promo code process functions as follows.
First, the promo code redemption process, to date, only works in the production environment. After the promo code is redeemed, it is the responsibility of the app to detect that the promo code was redeemed.
The process begins with the user entering their iTunes application to redeem the promo code. After the promo code is redeemed,
the App Store verifies the promo code,
determines which application bundle ID it is for and what the associated In-App Purchase identifier the code is for,
records a charge to the iTunes user account and sets up a queued transaction record for the application / iTunes user account.
At some point after the promo code redemption, the user launches the application. Assuming that the application correctly installs the transactionObserver at application launch time, the transactionObserver queries the App Store for any queued transaction using the current iTunes User account and the application bundle ID. In this case, the transactionObserver detects the matching queued transaction. iOS may present the user with an authentication dialog, which the user uses to validate themselves, then the App Store issues a successful SKPaymentTransactionStatePurchased indication to the applications updatedTransactions delegate method. The behavior is similar to that where the user has just pressed the “Buy” button for the In-App Purchase item. The application processes the transaction and makes the associated content available to the user, then finishes the process by calling finishTransaction to acknowledge the App Store that the application received and processed the transaction.
If you install the app via Xcode or TestFlight, the app always operates in the sandbox. This is also true for the App Review process.
If the app is using In-App Purchase identifiers for the first time in a version of the app, promo codes will not work in the production version of the app until the app is officially released on the App Store. For example, if you define In-App Purchase identifier "my company.myapp.myinapppurchaseitem5" for the first time in app revision v2.0, and App Review approves the app, you must approve the app for App Store use to verify that a promo code for "my company.myapp.myinapppurchaseitem5" works. If the app is in the "pending developer release" state, the promo code for "my company.myapp.myinapppurchaseitem5" will not work. However, once the identifier is released in an app, then in v2.1 of the app, you can verify the promo code for "my company.myapp.myinapppurchaseitem5" while the app is in "pending developer release state".
If you are looking for a means to test the promo code process in the sandbox environment, there is an alternative means to do so. Consider that a promo code results in an queued transaction being registered for a user on the App Store Server. When you make a purchase using the addPayment method, this results in an queued transaction being created. If the app never makes the finishTransaction call after being notified of the .purchased transaction, the next use of the transactionObserver should detect it. Try following these instructions.
In the StoreKit implementation in your application, comment out the use of the finishTransaction call. Prevent the app from making this call - also add a log statement to indicate that the finishTransaction call would have been made, but wasn't.
Install the app to your device (this won't work in the simulator) and make the test purchase with your test user account. Make sure that you see the log statement indicating that the finishTransaction call was not made. Since the finishTransaction call is not being made, the App Store Server will not clear the purchase from the test user record.
Stop the app. If you are launching the app within Xcode, you might want to set a breakpoint on the entry to the updatedTransactions delegate method.
Restart the app. After the call is made to addTransactionObserver, the incompleteTransaction should be detected and iOS should prompt you to authenticate the purchase. After authenticating your test user account, you should see the updatedTransactions delegate method entered with the .purchased indication. If your app can process this incompleteTransaction - it will handle a promo code in the production environment.
One more thing to test - move the app to the background, then to the foreground, if the app never makes the call to finishTransaction, the transaction remains incomplete. You should again be presented with the Authentication dialog - note, the transactionObserver fires in the following three cases
when the addTransactionObserver is called
when the app calls addPayment AND
when the app with active transactionObserver transitions from the background to the foreground.
rich kubota - rkubota@apple.com
developer technical support CoreOS/Hardware/MFI