Works in Editor but not in IOS device connected to XCODE

Hi there,
I have implemented IAP in our project for a single non-consumable purchase.
We have followed the instructions and it works perfectly in the editor.
When we run our app on an iPhone we go through the Sandbox purchase, it recognises we have purchased before and prompts to get it again. Next, we get the ‘you’re all set’ message.
Clicking ok does not then call any of our IAP functions, specifically our OnPurchaseComplete.

Unity Version 2019.2.15f1

These are the logs from XCODE
2019-12-19 20:25:10.975026+0000 Swiperly[2020:748483] UnityIAP UnityEarlyTransactionObserver: Created

2019-12-19 20:25:10.976145+0000 Swiperly[2020:748483] UnityIAP UnityEarlyTransactionObserver: Registered for lifecycle events

2019-12-19 20:25:11.271527+0000 Swiperly[2020:748483] UnityIAP UnityEarlyTransactionObserver: Added to the payment queue

UnityIAP Version: 1.23.1

2019-12-19 20:26:54.891979+0000 Swiperly[2020:748483] UnityIAP: Requesting 1 products

2019-12-19 20:26:54.892781+0000 Swiperly[2020:748483] UnityIAP: Requesting product data…

2019-12-19 20:26:55.834922+0000 Swiperly[2020:749161] UnityIAP: Received 1 products

2019-12-19 20:26:56.110041+0000 Swiperly[2020:748483] UnityIAP: Transaction 1000000606943210 not pending, nothing to finish here

UnityIAP Promo: Clearing promo product metadata

2019-12-19 20:26:56.110745+0000 Swiperly[2020:748483] UnityIAP: Add transaction observer

2019-12-19 20:26:56.110819+0000 Swiperly[2020:748483] UnityIAP: UpdatedTransactions

2019-12-19 20:26:56.112257+0000 Swiperly[2020:748483] UnityIAP UnityEarlyTransactionObserver: Request to initiate queued payments

2019-12-19 20:26:56.116600+0000 Swiperly[2020:748483] UnityIAP: Finishing transaction 1000000607284798

UnityIAP Promo: Clearing promo product metadata

2019-12-19 20:27:40.428896+0000 Swiperly[2020:748483] UnityIAP: PurchaseProduct: [correct code is here]

2019-12-19 20:27:40.433988+0000 Swiperly[2020:748483] UnityIAP: UpdatedTransactions

2019-12-19 20:28:04.140794+0000 Swiperly[2020:748483] UnityIAP: UpdatedTransactions

2019-12-19 20:28:09.693418+0000 Swiperly[2020:748483] UnityIAP: Finishing transaction 1000000607287688

UnityIAP Promo: Clearing promo product metadata
We have followed the code, which we can breakpoint in XCode, until it goes into the depth of the Unity interface warp system.

Also none of the buttons update.

Finally - pressing the restore button - we get the following logs - but again no callbacks.

2019-12-19 20:49:16.757951+0000 Swiperly[2020:748483] UnityIAP: Restore transactions

2019-12-19 20:49:23.128785+0000 Swiperly[2020:748483] UnityIAP: RestorePurchase

2019-12-19 20:49:24.103200+0000 Swiperly[2020:748483] UnityIAP: UpdatedTransactions

2019-12-19 20:49:24.104717+0000 Swiperly[2020:748483] UnityIAP: PaymentQueueRestoreCompletedTransactionsFinished

2019-12-19 20:49:24.112193+0000 Swiperly[2020:748483] UnityIAP: Finishing transaction 1000000607292620

UnityIAP Promo: Clearing promo product metadata

Regards

jon

Please show the code that you are using, as a file attachment. Alternatively, you can look at the IAP sample project here Sample IAP Project I would expect ProcessPurchase to trigger, not OnPurchaseComplete. Perhaps you are using Codeless?

Hi there,

Yes, you are correct, I forgot to mention, we are using codeless. So we have a simple purchase manager script with functions
OnPurchaseComplete and OnPurchaseFailure

OnPurchaseComplete gets called when we play the game in the editor (we have lots of debug logs).
But when in xcode it fails to be called.

It appears to get as far as paymentQueue in UnityPurchasing.m
In that function, it gets to the switch statement SKPaymentTransactionStateFailed

the following code:

NSString* errorCode = [NSString stringWithFormat:@“%ld”,(long)transaction.error.code];
UnityPurchasingLog(@“PurchaseFailed: %@”, errorCode);

where transaction.error.code seems to be 2, upshot being that we end up with the debug output of
PurchaseFailed: 0

which then means:
if (errorCodeString == nil) {
errorCodeString = @“SKErrorUnknown”;
}
hence the failed callback in csharp doesn’t get called.

Other points of interest:
in the Editor, the price panel is always zero, however on the devices it is correct.
On one of the devices where we made a purchase, a look in the itunes purchase history, shows us 2 purchases, one for £0.99 (as expected) and another for £0.00, not sure why.

Thanks

jon

The Editor doesn’t connect to an actual store. Please show a screenshot of your purchase button Inspector properties. Have you configured your products on iTunes Connect, and properly filled out the Apple Business and Tax info? Are you testing via TestFlight? Unity - Manual: Configuring for Apple App Store and Mac App Store

Also, I might add, if this is eventually for a production game, I might recommend scripted IAP vs Codeless, it’s much more flexible. For what you’re trying to do, you will likely need a Codeless Listener and will probably need to write some code anyway. The Sample IAP project link previously has two projects, the first is scripted IAP and the second is Codeless IAP. Please check out the first project.

Hi Jeff,
Thanks for coming back,
It really is the most simple set up- a single non-consumable to remove ads and access all levels, so I think it should be ideal for Codeless.

A couple more notes of interest, when running in Xcode, we see all of the startup function debug logs being called, stating the IAP version etc, so its all running ok.

The buttons are on a UI panel, which I assume is standard, one point of note, the panel in question is deactivated (SetActive(False)) on startup and enabled when a user clicks the store button - not sure if this may have an impact.

Finally - last night while trying to figure out the objective-c code, we noticed that in the depths of one of the object was an error code saying “Apple_cannot connect to ITunes” or something like that.

Attached are screenshots of the purchase button, the restore button and the IAP catalog (I have redacted id’s etc, however, they all match up ok).

Finally - we are developing on the legendary Catalina!

thanks

jon


5301633--532533--purchase button.png
5301633--532536--restore button.png

Please review and answer my previous comments, perhaps you missed my post. Please show your OnPurchaseComplete code, Works in Editor but not in IOS device connected to XCODE

Hi there,

here is the code - although it never gets called

thanks

jon

public class PurchaseManager : MonoBehaviour
{
    public GameObject iapButton;

    public void Awake()
    {
        iapButton.SetActive(true);
    }
     public void OnPurchaseComplete(Product product) {
            Debug.Log("-- Purchased product: " + product.definition.id + ", " + product.definition.ToString() );
         #if UNITY_EDITOR
            StartCoroutine(DisableIapButton() );
         #else
            iapButton.SetActive(false);
        #endif
       

        Debug.Log("Setting Purchase preferences");
        // turn ads off
        GameSettings.MakePurchase();
        GameSettings.SetPurchasedAdsOff();
        GameSettings.SetUnlockAllOn();

    }

    public void OnPurchaseFailure(Product product, PurchaseFailureReason reason)
    {
        Debug.Log("purchase of product: " + product.definition.id + "failed due to " + reason);
           
    }

    private IEnumerator DisableIapButton() {
        yield return new WaitForEndOfFrame();
            iapButton.SetActive(false);
    }

@jsx001 What iPhone model are you testing on? Make sure you are testing via TestFlight and have followed all the steps as mentioned here Unity - Manual: Configuring for Apple App Store and Mac App Store