"OnPurchaseFailed,Duplicate transaction" (733943)

hello, we are facing the same issue with version IAP 2.2.1, we tried upgrade to the lastest version 3.0.2, but it does not help, we have been using this implementation in production for 4 years, this issue only just happened about 2-3 weeks ago because we tested it before release 3 weeks ago

Hi guys, we have also the same problem on iOS platform. Even we return "Complete" at the end of ProcessPurchase, transactions couldn’t be complete somehow. I am testing UnityIAP in an empty Unity project without any additional third party dependencies.

Here is the stackoverflow topic about the problem :

https://stackoverflow.com/questions/67110660/unity-iap-2-2-7-3-0-1-consumable-item-transaction-completion-issue

Hi. Same problem here on iOS. Return “Complete” in ProcessPurchase, but it doesn’t consume the product. I’ve tried to manually consume all pending products, but that didn’t help. Here’s the manual consume function. It is called after IAP has initialized:

    void ConfirmPendingPurchasesForAllProducts()
    {
        ProductCollection products = m_StoreController.products;

        for (int i = 0; i < products.all.Length; i++)
        {
            m_StoreController.ConfirmPendingPurchase(products.all[i]);
        }
    }

If you are testing iOS sandbox purchases, it looks like it might be an issue on Apple side, see: [[SKPaymentQueue defaultQueue] fin… | Apple Developer Forums

@jannekai I am also seeing this problem with “DuplicateTransaction” errors in iOS using a Sandbox Account. My consumable IAPs were working fine until about two days ago, but on Thursday we starting seeing this issue where consumables could only be purchased a single time when testing in TestFlight using Sandbox. I don’t know if it is in production because we haven’t launched yet, but this is holding up our launch.

I tested yesterday without issue https://discussions.unity.com/t/706252/50

We’ve also tried upgrading to newer versions and our test plan for purchases fail with the newer version, but works when we revert back.
After the purchase comes through we mark the purchase as pending and then crash the app. With the older versions, when you run the app after initialize that purchase would returned in ProcessPurchase and we can send it to receipt validation but on newer versions we don’t get any callbacks and that store item is permanently locked out with the “Duplicate Transaction” error. We’ve been mostly testing Android. We’ve tried multiple store versions but most recently 3.02. If you think this is a separate issue I can start a new thread. We’re worried that the required google update will force us to upgrade to a version with a known issue.

I just tested your scenario on iOS using IAP 3.1.0 and I’m not seeing the issue. I’m using the Sample IAP Project v2 here and using the v1 Toggle button (to return Pending vs Complete from ProcessPurchase)

https://discussions.unity.com/t/700293/3

  • Launch the app
  • Purchase a consumable (gold50)
  • Prompted for Sandbox credentials
  • It says “You’re all set!”
  • ProcessPurchase is triggered, return Pending
  • I swipe the app up to kill it
  • I restart, and immediately see ProcessPurchase for gold50 when IAP initializes
  • I return Complete from ProcessPurchase
  • I can purchase gold50 again

I’m pretty sure it’s Android only. We did some some failures in our test plans on iOS after the upgrade but they didn’t have 100% repro rate.

I just ran the same test on Android, no issue. The Sample IAP Project was designed to test this very scenario.

@JeffDUnity3D We’ve narrowed it down. It occurs when you crash right after sending the a receipt to be validated but before you get a response. Receipt validation marks a purchase as “acknowledged” and acknowledged purchases aren’t sent to the client after reboot. So the purchase can’t be marked as complete and if you try to purchase the sku it will mark is as duplicate. This behaviour has changed some time after 1.23.3.

Can you share your code? Can you be specific about “before you get a response”. Our receipt validator doesn’t mark the receipt as acknowledged. You shouldn’t be using a Google API on the server to mark it as acknowledged, only verify the receipt. https://docs.unity3d.com/Manual/UnityIAPValidatingReceipts.html. What do you do differently IF you get response? If you mean the purchase remains in Pending state, then yes, Duplicate Transaction is expected. If a product is in Pending, you would expect ProcessPurchase to be triggered on next IAP initialization.

Our player inventory exists purely on the server and the receipt validation backend is shared between a few large published games. They use “acknowledged” to mark that entitlements were created for a purchase.
We are using the iaptestapp but using the companies receipt validation backend which does the google api calls. Changing that behaviour seems unlikely, but how do you suggest they do it? From the documentation it sounds like it is implemented as google intended.

Those docs say

  • Verify the purchase on your server. (only)

What company are you using for receipt validation? Please share your IAP code. And what response are you referring to? Is the transaction left in Pending? I spoke to engineering and we already do the acknowledge, doing it on the server would lead to undetermined behavior. But let’s first follow your code path.

Wizards of the Coast has shared services for receipt validation and entitlement fulfillment. I wouldn’t be able to share that code with you but I have confirmed that they used acknowledged to mark purchases as fulfilled. I don’t think there’s any other significant code to share that isn’t just the iap test app.

I’m not asking for server code. Do you mean the Sample IAP Project ? I would need to see how you are handing the response from your server, and how it might affect the client. And can you answer, is the transaction left in Pending? Looking at the code will tell me. The Sample IAP Project uses a Try/Catch block around receipt validation, for example

The bug occurs when we crash before we get a response from receipt validation.
We get a new purchase.
We send the purchase to be validated.
We mark the purchase as pending.
Then we force crash the app.

The server validates the receipt creates the entitlements and marks it as acknowledged.

When the player opens up the app that pending purchase isn’t returned in ProcessPurchase. This is the behaviour that has changed in newer versions of Unity purchasing.

Got it. Unfortunately we are unable to reproduce and don’t have any further suggestions at this time. The IAP Sample Project v1 at that same link provides a toggle to switch between Complete vs Pending as the ProcessPurchase return type at runtime, perhaps you could reproduce without a server side call, and just leave the status in Pending and crash the app as you suggest. Also, recent versions of Unity IAP contain the required and updated Google Billing Library v3. This may be why you are seeing different behavior with the new version of IAP. Also, how are you securely sending the user context from the device to the server to acknowledge the purchase on behalf of the user? Developer Payload has been deprecated, if you were using that approach.

We can’t mark the purchases as complete until we know the receipt was received and fulfilled.

Do validate a receipt you only need to the token (receipt).

The problem is that acknowledged purchases are stuck in limbo. I don’t think there’s any reason to hold back acknowledge receipts if they are still pending.

If you look at GoogleFinishTransactionService.cs in the FinishTransaction function you hold back Acknowledged purchases from being finished. You’re trying not to acknowledge purchases that are already acknowledged (I don’t think there’s any problem with that) but what do you do with the rest of purchases that need to be finished?

I have a feeling like our online receipt validation is working as expected. If so then Unity IAP doesn’t properly support online receipt validation anymore but it could with just this small fix and not hold back pending acknowledged purchases.

I have the same problem:
https://discussions.unity.com/t/836665

And I really don’t know, why JeffDUnity3D doesn’t want to fix this critical bug.