【问题标题】:Unity IAP (2.2.7 & 3.0.1) consumable item, transaction completion issueUnity IAP (2.2.7 & 3.0.1) 消耗品,交易完成问题
【发布时间】:2021-07-10 14:52:54
【问题描述】:

我有 12 件处于“准备提交”状态的消耗品,我试图通过使用一次又一次地购买其中一件 沙盒测试员帐户。在初始化过程中,我可以成功收到产品。我可以通过提供名称来启动购买流程 的产品。在“ProcessPurchase”回调中,我可以读取所有必需的数据,如 transactionId、payload 等并完成流程 通过返回 PurchaseProcessingResult.Complete。我希望 UnityIAP 能够完成交易并让当前商品再次可供购买。

问题是,当我再次尝试购买上一个项目时,它显示“此应用内购买已被购买”弹出窗口。这是日志文件:

PurchaseController - ,Purchasing product asychronously: 'mini_coin_pack'
PurchaseController:BuyProductID(String)
UnityEngine.Events.UnityAction:Invoke()
UnityEngine.Events.UnityEvent:Invoke()
UnityEngine.EventSystems.EventFunction`1:Invoke(T1, BaseEventData)
UnityEngine.EventSystems.ExecuteEvents:Execute(GameObject, BaseEventData, EventFunction`1)
UnityEngine.EventSystems.StandaloneInputModule:ProcessTouchPress(PointerEventData, Boolean, Boolean)
UnityEngine.EventSystems.StandaloneInputModule:ProcessTouchEvents()
UnityEngine.EventSystems.StandaloneInputModule:Process()
 
(Filename: ./Runtime/Export/Debug/Debug.bindings.h Line: 39)

2021-04-15 15:34:14.006798+0300 mygame[1689:850412] UnityIAP: PurchaseProduct: mini_coin_pack
purchase(mini_coin_pack)
UnityEngine.Events.UnityAction:Invoke()
UnityEngine.Events.UnityEvent:Invoke()
UnityEngine.EventSystems.EventFunction`1:Invoke(T1, BaseEventData)
UnityEngine.EventSystems.ExecuteEvents:Execute(GameObject, BaseEventData, EventFunction`1)
UnityEngine.EventSystems.StandaloneInputModule:ProcessTouchPress(PointerEventData, Boolean, Boolean)
UnityEngine.EventSystems.StandaloneInputModule:ProcessTouchEvents()
UnityEngine.EventSystems.StandaloneInputModule:Process()
 
(Filename: ./Runtime/Export/Debug/Debug.bindings.h Line: 39)

2021-04-15 15:34:14.048335+0300 mygame[1689:850412] UnityIAP: UpdatedTransactions
-> applicationWillResignActive()
-> applicationDidBecomeActive()
2021-04-15 15:34:22.947604+0300 mygame[1689:850412] UnityIAP: UpdatedTransactions
2021-04-15 15:34:22.948039+0300 mygame[1689:850412] UnityIAP: DuplicateTransaction error with product mini_coin_pack and transactionId 1000000801477725
-> applicationWillResignActive()
onPurchaseFailedEvent(productId:mini_coin_pack message:Duplicate transaction occurred)
UnityEngine.Purchasing.PurchasingManager:OnPurchaseFailed(PurchaseFailureDescription)
System.Action:Invoke()
UnityEngine.Purchasing.Extension.UnityUtil:Update()
 
(Filename: ./Runtime/Export/Debug/Debug.bindings.h Line: 39)

PurchaseController - ,OnPurchaseFailed, Product : mini_coin_pack, Reason : DuplicateTransaction
PurchaseController:OnPurchaseFailed(Product, PurchaseFailureReason)
System.Action:Invoke()
UnityEngine.Purchasing.Extension.UnityUtil:Update()
 
(Filename: ./Runtime/Export/Debug/Debug.bindings.h Line: 39)

PurchaseController - ,Store specific error code: Unknown
PurchaseController:OnPurchaseFailed(Product, PurchaseFailureReason)
System.Action:Invoke()
UnityEngine.Purchasing.Extension.UnityUtil:Update()
 
(Filename: ./Runtime/Export/Debug/Debug.bindings.h Line: 39)

PurchaseController - ,Purchase failure description message: Duplicate transaction occurred
PurchaseController:OnPurchaseFailed(Product, PurchaseFailureReason)
System.Action:Invoke()
UnityEngine.Purchasing.Extension.UnityUtil:Update()
 
(Filename: ./Runtime/Export/Debug/Debug.bindings.h Line: 39)

-> applicationDidBecomeActive()

当我终止并重新启动应用程序时,以下日志显示上次尝试仍有事务要完成。

2021-04-15 15:35:03.181235+0300 mygame[1699:852283] UnityIAP UnityEarlyTransactionObserver: Created
2021-04-15 15:35:03.182006+0300 mygame[1699:852283] UnityIAP UnityEarlyTransactionObserver: Registered for lifecycle events
CrashReporter: initialized
2021-04-15 15:35:03.215730+0300 mygame[1699:852283] Built from '2019.4/staging' branch, Version '2019.4.23f1 (3f4e01f1a5ec)', Build type 'Release', Scripting Backend 'il2cpp'
2021-04-15 15:35:03.228051+0300 mygame[1699:852283] MemoryManager: Using 'Default' Allocator.
-> applicationDidFinishLaunching()
2021-04-15 15:35:03.528270+0300 mygame[1699:852283] UnityIAP UnityEarlyTransactionObserver: Added to the payment queue
-> applicationDidBecomeActive()
GfxDevice: creating device client; threaded=1
Initializing Metal device caps: Apple A8 GPU
Initialize engine version: 2019.4.23f1 (3f4e01f1a5ec)
CrashReporter: No pending report exists at /var/mobile/Containers/Data/Application/01EA9697-0BD5-40AF-BB20-967567B5EAE2/Library/Caches/CrashReports/crash-pending.plcrash
UnloadTime: 1.242625 ms
UnityIAP Version: 3.0.1
UnityEngine.Purchasing.StandardPurchasingModule:Instance(AppStore)
PurchaseController:InitializePurchasing()
 
(Filename: ./Runtime/Export/Debug/Debug.bindings.h Line: 39)

2021-04-15 15:35:06.133617+0300 mygame[1699:852283] UnityIAP: Requesting 1 products
2021-04-15 15:35:06.201046+0300 mygame[1699:852283] UnityIAP: Requesting product data...
2021-04-15 15:35:07.031669+0300 mygame[1699:852283] UnityIAP: Received 1 products
PurchaseController - ,OnInitialized
PurchaseController:OnInitialized(IStoreController, IExtensionProvider)
UnityEngine.Purchasing.PurchasingManager:CheckForInitialization()
UnityEngine.Purchasing.PurchasingManager:OnProductsRetrieved(List`1)
UnityEngine.Purchasing.AppleStoreImpl:OnProductsRetrieved(String)
System.Action:Invoke()
UnityEngine.Purchasing.Extension.UnityUtil:Update()
 
(Filename: ./Runtime/Export/Debug/Debug.bindings.h Line: 39)

PurchaseController - ,Mini Coin Pack, is ready to purchase!
PurchaseController:OnInitialized(IStoreController, IExtensionProvider)
UnityEngine.Purchasing.PurchasingManager:CheckForInitialization()
UnityEngine.Purchasing.PurchasingManager:OnProductsRetrieved(List`1)
UnityEngine.Purchasing.AppleStoreImpl:OnProductsRetrieved(String)
System.Action:Invoke()
UnityEngine.Purchasing.Extension.UnityUtil:Update()
 
(Filename: ./Runtime/Export/Debug/Debug.bindings.h Line: 39)

UnityIAP: Initialization complete with  1 items
UnityEngine.Purchasing.Promo:ProvideProductsToAds(HashSet`1, Boolean)
UnityEngine.Purchasing.AppleStoreImpl:OnProductsRetrieved(String)
System.Action:Invoke()
UnityEngine.Purchasing.Extension.UnityUtil:Update()
 
(Filename: ./Runtime/Export/Debug/Debug.bindings.h Line: 39)

2021-04-15 15:35:07.079768+0300 mygame[1699:852283] UnityIAP: Add transaction observer
2021-04-15 15:35:07.080293+0300 mygame[1699:852283] UnityIAP: UpdatedTransactions
2021-04-15 15:35:07.084949+0300 mygame[1699:852283] UnityIAP UnityEarlyTransactionObserver: Request to initiate queued payments
Already recorded transaction 1000000801477725
UnityEngine.Purchasing.PurchasingManager:ProcessPurchaseIfNew(Product)
UnityEngine.Purchasing.JSONStore:OnPurchaseSucceeded(String, String, String)
System.Action:Invoke()
UnityEngine.Purchasing.Extension.UnityUtil:Update()
 
(Filename: ./Runtime/Export/Debug/Debug.bindings.h Line: 39)

2021-04-15 15:35:07.095638+0300 mygame[1699:852283] UnityIAP: Finishing transaction 1000000801477725

上述日志的最后一行,显示应用启动过程中调用了 ProcessPurchase 回调方法,并尝试再次完成交易。

这是我在测试期间使用的沙盒代码:

using UnityEngine;
using UnityEngine.Purchasing;
using UnityEngine.UI;

public class PurchaseController : MonoBehaviour, IStoreListener
{
    private IStoreController _storeController;
    private IExtensionProvider _extensionProvider;

    [SerializeField] private Button _purchaseButton;
    
    private string _miniCoinPack = "mini_coin_pack";

    private void Awake()
    {
        _purchaseButton.onClick.AddListener(BuyConsumable);
        DontDestroyOnLoad(gameObject);
    }

    private void Start()
    {
        if (_storeController == null)
        {
            InitializePurchasing();
        }
    }
    
    private void InitializePurchasing()
    {
        if (IsInitialized()) return;
        var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());
        builder.AddProduct(_miniCoinPack, ProductType.Consumable);
        UnityPurchasing.Initialize(this, builder);
    }
    
    public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
    {
        _storeController = controller;
        _extensionProvider = extensions;
        
        foreach (var product in _storeController.products.set)
        {
            if (product.hasReceipt)
            {
                _storeController.ConfirmPendingPurchase(product);
            }
            if (product.availableToPurchase)
            {
                Log(product.metadata.localizedTitle + ", is ready to purchase!");
            }
        }
    }
    
    public void OnInitializeFailed(InitializationFailureReason error)
    {
        Log("OnInitializeFailed: " + error);
    }
    
    private bool IsInitialized()
    {
        return _storeController != null && _extensionProvider != null;
    }
    
    public void BuyConsumable()
    {
        BuyProductID(_miniCoinPack);
    }
    
    private void BuyProductID(string productId)
    {
        if (IsInitialized())
        {
            Product product = _storeController.products.WithID(productId);
            if (product != null && product.availableToPurchase)
            {
                Log(string.Format("Purchasing product asychronously: '{0}'", product.definition.id));
                _storeController.InitiatePurchase(product, "{\"userID\":\"313131696969\"}");
            }
            else
            {
                Log("BuyProductID: FAIL. Not purchasing product, either is not found or is not available for purchase");
            }
        }
        else
        {
            Log("BuyProductID FAIL. Not initialized.");
        }
    }

    public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)
    {
        Log("purchase success for : " + args.purchasedProduct.definition.id);
        return PurchaseProcessingResult.Complete;
    }

    public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason)
    {
        Log(string.Format("OnPurchaseFailed, Product : {0}, Reason : {1}", product.definition.storeSpecificId, failureReason));
        var transactionHistoryExtensions = _extensionProvider.GetExtension<ITransactionHistoryExtensions>();
        Log("Store specific error code: " + transactionHistoryExtensions.GetLastStoreSpecificPurchaseErrorCode());
        if (transactionHistoryExtensions.GetLastPurchaseFailureDescription() != null)
        {
            Log("Purchase failure description message: " + transactionHistoryExtensions.GetLastPurchaseFailureDescription().message);
        }
    }

    private void Log(string message)
    {
        Debug.Log(string.Concat("PurchaseController - ,", message));
    }
}

我尝试了不同的方法将 UnityIAP 集成到我的沙盒 Unity 项目中,例如:

  • 仅使用统一包管理器并安装(分别为 2.2.7 和 3.0.2)
  • 激活应用内购买和分析服务并从那里安装 UnityIAP 包。

Unity 版本:2019.4.22f1、2019.4.23f1

Unity IAP 版本:2.2.7、3.0.2

测试设备:iPhone 6、iOS 12.5.1

测试用户:沙盒测试员(国家:美国,中断购买:禁用,Apple Pay:是)

App Store Connect 应用状态:准备提交(尚未提交!)

应用内购买项目:(类型:消耗品,状态:准备提交)

UnityIAP-2.2.2 版本似乎解决了这个问题,如下所述:https://forum.unity.com/threads/unity-iap-package-3-0-2-is-now-available.415517/page-2 但它仍然存在于 2.2.7 和 3.0.2 版本中。

是否还有其他人在实施 UnityIAP 时面临相同或相似的行为?

【问题讨论】:

标签: ios unity3d in-app-purchase


【解决方案1】:

我确实在 4 场比赛中确认这是苹果服务器端的东西。 它不仅适用于 Unity IAP,也适用于所有人。 有很多这样的问题https://developer.apple.com/forums/search/?q=sandbox&page=1&sortBy=newest

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-13
    • 1970-01-01
    • 2011-08-12
    • 1970-01-01
    • 2017-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多