Advertisement
Guest User

Untitled

a guest
Dec 5th, 2022
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 11.11 KB | None | 0 0
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using com.amazon.device.iap.cpt;
  5. using UnityEngine;
  6.  
  7. public class IAPManagerV2 : MonoBehaviour {
  8.     [SerializeField] private GameObject purchaseLoader;
  9.     private IAmazonIapV2 _iapService;
  10.  
  11.     private Dictionary<string, Dictionary<string, long>>
  12.         _shopItems = new Dictionary<string, Dictionary<string, long>>();
  13.  
  14.     private Dictionary<string, float> _shopItemPrices = new Dictionary<string, float>();
  15.     private Dictionary<string, bool> _amazonResponseReceived = new Dictionary<string, bool>();
  16.     private int _amazonRequestTimeout;
  17.     HashSet<string> fulfilledPurchases = new HashSet<string>();
  18.     public Action<Product> purchaseCompleteAction;
  19.     public Action purchaseFailedAction;
  20.  
  21.     [SerializeField] string purchaseCompleteEvent;
  22.  
  23.     private void Awake() {
  24.         _iapService = AmazonIapV2Impl.Instance;
  25.         _iapService.AddGetPurchaseUpdatesResponseListener(EventHandler);
  26.         _iapService.AddPurchaseResponseListener(EventHandler);
  27.         _iapService.AddGetProductDataResponseListener(EventHandler);
  28.  
  29.         GetPurchaseUpdates();
  30.     }
  31.  
  32.     private void InvokePurchaseComplete(Product product) {
  33.         purchaseCompleteAction?.Invoke(product);
  34.     }
  35.  
  36.     private void InvokePurchaseFailed() {
  37.         purchaseFailedAction?.Invoke();
  38.         DestroyLoader();
  39.     }
  40.  
  41.     private void GetProductData() {
  42.         SkusInput request = new SkusInput();
  43.         List<string> list = new List<string>();
  44.         foreach (var item in _shopItems) {
  45.             list.Add(item.Key);
  46.         }
  47.  
  48.         request.Skus = list;
  49.         Analytics.anl.SendEvent("AMAZON_FETCH_PRODUCTS");
  50.         RequestOutput response = _iapService.GetProductData(request);
  51.         string requestIdString = response.RequestId;
  52.         if (requestIdString != null) {
  53.             _amazonResponseReceived[requestIdString] = false;
  54.             StartCoroutine(sendFailureEventOnTimeout("AMAZON_FETCH_PRODUCTS_FAILED", requestIdString));
  55.         }
  56.         else
  57.             Analytics.anl.SendEvent("AMAZON_IAP_FAILURE");
  58.     }
  59.  
  60.     public void Purchase(string sku, string purchaseName) {
  61.         SetProductPayoutsToCache(sku, purchaseName);
  62.         Analytics.anl.SendEvent("PURCHASE_CLICKED",
  63.             new Dictionary<string, string>()
  64.             { { "misc", sku } });
  65.         purchaseLoader.SetActive(true);
  66.         if (Debug.isDebugBuild) {
  67.             StartCoroutine(DebugDelayedPurchase(sku, 3, simulateSuccessInEditor: true));
  68.             return;
  69.         }
  70.  
  71.         SkuInput request = new SkuInput();
  72.         request.Sku = sku;
  73.         RequestOutput response = _iapService.Purchase(request);
  74.         string requestIdString = response.RequestId;
  75.         if (requestIdString != null) {
  76.             _amazonResponseReceived[requestIdString] = false;
  77.             StartCoroutine(FailsafeManualFulfillPurchase(requestIdString));
  78.             StartCoroutine(sendFailureEventOnTimeout("AMAZON_PURCHASE_FAILED", requestIdString));
  79.         }
  80.         else
  81.             Analytics.anl.SendEvent("AMAZON_IAP_FAILURE");
  82.     }
  83.  
  84.  
  85.     private void EventHandler(PurchaseResponse args) {
  86.         DestroyLoader();
  87.         if (args.RequestId != null)
  88.             _amazonResponseReceived[args.RequestId] = true;
  89.         if (args.Status == "FAILED" || args.Status == "INVALID_SKU") {
  90.             Analytics.anl.SendEvent("AMAZON_PURCHASE_FAILED",
  91.                 new Dictionary<string, string>()
  92.                 { { "misc", "Response received, status " + args.Status } });
  93.             InvokePurchaseFailed();
  94.             return;
  95.         }
  96.  
  97.         string receiptId = args.PurchaseReceipt.ReceiptId;
  98.         string sku = args.PurchaseReceipt.Sku;
  99.         Analytics.anl.SendEvent("AMAZON_PURCHASE_SUCCESS",
  100.             new Dictionary<string, string>()
  101.             { { "purchase_code", sku } });
  102.         FulfillPurchase(new Product(sku, receiptId, _shopItems[sku]));
  103.     }
  104.  
  105.     private IEnumerator FailsafeManualFulfillPurchase(string requestIdString) {
  106.         yield return new WaitForSeconds(_amazonRequestTimeout);
  107.         if (!_amazonResponseReceived[requestIdString])
  108.             GetPurchaseUpdates();
  109.     }
  110.  
  111.     public void GetPurchaseUpdates() {
  112.  
  113.         ResetInput request = new ResetInput();
  114.         // false = get new purchases since last time this was called, true = get all purchases for user
  115.         request.Reset = true;
  116.         // ServerEventSender.SendEvent("AMAZON_FETCH_UNFULFILLED");
  117.         RequestOutput response = _iapService.GetPurchaseUpdates(request);
  118.  
  119.         string requestIdString = response.RequestId;
  120.         if (requestIdString != null) {
  121.             _amazonResponseReceived[requestIdString] = false;
  122.             StartCoroutine(sendFailureEventOnTimeout("AMAZON_FETCH_UNFULFILLED_FAILED", requestIdString));
  123.         }
  124.         else
  125.             Analytics.anl.SendEvent("AMAZON_IAP_FAILURE");
  126.     }
  127.  
  128.     /// <summary>
  129.     ///
  130.     /// </summary>
  131.     /// <param name="args"> Description:
  132.     ///     userId = args.AmazonUserData.UserId;
  133.     ///     marketplace = args.AmazonUserData.Marketplace;
  134.     ///     hasMore = args.HasMore;
  135.     ///     status = args.Status;
  136.     /// </param>
  137.     private void EventHandler(GetPurchaseUpdatesResponse args) {
  138.         if (args.RequestId != null)
  139.             _amazonResponseReceived[args.RequestId] = true;
  140.         List<PurchaseReceipt> receipts = args.Receipts;
  141.         Debug.Log("Got events");
  142.         int numOfReceipts = 0;
  143.         if (receipts != null) {
  144.             Debug.Log("Got reciepts");
  145.             numOfReceipts = receipts.Count;
  146.         }
  147.  
  148.         if (numOfReceipts.Equals(0)) {
  149.             Debug.Log("Got no reciepts");
  150.             DestroyLoader();
  151.             InvokePurchaseFailed();
  152.         }
  153.  
  154.         Analytics.anl.SendEvent("AMAZON_UNFULFILLED_RECEIVED",
  155.             new Dictionary<string, string>()
  156.             { { "misc", "unfulfilled purchases: " + numOfReceipts.ToString() } });
  157.         foreach (var receipt in receipts) {
  158.             if (_shopItems.ContainsKey(receipt.Sku))
  159.                 FulfillPurchase(new Product(receipt.Sku, receipt.ReceiptId, _shopItems[receipt.Sku]));
  160.             else
  161.                 FulfillPurchase(new Product(receipt.Sku, receipt.ReceiptId, GetLastProductPayoutsFromCache()));
  162.         }
  163.     }
  164.  
  165.     private Dictionary<string, long> GetLastProductPayoutsFromCache() {
  166.         Dictionary<string, long> payouts = new Dictionary<string, long>()
  167.         {
  168.         { Constants.Coins,
  169.           long.Parse(PlayerPrefs.GetString(Constants.LastProductClicked_Coins, "0")) } };
  170.         return payouts;
  171.     }
  172.  
  173.     private void SetProductPayoutsToCache(string sku, string purchaseName) {
  174.         long spins = 0, coins = 0;
  175.  
  176.         var shortenedShopItems = JsonUtility.ToJson(_shopItems.Keys).Replace("island_lords_prod_", "");
  177.         if (!_shopItems.ContainsKey(sku))
  178.             Analytics.anl.SendEvent("ERROR", new Dictionary<string, string>()
  179.             { { "misc", sku + "-No such product sku in config. Not a crash, but investigate!" },
  180.               { "comment", shortenedShopItems } });
  181.         else {
  182.             if (_shopItems[sku].ContainsKey(Constants.Coins))
  183.                 coins = _shopItems[sku][Constants.Coins];
  184.         }
  185.  
  186.         PlayerPrefs.SetString(Constants.LastProductClicked_Spins, spins.ToString());
  187.         PlayerPrefs.SetString(Constants.LastProductClicked_Coins, coins.ToString());
  188.         PlayerPrefs.SetString(Constants.LastProductClicked_Name, purchaseName);
  189.         PlayerPrefs.Save();
  190.     }
  191.  
  192.     private void EventHandler(GetProductDataResponse args) {
  193.         if (args.RequestId != null)
  194.             _amazonResponseReceived[args.RequestId] = true;
  195.         Dictionary<string, ProductData> productDataMap = args.ProductDataMap;
  196.         List<string> unavailableSkus = args.UnavailableSkus;
  197.         string status = args.Status;
  198.         if (productDataMap != null && productDataMap.Count > 0)
  199.             Analytics.anl.SendEvent("AMAZON_FETCH_PRODUCTS_SUCCESS");
  200.         else
  201.             Analytics.anl.SendEvent("AMAZON_FETCH_PRODUCTS_FAILED");
  202.     }
  203.  
  204.     private void FulfillPurchase(Product product) {
  205.         if (!fulfilledPurchases.Contains(product.receiptId)) {
  206.             DestroyLoader();
  207.  
  208.                 InvokePurchaseComplete(product);
  209.  
  210.             fulfilledPurchases.Add(product.receiptId);
  211.         }
  212.     }
  213.  
  214.     public void NotifyFulfillment(Product product, string purchaseName) {
  215.         // Construct object passed to operation as input
  216.         NotifyFulfillmentInput request = new NotifyFulfillmentInput();
  217.  
  218.         // Set input values
  219.         request.ReceiptId = product.receiptId;
  220.         request.FulfillmentResult = "FULFILLED";
  221.         // Call synchronous operation with input object
  222.         _iapService.NotifyFulfillment(request);
  223.         string productPayouts = JsonUtility.ToJson(_shopItems[product.sku]);
  224.         long coinsPurchased = 0;
  225.         if (productPayouts.Contains(Constants.Coins))
  226.             coinsPurchased = _shopItems[product.sku][Constants.Coins];
  227.         if (!Application.isEditor)
  228.         {
  229.             Analytics.anl.SendEvent("AMAZON_PURCHASE_FULFILLED",
  230.             new Dictionary<string, string>()
  231.             { { "purchase_code", product.sku },
  232.               { "purchase_payed", _shopItemPrices[product.sku].ToString() },
  233.               { "misc", productPayouts },
  234.               { "purchase_comment", purchaseName },
  235.               { "win_amount", coinsPurchased.ToString() } });
  236.         }
  237.     }
  238.  
  239.     private void DefaultPurchaseFulfillment(Product product) {
  240.         if (product.payouts.ContainsKey(Constants.Coins))
  241.             NotifyFulfillment(product, PlayerPrefs.GetString(Constants.LastProductClicked_Name));
  242.     }
  243.  
  244.     private IEnumerator sendFailureEventOnTimeout(string eventName, string requestId) {
  245.         yield return new WaitForSeconds(_amazonRequestTimeout);
  246.         if (!_amazonResponseReceived[requestId]) {
  247.             Analytics.anl.SendEvent(eventName, new Dictionary<string, string>()
  248.             { { "misc", "After " + _amazonRequestTimeout + " seconds" } });
  249.         }
  250.     }
  251.  
  252.     public void InitIapWithConfigs() {
  253.         _shopItems.Add(GlobalValues.config.gameData.shop.items[0].itemCode, new Dictionary<string, long> { { "Coins", 500 }});
  254.         _shopItems.Add(GlobalValues.config.gameData.shop.items[1].itemCode, new Dictionary<string, long> { { "RemoveAds", 200 }});
  255.         GetProductData();
  256.         GetPurchaseUpdates();
  257.     }
  258.  
  259.     private void DestroyLoader() {
  260.         if (purchaseLoader != null)
  261.             purchaseLoader.SetActive(false);
  262.     }
  263.  
  264.     private IEnumerator DebugDelayedPurchase(string sku, float delay, bool simulateSuccessInEditor) {
  265.         yield return new WaitForSeconds(0);
  266.         SkuInput request = new SkuInput();
  267.         request.Sku = sku;
  268.         RequestOutput response = _iapService.Purchase(request);
  269.         string requestIdString = response.RequestId;
  270.  
  271.         Product productPurchased = new Product(sku, "fake editor receipt", _shopItems[sku]);
  272.         if (simulateSuccessInEditor)
  273.             InvokePurchaseComplete(productPurchased);
  274.         else
  275.             InvokePurchaseFailed();
  276.         DestroyLoader();
  277.  
  278.     }
  279. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement