23

I am creating an app that implements the Soomla Unity IAP plugin. In my effort to get the IAP to work, I have gotten to a point where I can make a purchase when in the editor. (Not a real purchase, it just updates the virtual currency that the user can buy/spend in game).

When I launch this on an Android device, I get this error: Authentication is required. You need to sign into your Google Account.

Now I have read multiple different articles where people have had this issue and nothing seems to be helping me.

Here is list of what I have tried so far:

1) Make sure app is published either to alpha or beta for testing.(in alpha now)

2) Make sure prices match for game and in developer console.

3) Use a device that is logged in as a user that is not using the developer email.

4) Make sure the email on the test device is listed as a tester in the developer console.

5) Make sure the necessary permissions are listed in the Android Manifest.

6) Confirm merchant account is set up correctly and verified.

7) Make sure to build as release and not development (not sure if this even matters, but I tried both ways).

8) Completely removed all of the Soomla plugin from the project and then added it back in while following the tutorial very closely just to makes sure nothing small was missed. Still no dice.

I have the core and store components added to the scene that they are necessary in. Please let me know if you have any other ideas of what I should do to fix this problem. In the mean time, here is the StoreAssets.cs code I use for setting up Soomla:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Soomla.Store;

public class StoreAssets : IStoreAssets
{
    public static bool purchased = false;

    public int GetVersion()
    {
        return 0;
    }

    public void onItemPurchased(PurchasableVirtualItem pvi, string payload)
    {
        purchased = true;
    }

    public VirtualCurrency[] GetCurrencies() 
    {
        return new VirtualCurrency[]{TOKEN_CURRENCY};
    }

    public VirtualGood[] GetGoods() 
    {
        return new VirtualGood[] {BACKUP_FORCEFIELD, IMMUNITY, EMP, MULTIPLIER};
    }

    public VirtualCurrencyPack[] GetCurrencyPacks() 
    {
        return new VirtualCurrencyPack[] {FIVE_TOKEN_PACK, TEN_TOKEN_PACK, FIFTY_TOKEN_PACK};
    }

    public VirtualCategory[] GetCategories() 
    {
        return new VirtualCategory[]{};
    }

    /** Virtual Currencies **/

    public static VirtualCurrency TOKEN_CURRENCY = new VirtualCurrency
    (
        "Token",                               // Name
        "Token currency",                      // Description
        "token_currency_ID"                    // Item ID
    );

    /** Virtual Currency Packs **/

    public static VirtualCurrencyPack FIVE_TOKEN_PACK = new VirtualCurrencyPack
    (
        "5 Tokens",                          // Name
        "5 token currency units",            // Description
        "5_tokens_id",                       // Item ID
        5,                                  // Number of currencies in the pack
        "token_currency_ID",                   // ID of the currency associated with this pack
        new PurchaseWithMarket
        (               // Purchase type (with real money $)
            "tokens_5_PROD_ID",                   // Product ID
            0.99                                   // Price (in real money $)
        )
    );

    public static VirtualCurrencyPack TEN_TOKEN_PACK = new VirtualCurrencyPack
    (
        "10 Tokens",                          // Name
        "10 token currency units",            // Description
        "10_tokens_id",                       // Item ID
        10,                                  // Number of currencies in the pack
        "token_currency_ID",                   // ID of the currency associated with this pack
        new PurchaseWithMarket
        (               // Purchase type (with real money $)
            "tokens_10_PROD_ID",                   // Product ID
            1.99                                   // Price (in real money $)
        )
    );

    public static VirtualCurrencyPack FIFTY_TOKEN_PACK = new VirtualCurrencyPack
    (
        "50 Tokens",                          // Name
        "50 token currency units",            // Description
        "50_tokens_id",                       // Item ID
        50,                                  // Number of currencies in the pack
        "token_currency_ID",                   // ID of the currency associated with this pack
        new PurchaseWithMarket
        (               // Purchase type (with real money $)
            "tokens_50_PROD_ID",                   // Product ID
            4.99                                   // Price (in real money $)
        )
    );

    /** Virtual Goods **/

    public static VirtualGood BACKUP_FORCEFIELD = new SingleUseVG
    (
        "BackupForcefield",                             // Name
        "Secondary forcefield for extra protection.",      // Description
        "bff_ID",                          // Item ID
        new PurchaseWithVirtualItem
        (          // Purchase type (with virtual currency)
            "token_currency_ID",                     // ID of the item used to pay with
            1                                    // Price (amount of coins)
        )
    );

    public static VirtualGood EMP = new SingleUseVG
    (
        "Emp",                             // Name
        "Clear the surrounding space of all lasers.",      // Description
        "emp_ID",                          // Item ID
        new PurchaseWithVirtualItem
        (          // Purchase type (with virtual currency)
            "token_currency_ID",                     // ID of the item used to pay with
            5                                    // Price (amount of coins)
        )
    );

    public static VirtualGood IMMUNITY = new SingleUseVG
    (
        "Immunity",                             // Name
        "Immune to damage.",      // Description
        "immunity_ID",                          // Item ID
        new PurchaseWithVirtualItem
        (          // Purchase type (with virtual currency)
            "token_currency_ID",                     // ID of the item used to pay with
            10                                    // Price (amount of coins)
        )
    );

    public static VirtualGood MULTIPLIER = new SingleUseVG
    (
        "Multiplier",                             // Name
        "Double your score per deflected laser.",      // Description
        "multiplier_ID",                          // Item ID
        new PurchaseWithVirtualItem
        (          // Purchase type (with virtual currency)
            "token_currency_ID",                     // ID of the item used to pay with
            15                                    // Price (amount of coins)
        )
    );

}

In order to purchase Items, I call:

StoreInventory.BuyItem("the id of my item");

To use an item that has been purchased, I call:

StoreInventory.TakeItem("the id of my item");

StoreInventory is a class that is included in Soomla when it is imported into Unity.

Here is the code where buying and item consumption is done:

public class Purchase : MonoBehaviour 
{
    public Text tokens;
    public static bool bffFilled = false, 
        immFilled = false, empFilled = false,
        multFilled = false, init = false;

    void Start()
    {
        if (!init)
        {
            init = true;
            SoomlaStore.Initialize(new StoreAssets());
        }
        Token.updateTokens (tokens);
    }

    void Update()
    {
        if (StoreEvents.balanceChanged) 
        {
            StoreEvents.balanceChanged = false;
            Token.updateTokens(tokens);
        }
    }

    public void BuyItem (int item)
    {
        if (item == 1) 
        {
            StoreInventory.BuyItem (StoreAssets.FIVE_TOKEN_PACK.ItemId);
        } 
        else if (item == 2) 
        {
            StoreInventory.BuyItem (StoreAssets.TEN_TOKEN_PACK.ItemId);
        } 
        else if (item == 3) 
        {
            StoreInventory.BuyItem (StoreAssets.FIFTY_TOKEN_PACK.ItemId);
        }
        Token.updateTokens(tokens);
    }

    public void getUpgrade(int upgrade)
    {
        if (upgrade == 1) 
        {
            bool bffNotBought = PlayerPrefs.GetInt("Bff Available", 0) == 0;
            if (StoreAssets.TOKEN_CURRENCY.GetBalance() >= 1 && bffNotBought)
            {
                PlayerPrefs.SetInt("Bff Available", 1);
                PlayerPrefs.Save();
                bffFilled = true;
                StoreInventory.TakeItem(StoreAssets.TOKEN_CURRENCY.ItemId, 1);
            }
        }
        else if (upgrade == 2) 
        {
            bool empNotBought = PlayerPrefs.GetInt("Emp Available", 0) == 0;
            if (StoreAssets.TOKEN_CURRENCY.GetBalance() >= 5 && empNotBought)
            {
                PlayerPrefs.SetInt("Emp Available", 1);
                PlayerPrefs.Save();
                empFilled = true;
                StoreInventory.TakeItem(StoreAssets.TOKEN_CURRENCY.ItemId, 5);
            }
        }    
        else if (upgrade == 3) 
        {
            bool immNotBought = PlayerPrefs.GetInt("Imm Available", 0) == 0;
            if (StoreAssets.TOKEN_CURRENCY.GetBalance() >= 10 && immNotBought)
            {
                PlayerPrefs.SetInt("Imm Available", 1);
                PlayerPrefs.Save();
                immFilled = true;
                StoreInventory.TakeItem(StoreAssets.TOKEN_CURRENCY.ItemId, 10);
            }
        }
        else if (upgrade == 4) 
        {
            bool multNotBought = PlayerPrefs.GetInt("Mult Available", 0) == 0;    
            if (StoreAssets.TOKEN_CURRENCY.GetBalance() >= 15 && multNotBought)
            {
                PlayerPrefs.SetInt("Mult Available", 1);
                PlayerPrefs.Save();
                multFilled = true;
                StoreInventory.TakeItem(StoreAssets.TOKEN_CURRENCY.ItemId, 15);
            }
        }
        Token.updateTokens (tokens);
    }
}

8/26/15

I have now created both a google group and a google community for testing this app. I added the email for my other android device to the both of these and I used the link provided to download the app. Doing all of this still resulted in the same error as before.

8/27/15

I just noticed that my credit card on my merchant account had expired. One of the articles I read mentioned having issues like this if there were issues with the merchant account. I have updated the information and now I have to wait the deposit they will put in my account to make sure it is working. Once that is done I will update whether or not this fixed my current problem.

8/31/15

After finally verifying my merchant account on Google Play, I still seem to have the same problem. Fixing my merchant account did not change anything that I couldn't tell.

I just updated my post to include my whole StoreAssets.cs script and what I use to make purchases and consume items when a player uses them. I added this since I have no idea what else the issue could be.

9/7/15

Still no luck so far. Issue persists in android. The editor itself makes test purchases but purchases cannot be make from an android device without getting the same error as listed above.

9/9/15

Just as a quick update, I have tried building the project without the development build selected in the build settings and I send the link to all of the people in my Google community in order to give it a shot. Everyone still has the same error as my testing device does.

9/11/15

After trying a few things that Tony pointed out, I have noticed that the onBillingSupported() function is not called when I use this: StoreEvents.OnBillingSupported += onBillingSupported; I'm not sure why just yet.

9/12/15

After going through the tutorial on the soomla site, I have done everything it said except starting the Iab in the background and the fraud protection since they aren't required. the onBillingSupported method is still not called and I am still getting the same error as before on android devices.

9/12/15

I just removed everything for the Soomla plugin and imported the newest version and followed the instructions again and I still get the same error.

9/16/15

Really no idea what I am missing here. After removing all of the Soomla plugin and then adding it again and still getting the same error after multiple tries. I have followed everything as the tutorial says and I have all of the code above.

sabo
  • 911
  • 13
  • 37
  • I am not seeing the code you are actually using to authenticate with google or initializing the store. Check this thread maybe it will help but need more code to assist more. http://stackoverflow.com/questions/28079738/google-authentication-error-while-trying-to-purchase-with-soomla-iap – Tony Sep 09 '15 at 20:10
  • @Tony I updated with more code. Thanks. – sabo Sep 09 '15 at 21:48
  • @Tony I also noticed that the post you showed me initializes the StoreAssets in the class. I removed that as I saw that it was already being initialized in the SoomlaUtils.cs. It shows up in the inspector as being initialized and the purchases and consumptions are showing up in the inspector. – sabo Sep 09 '15 at 21:53
  • @Tony Please let me know if that is incorrect and I should still be initializing it on my own. It is confusing that it initializes on its own in the inspector and everything I see requires the initialization. – sabo Sep 10 '15 at 15:13

4 Answers4

5

I have never had the problem you describe. I created a private Google+ community though, and added the community as testers. Shifted my App to Beta. And invited people to my private community where there was a link to download the app and test it. It was easy.

The second point, is your code above. You are fetching 4 goods and 3 currency packs but the code does not reflect that. Maybe you you only pasted half the class.

Finally, see if this thread will help: http://answers.soom.la/t/solved-some-clarification-about-iab-testing/2067/8

By the way, SOOMLA have a dedicated site answers.soom.la for SOOMLA related issues.

Andrei Bazanov
  • 352
  • 2
  • 11
  • Yeah it is just part of the code just to get the idea. I will check out the link you sent. Thanks – sabo Aug 25 '15 at 16:47
  • Did you have to do anything special to setup the community? Or just create a community and invite your test email? I just need to know if there is a way I am supposed to link the app somehow. – sabo Aug 26 '15 at 01:58
  • No, I created the private community, and then added it in the Developer Dashboard on the APK page -> Beta Tab. There should be "Add Google Groups or Google+ Communities" there. – Andrei Bazanov Aug 26 '15 at 06:58
  • I setup a group and a community for it and just added them. I'll see later if this works over just using the emails. I'll update once finished. – sabo Aug 26 '15 at 15:17
  • Still no luck. I set up both a group and a community and after using the link to download the app on my other device, it still gives me the same error message. – sabo Aug 27 '15 at 00:41
  • Sorry, I have just corrected the link. It was pointing in the wrong direction. Can you follow it again, and make sure your app is actually published "not in draft" and that you have downloaded it from the store. Make sure the Google API Key is correctly set up in your game. – Andrei Bazanov Aug 27 '15 at 07:13
  • I have done all of that but the article you showed me has given me an idea. See the edit for 8/27 for details. I will update soon. – sabo Aug 28 '15 at 00:41
  • as you will see from the update I haven't had any changes since I verified my merchant account. Any other ideas what this could be? – sabo Aug 31 '15 at 13:17
1

Did you try buying goods from another device? I have had this issue before, but do not recall how I fixed it. From what I remember when it failed for me, it was working on the different co-worker's device. Try testing it on a different device. also, do you have multiple google accounts on your device? I remember that one of the things that I tried was removing all google account from my device and just left my main account registered. Unfortunately, I don't remember if that worked, but I hope it will help you. if you find out how to fix it please post an update here. good luck

Chaos Monkey
  • 964
  • 1
  • 6
  • 18
  • I have tried on a separate device that I have and I have had 2 other people in my google community also try it and they all get the same error. – sabo Sep 09 '15 at 13:05
  • Please let me know if you remember anything else you attempted to fix this issue. I'd be glad to give the bounty for it. Thanks. – sabo Sep 09 '15 at 16:30
1

In my case, I didn't realize that what I was using for my item ID and my product ID were mixed up. The item ID is just to identify the item within soomla, the product ID is the actual I'd you,set in google play.

sabo
  • 911
  • 13
  • 37
0

From the brief discussion in the comments it sounds like you may not have everything implemented.

Check out this link: http://know.soom.la/unity/store/store_gettingstarted/

In the Getting Started section it states..

  1. Create your own implementation of IStoreAssets in order to describe your game's specific assets.

  2. Initialize SoomlaStore with the class you just created:

SoomlaStore.Initialize(new YourStoreAssetsImplementation());

Initialize SoomlaStore in the Start function of MonoBehaviour and NOT in the Awake function. SOOMLA has its own MonoBehaviour and it needs to be "Awakened" before you initialize.

Initialize SoomlaStore ONLY ONCE when your application loads.

The initialization is confirmed on this page as well. http://know.soom.la/unity/store/store_istoreassets/

This says it is not mandatory but looks helpful

If you have your own storefront implemented inside your game, it's recommended that you open the IAB Service in the background when the store opens and close it when the store is closed.

// Start Iab Service SoomlaStore.StartIabServiceInBg();

// Stop Iab Service SoomlaStore.StopIabServiceInBg();

This is not mandatory, your game will work without this, but we do recommend it because it enhances performance. The idea here is to preemptively start the in-app billing setup process with Google's (or Amazon's) servers.

You could try adding logging to the initialize event to make sure it is initializing. Here is a list of events you can try logging from..

http://know.soom.la/unity/store/store_events/

NOTE: One thing you need to notice is that if you want to listen to OnSoomlaStoreInitialized event you have to set up the listener before you initialize SoomlaStore. So you'll need to do:

StoreEvents.OnSoomlaStoreInitialized += onSoomlaStoreInitialized;

before

Soomla.SoomlaStore.Initialize(new Soomla.Example.MuffinRushAssets());

You can also setup the OnBillingSetup event with some logging to make sure it is initializing your billing correctly.

StoreEvents.OnBillingSupported += onBillingSupported;

public void onBillingSupported() { // ... your game specific implementation here ... }

Tony
  • 3,269
  • 1
  • 27
  • 48
  • Okay, so I now initialize my StoreAssets class and I have changed it above to reflect that. As it seems that none of the other things are mandatory, I am testing this to make sure it works as a start. But as before, it seems to work and make purchases in the inspector, but gives me the same error once I try on my test device. – sabo Sep 11 '15 at 16:11
  • Did you try adding logging to onbillingsupported event to make sure that is hitting successfully? I would also make sure you have the right google dev api key configured. – Tony Sep 11 '15 at 16:39
  • I just tested it and I do not get the debug statement in the console that I put in the method so it is not working correctly. I'm not sure what could be wrong though. It does however work with the onSoomlaStoreInitialized method. – sabo Sep 11 '15 at 17:05
  • There is also an unsupported billing event, try logging there. Granted if you're using Google it should be supported but I am curious to see if it's saying it is not. – Tony Sep 11 '15 at 17:09
  • I don't get anything from the Not supported method either. – sabo Sep 11 '15 at 17:12
  • I am not really sure what it is. onMarketPurchased() is called. – sabo Sep 11 '15 at 19:49
  • What about the oninitialize event? Does it called? Does it called more than once? – Tony Sep 11 '15 at 19:56
  • I mentioned this in a previous comment but you must not have seen but yes it does call the onSoomlaStoreInitialized() method. – sabo Sep 11 '15 at 20:02
  • And it is only called one time. – sabo Sep 11 '15 at 20:09
  • I'm having a hard tI me figuring out why onBillingSupported isn't being called when onPurchasemade is being called. – sabo Sep 11 '15 at 23:03
  • By onPurchaseMade() I mean onMarketPurchase() – sabo Sep 12 '15 at 02:26
  • If you have any other ideas please let me know. I have been researching this all day and I have not made any progress. I appreciate it. – sabo Sep 12 '15 at 03:44
  • I have gone through that tutorial on the soomla site like 5 times and I have everything except the starting in the background and the fraud protection. They aren't required so this should still work but it does not. – sabo Sep 12 '15 at 17:49