Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Free Trial expire date incorrect? [Google Play]

Discussion in 'Unity IAP' started by Harrishun, Jan 15, 2020.

  1. Harrishun

    Harrishun

    Joined:
    Apr 13, 2016
    Posts:
    59
    Hi all,

    I've just come across a strange issue regarding free trials and I can't seem to find any evidence of it happening to anyone else. The quick story is that we want to utilise free trials for subscriptions on both Android (Google Play) and iOS in order to see more users signing up.

    We have taken the following steps:
    • Changed the trial period from 0 to 30 days on our Google Play subscription.
    • Logged into a Google Play account that has not previously had a subscription.
    • Successfully bought a subscription with a free trial (with the correct date of renewal and first charge displayed on Google Play's purchase UI).
    • Checked the database to see whether or not the subscription has updated correctly.
    Where the strangeness has happened is that the period at which the subscription was recorded to eventually renew is only (exactly) a week from the time of purchase, rather than 30 days. There are ways in which we can account for this, but we're wondering if anyone else has experienced this, whether we're doing something wrong, or even whether this is expected behaviour. We have actually tested purchasing subscriptions properly (without the free trial) and that worked as it should, giving us an expiry date exactly a month ahead.

    We have not gotten around to testing on iOS yet, but it will be my next task to look into that, and I'll report back on whether or not that works fine.

    tl;dr: Subscribing with a free trial period has recorded the expiry date 7 days in the future, rather than 30 days like the free trial has been set to be. Has anyone else experienced this? Are there any reasons why this is happening?

    Thank you for reading!

    EDIT: This was all done on production.
     
    Last edited: Jan 15, 2020
  2. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    This is expected behavior in the Google test environment (Alpha/Beta/Internal Test)
     
  3. Harrishun

    Harrishun

    Joined:
    Apr 13, 2016
    Posts:
    59
    Ah, I should have mentioned that this was in production. I can log into the Google Play account that was used and see that the subscription with the correct renewal date appears when navigating to the Subscriptions and Services page in the account settings.
     
    nicholasr likes this.
  4. Harrishun

    Harrishun

    Joined:
    Apr 13, 2016
    Posts:
    59
    I've now tested iOS, which is working as it should.

    Using Google Play's API (Purchases.subscriptions: get), I was able to find information regarding the subscription and the expiryTimeMillis was correct. Curiously, it is not exactly 30 days, but it is close enough and that is the least of my concerns at the moment. (The exact time between startTimeMillis and expiryTimeMillis is 30 days, 1 hour, 59 minutes and 41 seconds.)

    Is it possible that this is a bug on Unity's end?
     
  5. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    We are checking!
     
    Harrishun likes this.
  6. Harrishun

    Harrishun

    Joined:
    Apr 13, 2016
    Posts:
    59
    No worries Jeff! Thanks for that. I'll do a little bit more testing on my end to see if I can reproduce it as well.
     
  7. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    It reproduces every time for you, right?
     
  8. Harrishun

    Harrishun

    Joined:
    Apr 13, 2016
    Posts:
    59
    Yes, I have tested on two separate occasions and this has happened both times. I can do further testing, though the workflow for it is less than desirable (as a new Google account needs to be used each time, as well as a new account within our app).
     
  9. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    Got it, likely no need to test further. We are checking
     
  10. Harrishun

    Harrishun

    Joined:
    Apr 13, 2016
    Posts:
    59
    Great! Appreciate the help.
     
  11. Harrishun

    Harrishun

    Joined:
    Apr 13, 2016
    Posts:
    59
    @JeffDUnity3D Any update on this? Just wondering as we need to fix this for a coming build.
    I'm contemplating whether I should just implement a simple workaround for the time being.
     
  12. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    No updates, we are still looking into it. It will be several weeks at a minimum most likely. I typically create several test subscriptions and several test users when developing my app. Can you confirm that it is still occurring? One review of the code and some Google searching led us to believe that it might only be an issue on Week 52-53 of the year.
     
  13. Harrishun

    Harrishun

    Joined:
    Apr 13, 2016
    Posts:
    59
    No worries, I'll do another test and report back.
     
  14. Harrishun

    Harrishun

    Joined:
    Apr 13, 2016
    Posts:
    59
    Have just done another test and can confirm that it is still happening. Bought at 2020-01-22 23:23:04 UTC time and the date given back is 2020-01-29 23:23:04.
     
  15. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    Got it, we are checking here too
     
    Harrishun likes this.
  16. Harrishun

    Harrishun

    Joined:
    Apr 13, 2016
    Posts:
    59
    I just did a test in the Google Play internal test track (as I'm currently implementing a workaround for the initial 7/30 day inconsistency issue), and found some odd results:
    • Firstly, and the test track has never done this before, it seems as if it has done away with the Google Play test environment for subscriptions. They are no longer sandbox tests, it was registering the subscription (with free trial) directly to the Google account's subscriptions, as if the subscription was purchased on a production version of the app. It never did this before I added a free trial to the subscription (however, this is also the first time I've used the test track to test subscriptions since adding the free trial).
    • I'm now logging the details of the subscription to an external bug tracking site, so that the team here has a constant log of the subscription details as they're purchased, which are here:
    Product ID - <correct>
    Purchase Date - 01/24/2020 04:19:06
    isSubscribed? - True
    isExpired? - False
    isCancelled? - False
    isFreeTrial? - False
    isAutoRenewing? - True
    Remaining Time - 00:01:13.3445950
    isIntroductoryPricePeriod - False
    Introductory Price Period - 00:00:00
    Introductory Price Period Cycles - 0
    Introductory Price - not available
    Expire Date - 01/24/2020 04:19:06

    • The strange this about the above is specifically isFreeTrial, which returns as false (my workaround was actually based on this variable, so it didn't work correctly), and the Expire Date, which was given back as the exact same time as the purchase date.
    • Remaining Time is also strange, as it appears to only be a minute and 13 seconds (but maybe I'm reading the timestamp incorrectly).
    Unsure whether this might help you out @JeffDUnity3D, but I think it's worth having a record of the findings here regardless, in case someone else stumbles upon the same issue.

    Seems like there's definitely something weird going on but this time it seems like it might be a Google Play issue rather than a Unity issue. Unsure if the same results would occur in the production app. On my newly created Google account, the subscription free trial comes up as ending on February 23rd, which should be correct.

    I'll be attempting to implement the workaround again and I'll report back if it's successful that time.
     
  17. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
    Are you adding testers explicitly on your Dashboard, then browsing to the Opt-In link for testing on the device, and then downloading via Google Play? Test users should not be charged.
     
  18. Harrishun

    Harrishun

    Joined:
    Apr 13, 2016
    Posts:
    59
    I added a newly created Google account to the list of test users under Manage Testers on the Internal Test track on the Google Play Console, before uploading a new build. Then I opened the Opt-In link on a browser window with only that Google account logged in. Downloaded via Google Play and the description matched the one entered when uploading the new build, so I'm fairly certain that it was the correct build tested.

    I thought the behaviour was quite strange too, so I'll do another fresh test tomorrow when I'm back in our office.
     
  19. Harrishun

    Harrishun

    Joined:
    Apr 13, 2016
    Posts:
    59
    • Implemented a new workaround regarding the 7 day trial issue.
    • Created a new Google account.
    • Added new Google account to testers on Internal Test Track of Google Play Console.
    • Accepted becoming a tester on the account.
    • Removed previous accounts on test device, logged in with new account.
    • Uploaded build to Internal Test Track.
    • Checked Play Store on test device, description of build updated to reflect new test build information.
    • Installed build, created account, app on development database as expected (is thus different to current live build).
    • Bought new subscription (UI indicated that I was buying a subscription, with 30 day free trial, despite being on Internal Test track - can post image if needed).
    • Got the following data back from our bug-tracking site:
    Product ID - <correct> 
    Purchase Date - 01/28/2020 00:40:38
    isSubscribed? - True
    isExpired? - False
    isCancelled? - False
    isFreeTrial? - True
    isAutoRenewing? - True
    Remaining Time - 6.23:59:49.1937300
    isIntroductoryPricePeriod - False
    Introductory Price Period - 00:00:00
    Introductory Price Period Cycles - 0
    Introductory Price - not available
    Expire Date - 02/04/2020 00:40:38

    • New workaround worked correctly (as it is now based off the dates registered, rather than the isFreeTrial bool.
    So I was able to recreate the weird behaviour of Google Play thinking it's in production. I assume it's not a Unity issue, but still good to note. As you can tell, the information returned from the previous test does not entirely match this test (isFreeTrial and Expire Date). This test more accurately reflects the issue of the expire date only being 7 days ahead.

    As I now have a working workaround, I would call this "solved," but there are clearly still some... quirks, when working with the app stores. Would be great to eventually get an update on whether Unity has found out whether it's an issue on your end @JeffDUnity3D.

    Thank you for the help!
     
  20. unitylicense19

    unitylicense19

    Joined:
    Aug 29, 2018
    Posts:
    32
    I am having a similar issue, free trial days is set to 14 days in dashboard, but expiry date is coming as 7 days in future for the subscription.
    Only in android, IOS seems to be working fine.
    This happend in production environment, this needs to be fixed immediately, as while purchase we show 14 days trial in the UI, users will start complaining that they are getting only 7 days.
    @JeffDUnity3D. when will this be fixed?
    @Harrishun Is it solved for u? what workaround did u put in the production environment?
     
  21. SamOYUnity3D

    SamOYUnity3D

    Unity Technologies

    Joined:
    May 12, 2019
    Posts:
    600
    Could you provide a screenshot of the product's dashboard settings and a screenshot of the product's trial UI?
     
  22. unitylicense19

    unitylicense19

    Joined:
    Aug 29, 2018
    Posts:
    32
    Sorry for late reply.
    I have attached the dashboard settings image.
    "screenshot of the product's trial UI?" what do u mean by this exactly? In-game trial UI?
     

    Attached Files:

  23. SamOYUnity3D

    SamOYUnity3D

    Unity Technologies

    Joined:
    May 12, 2019
    Posts:
    600
    Thanks for the information, I just want to confirm the free trial period is 14 days. The expire date will be the next billing date. Could you provide the device log with the following code for investigation? Thanks.
    Code (CSharp):
    1. #if SUBSCRIPTION_MANAGER
    2.                 // this is the usage of SubscriptionManager class
    3.  
    4.  
    5.                 if (item.receipt != null) {
    6.                     if (item.definition.type == ProductType.Subscription) {
    7.                         if (checkIfProductIsAvailableForSubscriptionManager(item.receipt)) {
    8.                             string intro_json = (introductory_info_dict == null || !introductory_info_dict.ContainsKey(item.definition.storeSpecificId)) ? null : introductory_info_dict[item.definition.storeSpecificId];
    9.                             SubscriptionManager p = new SubscriptionManager(item, intro_json);
    10.                             SubscriptionInfo info = p.getSubscriptionInfo();
    11.                             Debug.Log("product id is: " + info.getProductId());
    12.                             Debug.Log("purchase date is: " + info.getPurchaseDate());
    13.                             Debug.Log("subscription next billing date is: " + info.getExpireDate());
    14.                             Debug.Log("is subscribed? " + info.isSubscribed().ToString());
    15.                             Debug.Log("is expired? " + info.isExpired().ToString());
    16.                             Debug.Log("is cancelled? " + info.isCancelled());
    17.                             Debug.Log("product is in free trial peroid? " + info.isFreeTrial());
    18.                             Debug.Log("product is auto renewing? " + info.isAutoRenewing());
    19.                             Debug.Log("subscription remaining valid time until next billing date is: " + info.getRemainingTime());
    20.                             Debug.Log("is this product in introductory price period? " + info.isIntroductoryPricePeriod());
    21.                             Debug.Log("the product introductory localized price is: " + info.getIntroductoryPrice());
    22.                             Debug.Log("the product introductory price period is: " + info.getIntroductoryPricePeriod());
    23.                             Debug.Log("the number of product introductory price period cycles is: " + info.getIntroductoryPricePeriodCycles());
    24.                         } else {
    25.                             Debug.Log("This product is not available for SubscriptionManager class, only products that are purchase by 1.19+ SDK can use this class.");
    26.                         }
    27.                     } else {
    28.                         Debug.Log("the product is not a subscription product");
    29.                     }
    30.                 } else {
    31.                     Debug.Log("the product should have a valid receipt");
    32.                 }
    33. #endif
     
  24. Harrishun

    Harrishun

    Joined:
    Apr 13, 2016
    Posts:
    59
    Sorry for the late response!
    We basically had to implement a workaround. I set it up so that before posting the subscription data to our database, we check if SubscriptionInfo.getExpireDate() is less than 25 days in the future (our free trial is for 30 days). In the case that it is, we add 30 days to getPurchaseDate(). Our subscription validation is handled server-side, so we automatically check after that new date whether or not the user still has a valid subscription. It's worked well for us so far.

    Hope this helps you!
     
  25. unitylicense19

    unitylicense19

    Joined:
    Aug 29, 2018
    Posts:
    32
    I have attached the logs, expiry date shows only 6 days ahead instead of 13days
     

    Attached Files:

  26. SamOYUnity3D

    SamOYUnity3D

    Unity Technologies

    Joined:
    May 12, 2019
    Posts:
    600
    Thanks for the device log, I saw the information provided in the log seems to indicate that this is a 7-day free trial period?

    'subscription product getFreeTrialPeriod 7.00:00:00'
     
  27. unitylicense19

    unitylicense19

    Joined:
    Aug 29, 2018
    Posts:
    32
    yes exactly thats the issue, it should have been 14 days.
    In the dashboard its set as 14 days as u can see in below screenshot.
     

    Attached Files:

  28. SamOYUnity3D

    SamOYUnity3D

    Unity Technologies

    Joined:
    May 12, 2019
    Posts:
    600
    Thanks for the information. We will check if it is a data processing error.
     
  29. unitylicense19

    unitylicense19

    Joined:
    Aug 29, 2018
    Posts:
    32
    Hi thank you for replying, i was hoping unity can resolve this from their end but not sure when they will get back on this.
    i have few doubts about this workaround, hoping you can help me with the following.
    1)"we add 30 days to getPurchaseDate()" u mean here 30 days to getExpireDate() right
    2)Even if we do this how did u test this workaround, bcos for me currently in android subscription testing is difficult.
    Even in test purchase account, getExpireDate() wrongly shows 7 days expiry date(i had posted in following forum)
    https://forum.unity.com/threads/check-if-subscription-has-ended.571627/
    How did u confirm your workaround was working

    3)Were u able to confirm In real production environment when does the money get deducted, is it after 30 days in your case or on 8th day itself money was deducted ( we are still in process of confirming this)
     
  30. JeffDUnity3D

    JeffDUnity3D

    Unity Technologies

    Joined:
    May 2, 2017
    Posts:
    14,446
  31. unitylicense19

    unitylicense19

    Joined:
    Aug 29, 2018
    Posts:
    32
    yes well that issue anyways is there that in android, Actual duration should be less but in android unity is not giving shorter duration, the SubscriptionInfo class returns 7 days instead of 5min even in testing environment, when subscription ends in 5min, subscription comes expired.
    explained this issue in this https://forum.unity.com/threads/check-if-subscription-has-ended.571627/

    but the free trial wrong duration issue is separate, in the production environment itself wrong trial days is coming, instead of 14 days SubscriptionInfo class returns 7 days as shown in the logs that i have attached in previous posts.

    This issue we have confirmed multiple times in production environment.
     
    JeffDUnity3D likes this.
  32. Harrishun

    Harrishun

    Joined:
    Apr 13, 2016
    Posts:
    59
    Sorry, my terminology may have been a bit confusing. In the case that the DateTime returned from getExpireDate() is less than 25 days from the DateTime returned from getPurchaseDate() - we take the DateTime returned from getPurchaseDate(), and we add 30 days to it, and then record that date for when our server-side subscription receipt validation should revalidate whether the user is still subscribed.

    For example:
    - getPurchaseDate() = 00:00:00 11 June 2020
    - getExpireDate() = 00:00:00 18 June 2020 <- Not at least 25 days from getPurchaseDate()
    - getPurchaseDate() + 30 days = 00:00:00 10 July 2020 <- we record this date to know when to check whether they're still subscribed

    Unfortunately, this workaround does make sandbox testing of subscriptions a bit inefficient. The workaround will always occur on sandbox, due to the shorter periods that sandbox subscriptions last for, which isn't great when testing server-side validation, but at least you can clearly see that the workaround in question is working when the DateTime returned from getExpireDate() is not far enough in the future.

    In order to test server-side validation, I often end up manually changing the DateTime we have stored during sandbox testing to something in the past, and then I run the server-side validator which updates the stored DateTime to the correct time. It's a bit annoying, but I'm unsure of a way to actually check whether the current purchase is in sandbox mode from Unity - if there was, I wouldn't run the workaround in these situations.

    In production, it is easier to see that our workaround is working as expected. When a user subscribes and gets their free trial period, the Google Play UI itself shows that when the free trial will end and we have confirmed that the date is 30 days in the future for us. It is Unity IAP itself that returns only 7 days, which is why we need our workaround.

    Here is an image of one of our email receipts for the free trial.
    The order date is 24 January 2020, and the trial ends on 23 February 2020.

    As you can see, the user is automatically charged at the end of the free trial period. We also have our app set up with the Bugsnag service, so when the workaround is called, I log a message there, allowing us to stay on top of what has happened with our subscriptions.

    Hopefully that makes things a bit clearer. Let me know if I can answer anymore questions!
     
  33. unitylicense19

    unitylicense19

    Joined:
    Aug 29, 2018
    Posts:
    32
    Thank u so much for replying,

    "Bit more doubt on this.
    For example:
    - getPurchaseDate() = 00:00:00 11 June 2020
    - getExpireDate() = 00:00:00 18 June 2020 <- Not at least 25 days from getPurchaseDate()
    - getPurchaseDate() + 30 days = 00:00:00 10 July 2020 <- we record this date to know when to check whether they're still subscribed, "

    Say they are still subscribed after free trial, and pack time is 1 month
    on 19th june if u fetch data from unity it will come as if the trial is ended and pack renewal cycle has started
    - getPurchaseDate() = 00:00:00 19 June 2020 (instead of actual 10 July 2020)
    - getExpireDate() = 00:00:00 29 June 2020 (instead of 10 august 2020)

    but given we know atleast till 10th july free trial is running we will have to ignore the data given from unity.

    on 11th june we fetch from unity again it will give
    - getPurchaseDate() = 00:00:00 19 June 2020 (instead of actual 10 July 2020)
    - getExpireDate() = 00:00:00 29 June 2020 (instead of 10 august 2020)

    so here also we will have have to add extra days to both the purchase date and expiry date(the difference in days found between actual trial end and trial end date given by unity)

    would not this be long sequence of adding extra days for every renewal based on assumption?
    One corner case i could think of is payment for renewal sometimes happen a day before the actual renewal time, so user might have payed already, but in the game bcos we cant depend on unitys start date and end date, we would not be able to get this data that user has payed and renwal has already happend.

    to test all this again sandbox is not enough right, i mean testing will be very difficult here.

    I hope u understood my doubts