6

Since iOS 13.4, the dialog for in-app purchases does not show up when the line...

[[SKPaymentQueue defaultQueue] addPayment:payment]; 

...is executed.

Pre iOS 13.4 a dialog popup showed up where the user confirmed the purchase, but now nothing. Does anyone know what might be causing this issue?

Notes:

  • It's a fullscreen game based upon libSDL and gles 3.0.
  • While 99% of the code base is C++, the in app purchases is made in Objective C++
  • It worked before iOS 13.4
Viktor Sehr
  • 12,825
  • 5
  • 58
  • 90
  • Did you happen to find a workaround to this issue? – Daniele Mar 29 '20 at 20:41
  • 1
    No, not yet. Do you have the same problem? – Viktor Sehr Mar 29 '20 at 21:31
  • 1
    Yes I do, It just won’t display the purchase dialog. It’s working great on iOS 13.3.1 – Daniele Mar 29 '20 at 21:44
  • 1
    I’m working with flutter and I opened this issue. The underlying problem appears to be the same. So I’ll leave the link here if you want to check it out https://github.com/flutter/flutter/issues/53534 – Daniele Mar 29 '20 at 21:49
  • Great, please give an update here if you get some feedback there. One difference is that the dialog does not show up at all (reading your issue it seems it at least show up once for you) – Viktor Sehr Mar 30 '20 at 09:35
  • Have you seen if the transaction state for the transaction has been set to Failed or something? – Viktor Sehr Mar 30 '20 at 09:50
  • Please file a radar if this impacted you, following these instructions: https://stackoverflow.com/a/60982115/308315 – iwasrobbed Apr 01 '20 at 23:49

4 Answers4

6

try to totally "flush" the queue once:

    - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions { 
        for (SKPaymentTransaction *transaction in transactions) {

        //debug - finish all transactions to make queue empty  
        [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; 
/*
            switch (transaction.transactionState) {
                case SKPaymentTransactionStatePurchased:
                     //your code 
                     [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                     break;

                case SKPaymentTransactionStateFailed:
                    //your code 
                    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
                    break;
            }
*/
        }
    }

then after replace it back by your code and try to make purchase.

Gabiden
  • 486
  • 3
  • 5
  • 1
    After that, I was able to make the purchase dialog popup correctly, but only the very first time after flushing the transactions. Awesome! We're close! Now, it looks like `finishTransaction` doesn't get called on iOS 13.4. do you have got an idea on how to fix it? – Daniele Mar 31 '20 at 17:43
  • 2
    actually you should always "finishTransaction" by yourself. I've updated answer to be clear. – Gabiden Mar 31 '20 at 22:51
5

First, ensure you're finishing transactions upon success/failure:

In our case, the old code was not calling SKPaymentQueue.default().finishTransaction(transaction) to remove it from the queue. Prior to iOS 13.4, that apparently worked fine even though the documentation says it’s required

So what would happen is the dialog would show once and the person would cancel and then from that point on the transaction would persist in the queue and automatically return as cancelled without showing the dialog again. Finishing the transaction purges it and allows the dialog to show again


If that doesn't work:

Per an Apple engineer's request, I filed a radar for this (FB7648374) with App Store logging and sysdiagnose

Please do the same:

iwasrobbed
  • 46,496
  • 21
  • 150
  • 195
1

I was having the same problem, this is how I solved it.

Perform the following actions with each purchase transaction.

1- remove all IAPPayment and IAPProductRequest.

func reset() {
    requests.removeAll()
    payments.removeAll()
}

2- remove all transactions.

func cleanTransactions() {
    reset()
    for transaction in SKPaymentQueue.default().transactions {
        SKPaymentQueue.default().finishTransaction(transaction)
    }
}
David Buck
  • 3,752
  • 35
  • 31
  • 35
-1

You can also just reboot your device

Dimitar Marinov
  • 922
  • 6
  • 14