Google 实施 Soomla Unity3d 插件时购买时播放错误

Google play error when making a purchase while implementing Soomla Unity3d plugin

我正在创建一个实现 Soomla Unity IAP 插件的应用程序。在我努力让 IAP 工作的过程中,我已经到了可以在编辑器中进行购买的地步。 (不是真正的购买,只是更新了用户在游戏中可以buy/spend的虚拟货币)。

当我在 Android 设备上启动它时,出现此错误:需要身份验证。您需要登录您的 Google 帐户。

现在我已经阅读了多篇不同的文章,其中人们遇到了这个问题,但似乎没有任何帮助。

以下是我迄今为止尝试过的列表:

1) 确保应用已发布到 alpha 版或 beta 版以进行测试。(现在处于 alpha 版)

2) 确保游戏和开发者控制台的价格相匹配。

3) 使用以未使用开发者电子邮件的用户身份登录的设备。

4) 确保测试设备上的电子邮件在开发者控制台中被列为测试人员。

5) 确保 Android 清单中列出了必要的权限。

6) 确认商家帐户设置正确并经过验证。

7) 确保构建为发布而不是开发(不确定这是否重要,但我尝试了两种方法)。

8) 从项目中完全删除所有 Soomla 插件,然后在非常严格地按照教程进行操作的同时将其重新添加进去,以确保没有遗漏任何细节。仍然没有骰子。

我已将核心组件和存储组件添加到场景中,它们是必需的。如果您对我应该如何解决此问题有任何其他想法,请告诉我。同时,这是我用来设置 Soomla 的 StoreAssets.cs 代码:

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)
        )
    );

}

为了购买物品,我打电话:

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

要使用已购买的物品,我致电:

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

StoreInventory 是 Soomla 导入 Unity 时包含的 class。

这是完成购买和物品消耗的代码:

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

我现在已经创建了一个 google 组和一个 google 社区来测试这个应用程序。我将我的其他 android 设备的电子邮件添加到这两个设备中,并使用提供的 link 下载应用程序。做所有这些仍然会导致与以前相同的错误。

8/27/15

我刚刚注意到我的商家帐户中的信用卡已过期。我读过的一篇文章提到,如果商家帐户存在问题,就会出现此类问题。我已经更新了信息,现在我必须等待他们存入我帐户的存款以确保它正常工作。一旦完成,我将更新这是否解决了我当前的问题。

8/31/15

最终在 Google Play 上验证了我的商家帐户后,我似乎仍然遇到同样的问题。修复我的商家帐户并没有改变任何我无法分辨的东西。

我刚刚更新了我的 post 以包含我的整个 StoreAssets.cs 脚本以及当玩家使用它们时我用来购买和消耗物品的内容。我添加了这个,因为我不知道还有什么问题。

9/7/15

到目前为止仍然没有运气。 android 中的问题仍然存在。编辑器本身进行了测试购买,但无法从 android 设备进行购买而不会出现与上面列出的相同的错误。

9/9/15

作为快速更新,我尝试在未在构建设置中选择开发构建的情况下构建项目,然后按顺序将 link 发送给 Google 社区中的所有人试一试。每个人仍然有与我的测试设备相同的错误。

9/11/15

在尝试了 Tony 指出的一些事情之后,我注意到当我使用这个时没有调用 onBillingSupported() 函数:StoreEvents.OnBillingSupported += onBillingSupported;我还不确定为什么。

9/12/15

在完成了 soomla 网站上的教程之后,除了在后台启动 Iab 和欺诈保护之外,我已经完成了它所说的一切,因为它们不是必需的。 onBillingSupported 方法仍未被调用,我在 android 设备上仍然遇到与以前相同的错误。

9/12/15

我刚刚删除了 Soomla 插件的所有内容并导入了最新版本,然后再次按照说明进行操作,但我仍然遇到相同的错误。

9/16/15

真的不知道我在这里错过了什么。在删除所有 Soomla 插件然后再次添加它并在多次尝试后仍然出现相同的错误。我已经按照教程所说的进行了所有操作,并且我拥有上面的所有代码。

我从来没有遇到过你描述的问题。不过,我创建了一个私人 Google+ 社区,并将该社区添加为测试人员。将我的应用程序转移到 Beta 版。并邀请人们到我的私人社区,那里有 link 下载应用程序并进行测试。很简单。

第二点,就是你上面的代码。您正在获取 4 种商品和 3 个货币包,但代码并未反映这一点。也许你只贴了一半class.

最后,看看这个帖子是否有帮助:http://answers.soom.la/t/solved-some-clarification-about-iab-testing/2067/8

顺便说一下,SOOMLA 有一个专门的网站 answers.soom.la 用于解决 SOOMLA 相关问题。

您是否尝试过从其他设备购买商品? 我以前遇到过这个问题,但不记得我是如何解决的。 据我所知,当它对我来说失败时,它正在不同同事的设备上工作。 尝试在不同的设备上测试它。 另外,您的设备上是否有多个 google 帐户? 我记得我尝试过的其中一件事是从我的设备中删除所有 google 帐户,只保留我的主帐户注册。不幸的是,我不记得这是否有效,但我希望它能帮助你。 如果您知道如何修复它,请 post 在此处进行更新。祝你好运

从评论中的简短讨论来看,您可能没有实现所有内容。

看看这个 link: http://know.soom.la/unity/store/store_gettingstarted/

在“入门”部分中指出..

  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.

此页面也已确认初始化。 http://know.soom.la/unity/store/store_istoreassets/

这不是强制性的,但看起来很有帮助

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.

您可以尝试将日志记录添加到初始化事件以确保它正在初始化。这是您可以尝试从中记录的事件列表..

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());

您还可以设置带有一些日志记录的 OnBillingSetup 事件,以确保它正确地初始化您的帐单。

StoreEvents.OnBillingSupported += onBillingSupported;

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

就我而言,我没有意识到我使用的商品 ID 和产品 ID 混淆了。 item ID只是用来标识soomla中的item,product ID是实际的I'd you,设置在google play。