实施Soomla Unity3d插件时进行购买时出现Google Play错误

23
我正在创建一个应用程序,实现Soomla Unity IAP插件。在尝试使IAP正常工作时,我已经达到了可以在编辑器中进行购买的程度。(不是真正的购买,它只更新用户可以在游戏中购买/消费的虚拟货币)。
当我在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 时包含的一个类。

下面是购买和物品消耗的代码实现:

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

我现在已经为测试这个应用程序创建了一个谷歌组和谷歌社区。我将我的另一个Android设备的电子邮件地址添加到了这两个地方,并使用提供的链接下载了应用程序。然而,尽管我做了所有这些事情,仍然出现了与以前相同的错误。

8/27/15

我刚刚注意到我在商户账户上的信用卡已经过期了。我阅读的一篇文章提到,如果商户账户有问题,就可能出现这样的问题。我已经更新了信息,现在必须等待他们放入我的账户的存款,以确保它正常工作。一旦这样做完了,我会更新是否解决了我的当前问题。

8/31/15

在最终验证了我的Google Play商户账户之后,我似乎仍然有同样的问题。修复商户账户并没有改变任何我所能察觉到的东西。

我刚刚更新了我的帖子,包括我整个StoreAssets.cs脚本以及当玩家使用物品时我用来购买和消耗物品的内容。我增加了这个,因为我不知道问题还可能是什么。

9/7/15

到目前为止仍然没有好运。问题在Android上仍然存在。编辑器本身可以进行测试购买,但是在Android设备上使用时却出现相同的错误。

9/9/15

只是一个快速的更新,我已经尝试在构建设置中不选择开发版本并向我谷歌社区的所有人发送了链接,以便他们试一试。每个人仍然有与我的测试设备相同的错误。

9/11/15

经过尝试Tony指出的一些东西后,我注意到当我使用这个函数时 onBillingSupported() 没有被调用: StoreEvents.OnBillingSupported += onBillingSupported; 我还不确定为什么会这样。

9/12/15

在浏览soomla网站上的教程之后,我做到了除了在后台启动Iab和欺诈保护之外的一切,因为它们不是必需的。onBillingSupported方法仍然没有被调用,并且在Android设备上仍然出现相同的错误。

9/12/15

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

9/16/15

真的不知道我在这里缺少什么。在多次尝试之后,删除了所有Soomla插件,然后再次添加它们,仍然出现相同的错误。我已经按照教程所说的做了一切,并且拥有上述所有代码。


我并没有看到您实际用来认证谷歌或初始化存储的代码。可以查看此线程,或许能提供帮助,但需要更多的代码才能提供更多协助。http://stackoverflow.com/questions/28079738/google-authentication-error-while-trying-to-purchase-with-soomla-iap - Tony
@Tony,我更新了更多的代码。谢谢。 - sabo
@Tony,我还注意到你给我展示的帖子在类中初始化了StoreAssets。但是我将其删除了,因为我发现它已经在SoomlaUtils.cs中被初始化了。在检查器中显示已经初始化,并且购买和消费也在检查器中显示出来了。 - sabo
@Tony,请告诉我是否不正确,我仍然应该自己初始化它。在检查器中它自动初始化,但是我看到的所有内容都需要初始化,这很令人困惑。 - sabo
4个回答

5
我从未遇到你所描述的问题。但我创建了一个私人的Google+社区,并将该社区添加为测试人员。将我的应用程序转移到Beta,并邀请人们加入我的私人社区,其中有一个链接可供下载应用程序并进行测试。这很容易。
第二点是您上面的代码。您正在获取4个商品和3个货币包,但代码没有反映出来。也许您只粘贴了类的一半。
最后,请查看此线程是否有帮助:http://answers.soom.la/t/solved-some-clarification-about-iab-testing/2067/8 顺便说一句,SOOMLA专门为SOOMLA相关问题提供了dedicated网站answers.soom.la。

是的,这只是代码的一部分,只是为了让你有个想法。我会查看你发送的链接。谢谢。 - sabo
你需要特别设置社区吗?还是只需创建社区并邀请测试电子邮件即可?我只需要知道是否有一种方式可以将应用程序链接起来。 - sabo
我建立了一个组和一个社区,并将它们添加进去。稍后我会看看这是否比仅使用电子邮件更有效。完成后我会更新。 - sabo
我已经做了所有的那些,但是你给我看的那篇文章给了我一个思路。有关详细信息,请参见8/27的编辑。我会尽快更新。 - sabo
正如您从更新中所看到的,自从我验证了我的商家账户以来,我没有进行任何更改。还有其他什么想法吗? - sabo
显示剩余3条评论

1

你尝试过从其他设备购买商品吗?我以前遇到过这个问题,但不记得如何解决。据我记得,当我遇到问题时,它在另一位同事的设备上运行正常。尝试在另一个设备上进行测试。此外,你的设备上是否有多个谷歌账户?我记得我尝试的其中一件事是从我的设备中删除所有谷歌账户,只留下我的主要账户注册。不幸的是,我不记得是否有效,但希望能帮到你。如果你知道如何解决,请在这里发布更新。祝好运


我已经在我的另一个设备上尝试过,并且我在我的谷歌社区中还有其他两个人也尝试了,他们都得到了相同的错误。 - sabo
请告诉我,如果您记得尝试过其他任何解决此问题的方法。我很乐意为此提供悬赏。谢谢。 - sabo

1
在我的情况下,我没有意识到我用于项目ID和产品ID的内容混淆了。项目ID仅用于在soomla中识别该项目,而产品ID是您在Google Play设置的实际ID。

0

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

请查看此链接: http://know.soom.la/unity/store/store_gettingstarted/

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

  1. 创建自己的IStoreAssets实现,以描述游戏的特定资产。

  2. 使用刚刚创建的类初始化SoomlaStore:

SoomlaStore.Initialize(new YourStoreAssetsImplementation());

在MonoBehaviour的Start函数中初始化SoomlaStore,而不是在Awake函数中。SOOMLA有自己的MonoBehaviour,需要在初始化之前“唤醒”。

应用程序加载时仅初始化SoomlaStore一次。

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

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

如果您在游戏中实现了自己的商店前端,建议在打开商店时后台打开IAB服务,并在关闭商店时关闭它。

// 启动Iab服务 SoomlaStore.StartIabServiceInBg();

// 停止Iab服务 SoomlaStore.StopIabServiceInBg();

这不是必须的,您的游戏可以在没有此功能的情况下运行,但我们建议使用它,因为它可以提高性能。这里的想法是预先启动与Google(或Amazon)服务器的应用内购买设置过程。

您可以尝试向初始化事件添加日志记录以确保其正在初始化。以下是您可以尝试从中记录日志的事件列表。

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

注意:如果你想监听 OnSoomlaStoreInitialized 事件,你需要在初始化 SoomlaStore 之前设置好监听器。所以你需要做以下操作:
``` StoreEvents.OnSoomlaStoreInitialized += onSoomlaStoreInitialized; ```
在以下代码之前:
``` Soomla.SoomlaStore.Initialize(new Soomla.Example.MuffinRushAssets()); ```
你也可以设置 OnBillingSetup 事件并添加一些日志来确保它正确初始化了你的计费。
``` StoreEvents.OnBillingSupported += onBillingSupported; public void onBillingSupported() { // ... 在此处添加你的游戏特定实现 ... } ```

你尝试在onbillingsupported事件中添加日志记录以确保它成功触发了吗?我还会确保你已经配置了正确的Google Dev API密钥。 - Tony
我刚刚测试了一下,但是在控制台中没有看到我在方法中放置的调试语句,所以它没有正常工作。虽然我不确定可能出了什么问题,但是它确实可以使用onSoomlaStoreInitialized方法。 - sabo
还有一个不受支持的计费事件,请尝试登录该事件。如果您使用的是Google,那么它应该是受支持的,但我很好奇它是否会说它不受支持。 - Tony
我也从不支持的方法中得不到任何东西。 - sabo
它只被调用了一次。 - sabo
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接