using UnityEngine; using System; using System.Collections.Generic; using System.Runtime.InteropServices; using AOT; public enum NimbleBridge_PromotedPaymentAction { PROMOTED_PAYMENT_DELAY, PROMOTED_PAYMENT_ACKNOWLEDGED } public enum NimbleBridge_StorePromotionVisibility { DEFAULT, HIDE, SHOW } public delegate void MTXTransactionCallback(NimbleBridge_MTXTransaction transaction); public delegate void MTXRefreshReceiptCallback(NimbleBridge_Error error); public delegate NimbleBridge_PromotedPaymentAction MTXPromotedPaymentCallback(string sku); public delegate void MTXPromotedItemsCallback (List skus, NimbleBridge_Error error); public delegate void MTXCompletionCallback(NimbleBridge_Error error); public delegate void MTXStorePromotionVisibilityCallback(NimbleBridge_StorePromotionVisibility visibility, NimbleBridge_Error error); public class NimbleBridge_MTX { [UnmanagedFunctionPointer(CallingConvention.Cdecl)] private delegate void BridgeMTXTransactionCallback(IntPtr transactionPtr, IntPtr callbackDataPtr); private delegate void BridgeMTXCompletionCallback(IntPtr errorPtr, IntPtr callbackDataPtr); private delegate int BridgeMTXPromotedPaymentCallback(string sku, IntPtr callbackDataPtr); private delegate void BridgeMTXPromotedItemsCallback(IntPtr skus, IntPtr errorPtr, IntPtr callbackDataPtr); private delegate void BridgeMTXStorePromotionVisibilityCallback(int visibility, IntPtr errorPtr, IntPtr callbackDataPtr); [MonoPInvokeCallback(typeof(BridgeMTXTransactionCallback))] private static void OnMTXTransactionCallback(IntPtr transactionPtr, IntPtr callbackDataPtr) { var helper = NimbleBridge_CallbackHelper.Get(); NimbleBridge_MTXTransaction transaction; #if UNITY_EDITOR || ( ! UNITY_IPHONE && ! UNITY_ANDROID ) transaction = new NimbleBridge_MTXTransaction(Marshal.PtrToStringUni(transactionPtr)); #else transaction = new NimbleBridge_MTXTransaction(transactionPtr); #endif var callback = (MTXTransactionCallback)helper.GetData(callbackDataPtr); helper.RunOnMainThread(callbackDataPtr, () => callback(transaction)); } [MonoPInvokeCallback(typeof(BridgeMTXCompletionCallback))] private static void OnMTXRefreshReceiptCallback(IntPtr errorPtr, IntPtr callbackDataPtr) { var helper = NimbleBridge_CallbackHelper.Get(); var error = new NimbleBridge_Error(errorPtr); var callback = (MTXRefreshReceiptCallback)helper.GetData(callbackDataPtr); helper.RunOnMainThread(callbackDataPtr, () => callback(error)); } [MonoPInvokeCallback(typeof(BridgeMTXPromotedPaymentCallback))] private static int OnMTXPromotedPaymentCallback(string sku, IntPtr callbackDataPtr) { var helper = NimbleBridge_CallbackHelper.Get(); var callback = (MTXPromotedPaymentCallback)helper.GetData(callbackDataPtr); return (int)callback(sku); } [MonoPInvokeCallback(typeof(BridgeMTXPromotedItemsCallback))] private static void OnMTXPromotedItemsCallback(IntPtr skus, IntPtr errorPtr, IntPtr callbackDataPtr) { var helper = NimbleBridge_CallbackHelper.Get(); var skuList = new List(MarshalUtility.ConvertPtrToStringArray(skus, MarshalUtility.MarshalType.CallbackParam)); var error = new NimbleBridge_Error(errorPtr); var callback = (MTXPromotedItemsCallback)helper.GetData(callbackDataPtr); helper.RunOnMainThread(callbackDataPtr, () => callback(skuList, error)); } [MonoPInvokeCallback(typeof(BridgeMTXCompletionCallback))] private static void OnMTXCompletionCallback(IntPtr errorPtr, IntPtr callbackDataPtr) { var helper = NimbleBridge_CallbackHelper.Get(); var error = new NimbleBridge_Error(errorPtr); var callback = (MTXCompletionCallback)helper.GetData(callbackDataPtr); helper.RunOnMainThread(callbackDataPtr, () => callback(error)); } [MonoPInvokeCallback(typeof(BridgeMTXStorePromotionVisibilityCallback))] private static void OnMTXStorePromotionVisibilityCallback(int visibility, IntPtr errorPtr, IntPtr callbackDataPtr) { var helper = NimbleBridge_CallbackHelper.Get(); var error = new NimbleBridge_Error(errorPtr); var callback = (MTXStorePromotionVisibilityCallback)helper.GetData(callbackDataPtr); helper.RunOnMainThread(callbackDataPtr, () => callback((NimbleBridge_StorePromotionVisibility)visibility, error)); } /*! * Errors */ public const int ERROR_BILLING_UNAVAILABLE = 10001; public const int ERROR_USER_CANCELED = 10002; public const int ERROR_ITEM_ALREADY_PURCHASED = 10003; public const int ERROR_ITEM_UNAVAILABLE = 10004; public const int ERROR_PURCHASE_VERIFICATION_FAILED = 10005; /*! * NOTIFICATION_MTX_REFRESH_CATALOG_FINISHED * * Sent in response to RefreshAvailableCatalogItems() * * UserInfo keys: * NIMBLE_ERROR - Error object, if query error'd. */ public const string NOTIFICATION_REFRESH_CATALOG_FINISHED = "nimble.notification.mtx.refreshcatalogfinished"; /*! * NOTIFICATION_MTX_RESTORE_PURCHASED_TRANSACTIONS_FINISHED * * Sent in response to refreshPurchasedItems * * UserInfo keys: * NIMBLE_ERROR - Error object, if refresh error'd. */ public const string NOTIFICATION_RESTORE_PURCHASED_TRANSACTIONS_FINISHED = "nimble.notification.mtx.restorepurchasedtransactionsfinished"; /*! * NOTIFICATION_MTX_TRANSACTIONS_RECOVERED * * Sent on startup if there are pending transactions without callbacks. * * UserInfo keys: * */ public const string NOTIFICATION_TRANSACTIONS_RECOVERED = "nimble.notification.mtx.transactionsrecovered"; #if UNITY_EDITOR || ( ! UNITY_IPHONE && ! UNITY_ANDROID ) static private void MockTransactionCallback(System.Timers.Timer timer, IntPtr transactionIdPtr, IntPtr callbackData, bool disposeTransaction = true) { timer.Enabled = false; OnMTXTransactionCallback(transactionIdPtr, callbackData); if (disposeTransaction) { Marshal.FreeHGlobal(transactionIdPtr); } NimbleBridge_CallbackHelper.InvalidateCallback(callbackData); NimbleBridge_CallbackHelper.DisposeCallbackOnMainThread (callbackData); timer.Close(); } static private NimbleBridge_Error NimbleBridge_MTX_purchaseItem(string sku, BridgeMTXTransactionCallback receiptCallback, IntPtr receiptCallbackData, BridgeMTXTransactionCallback purchaseCallback, IntPtr purchaseCallbackData, string metadata) { IntPtr skuPtr = Marshal.StringToHGlobalUni(sku); System.Timers.Timer receiptTimer = new System.Timers.Timer(500); receiptTimer.Elapsed += delegate { MockTransactionCallback(receiptTimer, skuPtr, receiptCallbackData, false); }; receiptTimer.Enabled = true; receiptTimer.AutoReset = false; System.Timers.Timer purchaseTimer = new System.Timers.Timer(1000); purchaseTimer.Elapsed += delegate { MockTransactionCallback(purchaseTimer, skuPtr, purchaseCallbackData); }; purchaseTimer.Enabled = true; purchaseTimer.AutoReset = false; return new NimbleBridge_Error(IntPtr.Zero); } #else [DllImport (MarshalUtility.CINTERFACE_LIB_NAME)] static private extern NimbleBridge_Error NimbleBridge_MTX_purchaseItem(string sku, BridgeMTXTransactionCallback receiptCallback, IntPtr receiptCallbackData, BridgeMTXTransactionCallback purchaseCallback, IntPtr purchaseCallbackData, string metadata); #endif #if UNITY_EDITOR || ( ! UNITY_IPHONE && ! UNITY_ANDROID ) static private NimbleBridge_Error NimbleBridge_MTX_itemGranted(string transactionId, int itemType, BridgeMTXTransactionCallback callback, IntPtr callbackData) { IntPtr transactionIdPtr = Marshal.StringToHGlobalUni(transactionId); System.Timers.Timer timer = new System.Timers.Timer(500); timer.Elapsed += delegate { MockTransactionCallback(timer, transactionIdPtr, callbackData); }; timer.Enabled = true; timer.AutoReset = false; return new NimbleBridge_Error(IntPtr.Zero); } #else [DllImport (MarshalUtility.CINTERFACE_LIB_NAME)] static private extern NimbleBridge_Error NimbleBridge_MTX_itemGranted(string transactionId, int itemType, BridgeMTXTransactionCallback callback, IntPtr callbackData); #endif #if UNITY_EDITOR || ( ! UNITY_IPHONE && ! UNITY_ANDROID ) static private NimbleBridge_Error NimbleBridge_MTX_finalizeTransaction(string transactionId, BridgeMTXTransactionCallback callback, IntPtr callbackData) { IntPtr transactionIdPtr = Marshal.StringToHGlobalUni(transactionId); System.Timers.Timer timer = new System.Timers.Timer(500); timer.Elapsed += delegate { MockTransactionCallback(timer, transactionIdPtr, callbackData); }; timer.Enabled = true; timer.AutoReset = false; return new NimbleBridge_Error(IntPtr.Zero); } #else [DllImport (MarshalUtility.CINTERFACE_LIB_NAME)] static private extern NimbleBridge_Error NimbleBridge_MTX_finalizeTransaction(string transactionId, BridgeMTXTransactionCallback callback, IntPtr callbackData); #endif #if UNITY_EDITOR || ( ! UNITY_IPHONE && ! UNITY_ANDROID ) static private void MockRestoreFinishedNotification(System.Timers.Timer timer) { timer.Enabled = false; string userData = "{\"" + NimbleBridge_Global.DICTIONARY_KEY_RESULT_BOOLEAN + "\":\"" + NimbleBridge_Global.DICTIONARY_VALUE_RESULT_SUCCESS + "\"}"; NimbleBridge_NotificationCenter.SendNotification(NimbleBridge_MTX.NOTIFICATION_RESTORE_PURCHASED_TRANSACTIONS_FINISHED, userData); timer.Close(); } static private void NimbleBridge_MTX_restorePurchasedTransactions() { System.Timers.Timer timer = new System.Timers.Timer(1000); timer.Elapsed += delegate { MockRestoreFinishedNotification(timer); }; timer.Enabled = true; timer.AutoReset = false; } #else [DllImport (MarshalUtility.CINTERFACE_LIB_NAME)] static private extern void NimbleBridge_MTX_restorePurchasedTransactions(); #endif #if UNITY_EDITOR || ( ! UNITY_IPHONE && ! UNITY_ANDROID ) static private IntPtr NimbleBridge_MTX_getPurchasedTransactions() { return IntPtr.Zero; } #else [DllImport (MarshalUtility.CINTERFACE_LIB_NAME)] static private extern IntPtr NimbleBridge_MTX_getPurchasedTransactions(); #endif #if UNITY_EDITOR || ( ! UNITY_IPHONE && ! UNITY_ANDROID ) static private IntPtr NimbleBridge_MTX_getPendingTransactions() { return IntPtr.Zero; } #else [DllImport (MarshalUtility.CINTERFACE_LIB_NAME)] static private extern IntPtr NimbleBridge_MTX_getPendingTransactions(); #endif #if UNITY_EDITOR || ( ! UNITY_IPHONE && ! UNITY_ANDROID ) static private IntPtr NimbleBridge_MTX_getRecoveredTransactions() { return IntPtr.Zero; } #else [DllImport (MarshalUtility.CINTERFACE_LIB_NAME)] static private extern IntPtr NimbleBridge_MTX_getRecoveredTransactions(); #endif #if UNITY_EDITOR || ( ! UNITY_IPHONE && ! UNITY_ANDROID ) static private NimbleBridge_Error NimbleBridge_MTX_resumeTransaction(string transactionId, BridgeMTXTransactionCallback receiptCallback, IntPtr receiptCallbackData, BridgeMTXTransactionCallback purchaseCallback, IntPtr purchaseCallbackData, BridgeMTXTransactionCallback itemGrantedCallback, IntPtr itemGrantedCallbackData, BridgeMTXTransactionCallback finalizeCallback, IntPtr finalizeCallbackData) { return new NimbleBridge_Error(IntPtr.Zero); } #else [DllImport (MarshalUtility.CINTERFACE_LIB_NAME)] static private extern NimbleBridge_Error NimbleBridge_MTX_resumeTransaction(string transactionId, BridgeMTXTransactionCallback receiptCallback, IntPtr receiptCallbackData, BridgeMTXTransactionCallback purchaseCallback, IntPtr purchaseCallbackData, BridgeMTXTransactionCallback itemGrantedCallback, IntPtr itemGrantedCallbackData, BridgeMTXTransactionCallback finalizeCallback, IntPtr finalizeCallbackData); #endif #if UNITY_EDITOR || ( ! UNITY_IPHONE && ! UNITY_ANDROID ) static private void MockRefreshFinishedNotification(System.Timers.Timer timer) { timer.Enabled = false; string userData = "{\"" + NimbleBridge_Global.DICTIONARY_KEY_RESULT_BOOLEAN + "\":\"" + NimbleBridge_Global.DICTIONARY_VALUE_RESULT_SUCCESS + "\"}"; NimbleBridge_NotificationCenter.SendNotification(NimbleBridge_MTX.NOTIFICATION_REFRESH_CATALOG_FINISHED, userData); timer.Close(); } static private void NimbleBridge_MTX_refreshAvailableCatalogItems() { System.Timers.Timer timer = new System.Timers.Timer(1000); timer.Elapsed += delegate { MockRefreshFinishedNotification(timer); }; timer.Enabled = true; timer.AutoReset = false; } #else [DllImport (MarshalUtility.CINTERFACE_LIB_NAME)] static private extern void NimbleBridge_MTX_refreshAvailableCatalogItems(); #endif #if UNITY_EDITOR || ( ! UNITY_IPHONE && ! UNITY_ANDROID ) static private IntPtr NimbleBridge_MTX_getAvailableCatalogItems() { return IntPtr.Zero; } #else [DllImport (MarshalUtility.CINTERFACE_LIB_NAME)] static private extern IntPtr NimbleBridge_MTX_getAvailableCatalogItems(); #endif #if UNITY_EDITOR || ( ! UNITY_IPHONE && ! UNITY_ANDROID ) static private void NimbleBridge_MTX_setPlatformParameters(NimbleBridge_Map parameters) { } #else [DllImport (MarshalUtility.CINTERFACE_LIB_NAME)] static private extern void NimbleBridge_MTX_setPlatformParameters(NimbleBridge_Map parameters); #endif #if UNITY_EDITOR || ( ! UNITY_IPHONE && ! UNITY_ANDROID ) static private void NimbleBridge_MTXRefreshReceipt(BridgeMTXCompletionCallback refreshReceiptCallback, IntPtr refreshReceiptCallbackData) { } #else [DllImport (MarshalUtility.CINTERFACE_LIB_NAME)] static private extern void NimbleBridge_MTXRefreshReceipt(BridgeMTXCompletionCallback refreshReceiptCallback, IntPtr refreshReceiptCallbackData); #endif #if UNITY_EDITOR || ( ! UNITY_IPHONE && ! UNITY_ANDROID ) static private void NimbleBridge_MTX_registerPromotedPaymentHandler(BridgeMTXPromotedPaymentCallback promotedPaymentCallback, IntPtr promotedPaymentCallbackData) { } #else [DllImport (MarshalUtility.CINTERFACE_LIB_NAME)] static private extern void NimbleBridge_MTX_registerPromotedPaymentHandler(BridgeMTXPromotedPaymentCallback promotedPaymentCallback, IntPtr promotedPaymentCallbackData); #endif #if UNITY_EDITOR || ( ! UNITY_IPHONE && ! UNITY_ANDROID ) static private void NimbleBridge_MTX_fetchStorePromotionOrder(BridgeMTXPromotedItemsCallback promotedItemsCallback, IntPtr promotedItemsCallbackData) { } #else [DllImport (MarshalUtility.CINTERFACE_LIB_NAME)] static private extern void NimbleBridge_MTX_fetchStorePromotionOrder(BridgeMTXPromotedItemsCallback promotedItemsCallback, IntPtr promotedItemsCallbackData); #endif #if UNITY_EDITOR || ( ! UNITY_IPHONE && ! UNITY_ANDROID ) static private void NimbleBridge_MTX_updateStorePromotionOrder(IntPtr skus, BridgeMTXCompletionCallback completionCallback, IntPtr completionCallbackData) { } #else [DllImport (MarshalUtility.CINTERFACE_LIB_NAME)] static private extern void NimbleBridge_MTX_updateStorePromotionOrder(IntPtr skus, BridgeMTXCompletionCallback completionCallback, IntPtr completionCallbackData); #endif #if UNITY_EDITOR || ( ! UNITY_IPHONE && ! UNITY_ANDROID ) static private void NimbleBridge_MTX_fetchStorePromotionVisibility(string sku, BridgeMTXStorePromotionVisibilityCallback visibilityCallback, IntPtr visibilityCallbackData) { } #else [DllImport (MarshalUtility.CINTERFACE_LIB_NAME)] static private extern void NimbleBridge_MTX_fetchStorePromotionVisibility(string sku, BridgeMTXStorePromotionVisibilityCallback visibilityCallback, IntPtr visibilityCallbackData); #endif #if UNITY_EDITOR || ( ! UNITY_IPHONE && ! UNITY_ANDROID ) static private void NimbleBridge_MTX_updateStorePromotionVisibility(string sku, int visibility, BridgeMTXCompletionCallback completionCallback, IntPtr completionCallbackData) { } #else [DllImport (MarshalUtility.CINTERFACE_LIB_NAME)] static private extern void NimbleBridge_MTX_updateStorePromotionVisibility(string sku, int visibility, BridgeMTXCompletionCallback completionCallback, IntPtr completionCallbackData); #endif private NimbleBridge_MTX() { } static public NimbleBridge_MTX GetComponent() { return new NimbleBridge_MTX(); } /*! * Purchase an item given an item identifier. Optional: Include metadata (e.g. offer code) that will be added to the transaction. * Returns Error object on error. Null if no immediate error. */ public NimbleBridge_Error PurchaseItem(string sku, MTXTransactionCallback receiptCallback, MTXTransactionCallback purchaseCallback, string metadata = "") { var receiptCbData = NimbleBridge_CallbackHelper.Get().MakeCallbackData(receiptCallback); var purchaseCbData = NimbleBridge_CallbackHelper.Get().MakeCallbackData(purchaseCallback); NimbleBridge_Error error = NimbleBridge_MTX_purchaseItem(sku, OnMTXTransactionCallback, receiptCbData, OnMTXTransactionCallback, purchaseCbData, metadata); return error; } /*! * Consume the given item/transaction. Where necessary, this makes the notification to the billing platform * that the item has been granted. Indicate if this was a consumable or non-consumable item. * * Note: Game should call ItemGranted() immediately after granting the item to the player to avoid exploit where * user interrupts the app between item grant and GooglePlay consumption, then restores purchases and gets * the same item again through the restore. * * @param transactionId * @param itemType * @param callback * @return Error object on error. Null if no immediate error. */ public NimbleBridge_Error ItemGranted(string transactionId, NimbleBridge_MTXCatalogItem.Type itemType, MTXTransactionCallback callback) { var cbData = NimbleBridge_CallbackHelper.Get().MakeCallbackData(callback); NimbleBridge_Error error = NimbleBridge_MTX_itemGranted(transactionId, (int) itemType, OnMTXTransactionCallback, cbData); return error; } /*! * Game calls this to acknowledge the purchase notification, for both successes and errors. * * @param transactionId * @param callback */ public NimbleBridge_Error FinalizeTransaction(string transactionId, MTXTransactionCallback callback) { var cbData = NimbleBridge_CallbackHelper.Get().MakeCallbackData(callback); NimbleBridge_Error error = NimbleBridge_MTX_finalizeTransaction(transactionId, OnMTXTransactionCallback, cbData); return error; } /*! * Get list of already purchased items, as list of SKU strings. * This list does not include history of consumable items. * This list does not included subscription items (not supported). * Game notified of completion via notification, NOTIFICATION_MTX_RESTORE_PURCHASED_TRANSACTIONS_FINISHED. */ public void RestorePurchasedTransactions() { NimbleBridge_MTX_restorePurchasedTransactions(); } /*! * Get already purchased items as a list of NimbleMTXTransactions. The transaction object includes receipts * and additional info. * * @return */ public NimbleBridge_MTXTransaction[] GetPurchasedTransactions() { IntPtr transactionArrayPtr = NimbleBridge_MTX_getPurchasedTransactions(); return MarshalUtility.ConvertPtrToArray(transactionArrayPtr, ptr => new NimbleBridge_MTXTransaction(ptr)); } /*! * Get list of in-progress transactions that have not been finalized. */ public NimbleBridge_MTXTransaction[] GetPendingTransactions() { IntPtr transactionArrayPtr = NimbleBridge_MTX_getPendingTransactions(); return MarshalUtility.ConvertPtrToArray(transactionArrayPtr, ptr => new NimbleBridge_MTXTransaction(ptr)); } /*! * Get list of purchase transactions recovered from a previous session. Call resumePurchaseTransaction to continue the process. * * @return */ public NimbleBridge_MTXTransaction[] GetRecoveredTransactions() { IntPtr transactionArrayPtr = NimbleBridge_MTX_getRecoveredTransactions(); return MarshalUtility.ConvertPtrToArray(transactionArrayPtr, ptr => new NimbleBridge_MTXTransaction(ptr)); } /*! * Resume a recovered transaction. * * @param transactionId * @param callback * */ public NimbleBridge_Error ResumeTransaction(string transactionId, MTXTransactionCallback receiptCallback, MTXTransactionCallback purchaseCallback, MTXTransactionCallback itemGrantedCallback, MTXTransactionCallback finalizeCallback) { var helper = NimbleBridge_CallbackHelper.Get(); var receiptCbData = helper.MakeCallbackData(receiptCallback); var purchaseCbData = helper.MakeCallbackData(purchaseCallback); var itemGrantedCbData = helper.MakeCallbackData(itemGrantedCallback); var finalizeCbData = helper.MakeCallbackData(finalizeCallback); NimbleBridge_Error error = NimbleBridge_MTX_resumeTransaction(transactionId, OnMTXTransactionCallback, receiptCbData, OnMTXTransactionCallback, purchaseCbData, OnMTXTransactionCallback, itemGrantedCbData, OnMTXTransactionCallback, finalizeCbData); return error; } /*! * Initiate a refresh of the entire catalog. No filter. */ public void RefreshAvailableCatalogItems() { NimbleBridge_MTX_refreshAvailableCatalogItems(); } /*! * Get the list of available items. */ public NimbleBridge_MTXCatalogItem[] GetAvailableCatalogItems() { #if UNITY_EDITOR || ( ! UNITY_IPHONE && ! UNITY_ANDROID ) List items = new List(); foreach (uint mtxCatalogItemId in NimbleBridge_MockDataStorage.Get().GetMTXCatalogItemIds()) { items.Add(new NimbleBridge_MTXCatalogItem(mtxCatalogItemId)); } return items.ToArray(); #else IntPtr itemArrayPtr = NimbleBridge_MTX_getAvailableCatalogItems(); return MarshalUtility.ConvertPtrToArray(itemArrayPtr, ptr => new NimbleBridge_MTXCatalogItem(ptr)); #endif } /*! * Set MTX platform specific parameters in a key-value map. It is up to the MTX component implementation to understand the key-value passed in. */ public void SetPlatformParameters(Dictionary parameters) { NimbleBridge_MTX_setPlatformParameters(MarshalUtility.ConvertDictionaryToMap(parameters)); } public void RefreshReceipt(MTXRefreshReceiptCallback refreshReceiptCallback) { var helper = NimbleBridge_CallbackHelper.Get(); var receiptCbData = helper.MakeCallbackData(refreshReceiptCallback); NimbleBridge_MTXRefreshReceipt(OnMTXRefreshReceiptCallback, receiptCbData); } /*! * Registers promoted payment handler which returns a NimbleMTXPromotedPaymentAction depending on if the promoted payment should be continued, delayed, or canceled. * This callback is used to determine the action to take when a user initiates a promoted payment through the Apple store. iOS only. */ public void RegisterPromotedPaymentHandler(MTXPromotedPaymentCallback promotedPaymentCallback) { var helper = NimbleBridge_CallbackHelper.Get(); var promotedPaymentCbData = helper.MakeCallbackData(promotedPaymentCallback); NimbleBridge_MTX_registerPromotedPaymentHandler(OnMTXPromotedPaymentCallback, promotedPaymentCbData); } public void FetchStorePromotionOrder(MTXPromotedItemsCallback promotedItemsCallback) { var helper = NimbleBridge_CallbackHelper.Get(); var promotedItemsCbData = helper.MakeCallbackData(promotedItemsCallback); NimbleBridge_MTX_fetchStorePromotionOrder(OnMTXPromotedItemsCallback, promotedItemsCbData); } public void UpdateStorePromotionOrder(List skus, MTXCompletionCallback completionCallback) { var helper = NimbleBridge_CallbackHelper.Get(); var completionCbData = helper.MakeCallbackData(completionCallback); NimbleBridge_MTX_updateStorePromotionOrder(MarshalUtility.ConvertArrayToPtr(skus), OnMTXCompletionCallback, completionCbData); } public void FetchStorePromotionVisibility(string sku, MTXStorePromotionVisibilityCallback visibilityCallback) { var helper = NimbleBridge_CallbackHelper.Get(); var visibilityCbData = helper.MakeCallbackData(visibilityCallback); NimbleBridge_MTX_fetchStorePromotionVisibility(sku, OnMTXStorePromotionVisibilityCallback, visibilityCbData); } public void UpdateStorePromotionVisibility(string sku, NimbleBridge_StorePromotionVisibility visibility, MTXCompletionCallback completionCallback) { var helper = NimbleBridge_CallbackHelper.Get(); var completionCbData = helper.MakeCallbackData(completionCallback); NimbleBridge_MTX_updateStorePromotionVisibility(sku, (int)visibility, OnMTXCompletionCallback, completionCbData); } }