YoYoGames / GMEXT-GooglePlayBilling

Repository for GameMaker's GooglePlayBilling Extension
Other
6 stars 2 forks source link

Purchase keeps getting cancelled. #9

Closed MHG-Works closed 4 months ago

MHG-Works commented 4 months ago

Hi,

EDITED NOTE: The issue is applicable for the most recent version of the extension, 1.0.6, which I obtained from the marketplace very recently when I started implementing iaps a few days ago.

There is a problem with the extension. I can get it to initiate a purchase, but it keeps failing to acknowledge the purchase after a few minutes and the purchase is refunded.

I'm using my own gmail account and running this via internal testing, and am currently only testing with the No Ads IAP. Once I tap the button for the No Ads IAP, I get the option to "Test card, always approves". Once I do so, the purchase passes thru and I get an email telling me that my test purchase was successful. While I'm inside the app after making the purchase, the button does not get locked like it is supposed to and tapping it then gives me an error telling me I already own it. If I restart the app, then the button gets locked. However, shortly afterwards, I get an email telling me that my purchase was cancelled, with the following message:

"This test purchase was cancelled because it was not acknowledged. You should ensure that all purchases are acknowledged so that they are not subject to refunds. For more information, see https://developer.android.com/google/play/billing/integrate#process."

If I restart the app, the button for No Ads becomes clickable again.

So there is clearly an issue with the extension not performing the acknowledgement step correctly.

I did not make any changes to how the extension works whatsoever, except for using my own Google Licensing Public Key and changing the product id for the No Ads iap. I know there is no issue on setting up things on my end as the details of the iap are displayed correctly and obviously, the test purchase can be made.

Could someone please fix this issue and update the extension?

Thanks.

MHG-Works commented 4 months ago

Hi @jzavala-YYG ,

Thanks for the reply. As of the extension version 1.0.6, the function _iapQueryPurchases() does not register when I type it in the code editor. There is also no function with that name in the instructions document. In case you meant _GPBillingQueryPurchases, this function was deleted as of version 1.0.6.

Thanks.

jzavala-YYG commented 4 months ago

Hi @MHG-Works

Sorry about my "_GPBillingQueryPurchases" reply I got confused with the apple extensions equivalent

I did a fast test to confirm if doesn't work.

1) I create a new "yoyonoads2" 2) I changed the **#macro IAPnoads** 3) I buy it image 4)Close and open the app to confirm if persists image

Seems that it's working correctly

Please confirm your integration and if the problems persist re-open the ticket

MHG-Works commented 4 months ago

I'm not sure if you're receiving gmail notifications on your phone, but could you please confirm if you actually only receive the success receipt and not the cancellation email? I've set my developer gmail account as an internal tester along with a separate gmail account which I use on a different phone. If I make a test purchase with either, I get the successful purchase:

image

But then after waiting a few minutes, I get the purchase cancellation email. I don't even have to close the app, soon as I get confirmation that the purchase ack failed, I can buy the iap again, even tho I could not buy it just a few seconds before, after the initial purchase. I've tested this with my main dev gmail account as tester, and a different gmail account as a tester also, on a separate phone where I'm logged into gmail with the second email.

I repeat, the purchase acknowledgement is not working. I would advise you to please check your test again and see if indeed it has stayed in the purchase state after you first ran the test without having reset anything. If you've reset things, please run the test again, and on this new test run, wait at least 5-7 minutes after the initial purchase, then try purchasing again. If you try purchasing again immediately after a few seconds or even a minute or so, yeah it will tell you that you own the product already - you have to wait a bit.

Thanks.

jzavala-YYG commented 4 months ago

@MHG-Works

I can confirm that I'm not getting a cancellation email and the NoAds2 IAP persists

You are keeping the relationship of your NoAds object with _Obj_GooglePlayBillingDurable? Please check if user Event0 it's triggered , in that event _GPBillingAcknowledgePurchase(purchaseToken); should be called

DiasFranciscoA commented 4 months ago

Good morning, @MHG-Works! If you're working with the latest version of the extension demo, we recommend checking the IDE console logs for any issues during the setup process. As detailed in our One Time Purchase Guide, please ensure you're following the outlined steps. Specifically, if you're receiving the gpb_acknowledge_purchase_response event with a gpb_no_error response code, this is crucial information for us. Could you confirm whether this is happening? Your feedback is invaluable to us.

MHG-Works commented 4 months ago

Morning @DiasFranciscoA ,

Found the cause of the problem. In the example project, you have this section for the gpb_iap_receipt case:

// This is purely an example. Verifying in this manner is less secure and prone to spoofing. // Ideally, developers will verify all IAPs, consumable/subs/entitlements using their own server. var signature = GPBilling_Purchase_GetSignature(token); var purchaseJsonStr = GPBilling_Purchase_GetOriginalJson(token); if(GPBilling_Purchase_VerifySignature(purchaseJsonStr, signature)) { // At this point the purchase was verified and we should now proceed to // store the purchaseToken for later triggering the acknowledge/consume logic // that confirms the purchase within the google play servers. purchaseTokens[$ sku] = token; show_message_async("Verif success") //<- This part added by me }

In the example project, I would advise commenting out the check for if(GPBilling_Purchase_VerifySignature and letting users know about it in a comment.

More importantly, there is an issue with the GPBilling_Purchase_VerifySignature() function. In the code editor, it says it only takes one argument, but the example (and the manual) state that it has two arguments. So this function needs to be fixed. Probably don't need to comment the GPBilling_Purchase_VerifySignature part out if the correction is made.

After commenting it out, the No Ads button got locked immediately, I got debug messages printed, and didn't get any purchase cancelled email. The No Ads button continues to remain locked for purchase on resetting the app.

DiasFranciscoA commented 4 months ago

The functionality you're referring to should operate correctly without the need to comment out any lines. The demo provides a fully functional example, although it's important to note that it's not considered safe or secure due to susceptibility to spoofing. However, it has been verified to work correctly on our end. If you're encountering issues, there might be aspects we've overlooked. We encourage you to submit a bug report, including a project that reproduces the problem and any relevant debug logs. This will enable us to accurately identify and address the issue more effectively.

MHG-Works commented 4 months ago

Can you provide an email I can use to add to my tester list? I will revoke the purchase and uncomment that line to replicate the issue. I can then send the test link as well as the project file. Though like I said before, I’m using the YoYo demo project itself and only changed the macro to use the id of the product for No Ads, and added my public licensing key. Nothing else.

EDIT: I now realize that the GPBilling_Purchase_VerifySignature(purchaseJsonStr, signature)) check is needed for server verification as well so thanks for re-opening it. The signature verification check must work correctly for securing the IAPs from fraudulent purchases. I revoked the purchase and tested to see what values I'd get for the following:

`var sku = purchase[$ "productId"]; var token = purchase[$ "purchaseToken"];

            // This is purely an example. Verifying in this manner is less secure and prone to spoofing. 
            // Ideally, developers will verify all IAPs, consumable/subs/entitlements using their own server.                       
            var signature = GPBilling_Purchase_GetSignature(token);
            var purchaseJsonStr = GPBilling_Purchase_GetOriginalJson(token);    

            show_message_async("sku " + string(sku))
            show_message_async("token " + string(token))
            show_message_async(signature);
            show_message_async(purchaseJsonStr);`

And I'm getting proper values (and not nulls or undefined values). So I'm at a loss as to why verification using that _VerifySignature function for the token and signature fails to work on my end, but apparently seems to be working fine on your end. If I send my project file using Help > Report a GameMaker bug, will this send the project file with my public license key? Or should I scrub this first?

DiasFranciscoA commented 4 months ago

To streamline the process and ensure your issue is handled efficiently, I recommend reporting your issue through Zendesk instead of using the Help > Report a GameMaker bug option. This method allows for a more direct and secure exchange of information. When submitting your ticket on Zendesk, please include the public key as it is essential for us to test your application locally. Rest assured, any project files you submit will be accessible exclusively to the YoYoGames team, ensuring your work remains confidential. Additionally, we will provide an email address for you to add as a tester, which can be removed from your testers' list once we've resolved the bug. Opening a Zendesk ticket is the best way to ensure all necessary information and attachments are securely and efficiently handled.

MHG-Works commented 4 months ago

^Done. Hope this can get resolved soon.

DiasFranciscoA commented 4 months ago

As we've resolved the issue discussed in this ticket, I'm closing it. The root cause was indeed related to the incorrect use of the Google Public Key, which led to the validation problems we observed. For the record and to assist anyone facing similar issues in the future, please ensure the correct base64-encoded public key from the Google Play Developer Console is used for purchase signature verifications. This key is crucial for such operations and differs from the "developer public key."

Thank you to everyone who contributed to diagnosing and resolving this matter.