Hello, I am trying to add IAPs to my steam game. I have successfully launched my game from steam and all that however I have been struggling miserably with IAPs.
I build:
Windows x86_64 with IL2CPP
Unity Version: 2019.3.0f6
Here is my code:
public Callback<MicroTxnAuthorizationResponse_t> m_MicroTxnAuthorizationResponse;
private async void BuyProductID(string productId)
{
if (steam.steamEnabled)
{
//gets steam info like country code, player id etc
m_MicroTxnAuthorizationResponse = Callback<MicroTxnAuthorizationResponse_t>.Create(OnMicroTxnAuthorizationResponse);
if (CanPurchase) BuyProductID(productId);
}
}
private static bool CanPurchase;
[AOT.MonoPInvokeCallback(typeof(MicroTxnAuthorizationResponse_t))]
private static async void OnMicroTxnAuthorizationResponse(MicroTxnAuthorizationResponse_t pCallback)
{
CanPurchase = pCallback.m_bAuthorized == 1;
if (pCallback.m_bAuthorized != 1) return;
Log("Authorized Payment");
const string url = "https://partner.steam-api.com/ISteamMicroTxn/FinalizeTxn/v2/?key=<key>&input_json";
var values = new FinalizeTxn(10000, <id>);
var json = new StringContent(JsonUtility.ToJson(values));
await client.PostAsync(url, json);
}
And this is one of the errors I get in the âPlayer.txtâ file when calling âBuyProductID()â
Uploading Crash Report
NotSupportedException: IL2CPP does not support marshaling delegates that point to instance methods to native code. The method we're attempting to marshal is: Steamworks.Callback`1[[Steamworks.MicroTxnAuthorizationResponse_t, Assembly-CSharp-firstpass, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]::OnRunCallResult
at Steamworks.Callback`1[T].BuildCCallbackBase () [0x00000] in <00000000000000000000000000000000>:0
at Steamworks.Callback`1[T]..ctor (Steamworks.Callback`1+DispatchDelegate[T] func, System.Boolean bGameServer) [0x00000] in <00000000000000000000000000000000>:0
at Steamworks.Callback`1[T].Create (Steamworks.Callback`1+DispatchDelegate[T] func) [0x00000] in <00000000000000000000000000000000>:0
at GoogleMobileAds.Api.RewardedAd.remove_OnUserEarnedReward (System.EventHandler`1[TEventArgs] value) [0x00000] in <00000000000000000000000000000000>:0
at Discord.ActivityManager+ActivityJoinHandler.Invoke (System.String secret) [0x00000] in <00000000000000000000000000000000>:0
at System.Threading.ExecutionContext.RunInternal (System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, System.Object state, System.Boolean preserveSyncCtx) [0x00000] in <00000000000000000000000000000000>:0
at System.Runtime.CompilerServices.AsyncMethodBuilderCore+MoveNextRunner.Run () [0x00000] in <00000000000000000000000000000000>:0
at System.Action.Invoke () [0x00000] in <00000000000000000000000000000000>:0
at Discord.ActivityManager+ActivityJoinHandler.Invoke (System.String secret) [0x00000] in <00000000000000000000000000000000>:0
at UnityEngine.WaitForSeconds..ctor (System.Single seconds) [0x00000] in <00000000000000000000000000000000>:0
at UnityEngine.UnitySynchronizationContext.Exec () [0x00000] in <00000000000000000000000000000000>:0
--- End of stack trace from previous location where exception was thrown ---
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x00000] in <00000000000000000000000000000000>:0
at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state) [0x00000] in <00000000000000000000000000000000>:0
at Discord.ActivityManager+ActivityJoinHandler.Invoke (System.String secret) [0x00000] in <00000000000000000000000000000000>:0
at UnityEngine.WaitForSeconds..ctor (System.Single seconds) [0x00000] in <00000000000000000000000000000000>:0
at UnityEngine.UnitySynchronizationContext.Exec () [0x00000] in <00000000000000000000000000000000>:0
UnityEngine.Logger:LogException(Exception, Object)
UnityEngine.Debug:LogException(Exception)
UnityEngine.WaitForSeconds:.ctor(Single)
UnityEngine.UnitySynchronizationContext:Exec()
I also have been getting this when I launch the game:
Uploading Crash Report
NotSupportedException: To marshal a managed method, please add an attribute named 'MonoPInvokeCallback' to the method definition. The method we're attempting to marshal is: SteamManager::SteamAPIDebugTextHook
at Steamworks.SteamClient.SetWarningMessageHook (Steamworks.SteamAPIWarningMessageHook_t pFunction) [0x00000] in <00000000000000000000000000000000>:0
at SteamManager.OnEnable () [0x00000] in <00000000000000000000000000000000>:0
It appears that it started showing up after I added [AOT.MonoPInvokeCallback(typeof(MicroTxnAuthorizationResponse_t))], maybe not, I am unsure and was a little unaware till I noticed it.
Marshaling of async functions like this does not work. The error message here is a bit misleading, as it does not mention async, but instead thinks this is an instance method (which is incorrect, it is clearly static).
Can you re-write OnMicroTxnAuthorizationResponse so that it is not async?
Do you have source code for âSteamworks.Callback`1[T].BuildCCallbackBase ()â? Looks like itâs trying to marshal a non-static function to native code there.
Ok I made them static and these are the errors I get:
(also, I moved m_MicroTxnAuthorizationResponse = Callback<MicroTxnAuthorizationResponse_t>.Create(OnMicroTxnAuthorizationResponse); to the start where it initialized steamworks.
Full Errors
Uploading Crash Report
NotSupportedException: To marshal a managed method, please add an attribute named 'MonoPInvokeCallback' to the method definition. The method we're attempting to marshal is: SteamManager::SteamAPIDebugTextHook
at Steamworks.SteamClient.SetWarningMessageHook (Steamworks.SteamAPIWarningMessageHook_t pFunction) [0x00000] in <00000000000000000000000000000000>:0
at SteamManager.OnEnable () [0x00000] in <00000000000000000000000000000000>:0
(Filename: currently not available on il2cpp Line: -1)
UnityIAP Version: 1.23.3
0x00007FFA0DADAD7C (UnityPlayer)
0x00007FFA0DADD823 (UnityPlayer)
0x00007FFA0DAD2D4D (UnityPlayer)
0x00007FFA0E373E3E (UnityPlayer) UnityMain
0x00007FFA0DEE0CC7 (UnityPlayer) UnityMain
0x00007FFA0CBD0992 (GameAssembly) [UnityEngine.CoreModule.cpp:26249] Logger_Log_mB522987DEE1BF780EAEC6864D34D7E285F5E8AB2
0x00007FFA0C954A1E (GameAssembly) [Stores.cpp:34336] StandardPurchasingModule_Instance_mBFD020AAC15056A1B2FC83F818751676576D4A98
0x00007FFA0CE916BA (GameAssembly) [Assembly-CSharp5.cpp:40202] IAPManager_InitializePurchasing_m2E0B90FC1911C935C1FB216EC8EB77014FC42B25
0x00007FFA0CE93724 (GameAssembly) [Assembly-CSharp5.cpp:39185] IAPManager_Start_m468873CB081DE60E03D10A263F9812973E9E04AC
0x00007FFA0C6FAB7C (GameAssembly) [Il2CppInvokerTable.cpp:25721] RuntimeInvoker_TrueVoid_t22962CB4C05B1D89B55A6E1139F0E87A90987017
0x00007FFA0C6A4510 (GameAssembly) [Runtime.cpp:506] il2cpp::vm::Runtime::Invoke
0x00007FFA0DE60520 (UnityPlayer) UnityMain
0x00007FFA0DE71673 (UnityPlayer) UnityMain
0x00007FFA0DE7B818 (UnityPlayer) UnityMain
0x00007FFA0DE7B8AE (UnityPlayer) UnityMain
0x00007FFA0DE7A909 (UnityPlayer) UnityMain
0x00007FFA0DC02FCD (UnityPlayer) UnityMain
0x00007FFA0DD47827 (UnityPlayer) UnityMain
0x00007FFA0DD478C3 (UnityPlayer) UnityMain
0x00007FFA0DD49CCB (UnityPlayer) UnityMain
0x00007FFA0DB06DAE (UnityPlayer)
0x00007FFA0DB05B0A (UnityPlayer)
0x00007FFA0DB09AF8 (UnityPlayer)
0x00007FFA0DB0D5AB (UnityPlayer) UnityMain
0x00007FF7CC7D11F2 (CryptoClickers)
0x00007FFAB20C7BD4 (KERNEL32) BaseThreadInitThunk
0x00007FFAB33CCE51 (ntdll) RtlUserThreadStart
(Filename: C:\buildslave\unity\build\Runtime/Export/Debug/Debug.bindings.h Line: 35)
Uploading Crash Report
NotSupportedException: To marshal a managed method, please add an attribute named 'MonoPInvokeCallback' to the method definition. The method we're attempting to marshal is: Steamworks.Callback`1[[Steamworks.MicroTxnAuthorizationResponse_t, Assembly-CSharp-firstpass, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]::OnRunCallResult
at Steamworks.Callback`1[T].BuildCCallbackBase () [0x00000] in <00000000000000000000000000000000>:0
at Steamworks.Callback`1[T]..ctor (Steamworks.Callback`1+DispatchDelegate[T] func, System.Boolean bGameServer) [0x00000] in <00000000000000000000000000000000>:0
at Steamworks.Callback`1[T].Create (Steamworks.Callback`1+DispatchDelegate[T] func) [0x00000] in <00000000000000000000000000000000>:0
at IAPManager.Start () [0x00000] in <00000000000000000000000000000000>:0
(Filename: currently not available on il2cpp Line: -1)
Uploading Crash Report
InvalidOperationException: Handle is not pinned.
at System.Runtime.CompilerServices.FixedBufferAttribute..ctor (System.Type elementType, System.Int32 length) [0x00000] in <00000000000000000000000000000000>:0
at Steamworks.Callback`1[T].Unregister () [0x00000] in <00000000000000000000000000000000>:0
at Steamworks.Callback`1[T].Dispose () [0x00000] in <00000000000000000000000000000000>:0
at Steamworks.Callback`1[T].Finalize () [0x00000] in <00000000000000000000000000000000>:0
UnityEngine.Logger:LogException(Exception, Object)
UnityEngine.Debug:LogException(Exception)
System.Reflection.AddEventAdapter:Invoke(Object, Delegate)
(Filename: currently not available on il2cpp Line: -1)```
Right, so how you added [MonoPInvokeCallback] attribute on OnMicroTxnAuthorizationResponse on your first post, you need to do the same for these three methods.
Well doing that now causes: https://hatebin.com/psreopmqol on build. Maybe its unrelated? I am not sure.
In all honesty, I am not really sure why this is a struggle to implement. There is absolutely 0 forums online where people are in the same position as me.
Ok so I have done some more research and my system is still messed up. So I fixed it and now I am getting the Steam Purchase confirmation. However, my callback is still generating errors:
Uploading Crash Report
NotSupportedException: To marshal a managed method, please add an attribute named 'MonoPInvokeCallback' to the method definition. The method we're attempting to marshal is: Steamworks.Callback`1[[Steamworks.SteamInventoryResultReady_t, Assembly-CSharp-firstpass, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]::OnRunCallResult
at Steamworks.Callback`1[T].BuildCCallbackBase () [0x00000] in <00000000000000000000000000000000>:0
at Steamworks.Callback`1[T]..ctor (Steamworks.Callback`1+DispatchDelegate[T] func, System.Boolean bGameServer) [0x00000] in <00000000000000000000000000000000>:0
at Steamworks.Callback`1[T].Create (Steamworks.Callback`1+DispatchDelegate[T] func) [0x00000] in <00000000000000000000000000000000>:0
at IAPManager.Start () [0x00000] in <00000000000000000000000000000000>:0
Is that this method? âSteamworks.Callback`1[[Steamworks.SteamInventoryResultReady_t, Assembly-CSharp-firstpass, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null]]::OnRunCallResultâ.
Itâs bizarre itâs giving you âTo marshal a managed method, please add an attribute named âMonoPInvokeCallbackâ to the method definition.â error if itâs the right method.
OIt is referring to Steamworks.Callback<SteamInventoryResultReady_t>.OnRunCallResult. If thatâs the only OnRunCallResult method, it has that attribute and youâre still getting that error it might be a bug in Unity. Could you report a bug on ti?