private void TicketReceived(string purchaseId, string productId, string ticketId, Action <string> purchaseSucceeded, Action <string, PurchaseError, int, string> purchaseFailed) { var product = this.controller.products.WithID(productId); if (product != null) { if (product.availableToPurchase) { routerState = RouterState.Purchasing; /* * renew callback. */ callbacks = new Callbacks(product, purchaseId, ticketId, purchaseSucceeded, purchaseFailed); this.controller.InitiatePurchase(product); return; } } routerState = RouterState.PurchaseReady; if (purchaseFailed != null) { purchaseFailed(purchaseId, PurchaseError.UnavailableProduct, -1, "selected product is not available."); } }
public RouterActor(Props routeeProps, IRouterConfig config, RouterState routerState, AutoResetEvent wg) { _routeeProps = routeeProps; _config = config; _routerState = routerState; _wg = wg; }
public async Task Test_ResumeAsync_Resumes_Stored_ViewModel_State() { Resolver.Register(() => new TestReActivatableViewModel(), typeof(TestReActivatableViewModel)); Navigator = new Navigator(); Router = new Router(Navigator); var routerParams = new RouterBuilder() .When <TestReActivatableViewModel>(r => r.Navigate()) .Build(); var viewModelState = new TestState(); var savedState = new RouterState() { Actions = new[] { new Router.StoredRouterAction() { Action = RouterActions.ShowViewModel(typeof(TestReActivatableViewModel), new TestParams()), ViewModelState = viewModelState }, } }; await Router.InitAsync(routerParams); await Router.ResumeAsync(savedState); Assert.Collection(Navigator.TransitionStack, t => { t.ViewModel.Should().BeAssignableTo <TestReActivatableViewModel>(); t.ViewModel.As <TestReActivatableViewModel>().State.Should().Be(viewModelState); }); }
// public class MyPurchasingModule : UnityEngine.Purchasing.Extension.IPurchasingModule { // public void Configure (UnityEngine.Purchasing.Extension.IPurchasingBinder binder) { // binder.RegisterStore("MyManufacturerAppStore", InstantiateMyManufacturerAppStore()); // // Our Purchasing service implementation provides the real implementation. // binder.RegisterExtension<IStoreExtension>(new FakeManufacturerExtensions()); // } // UnityEngine.Purchasing.Extension.IStore InstantiateMyManufacturerAppStore () { // // Check for Manufacturer. "Android" used here for the sake of example. // // In your implementation, return platform-appropriate store instead of "null". // if (Application.platform == RuntimePlatform.Android) { return null; } // else { return null; } // } // public IStoreExtension IManufacturerExtensions() { return null; } // } // public class FakeManufacturerExtensions : IStoreExtension { // } private void ReadyIAPFeature(ProductInfo[] productInfos) { routerState = RouterState.LoadingStore; #if !Update_PurchaseLib var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance()); foreach (var productInfo in productInfos) { builder.AddProduct( productInfo.productId, ProductType.Consumable, new IDs { { productInfo.platformProductId, storeKind } } ); } /* * check network connectivity again. because Unity IAP never tells offline. */ if (Application.internetReachability == NetworkReachability.NotReachable) { failedToReady(PurchaseReadyError.Offline, 0, "network is offline."); return; } UnityPurchasing.Initialize(this, builder); #endif }
/** * start purchase. */ public void PurchaseAsync( string purchaseId, string productId, Action <string> purchaseSucceeded, Action <string, PurchaseError, string> purchaseFailed ) { if (Application.internetReachability == NetworkReachability.NotReachable) { purchaseFailed(purchaseId, PurchaseError.Offline, "network is offline."); return; } var error = PurchaseError.None; var reason = string.Empty; if (!IsPurchaseReady(out error, out reason)) { purchaseFailed(purchaseId, error, reason); return; } if (verifiedProducts != null) { var verified = false; foreach (var verifiedProduct in verifiedProducts) { if (verifiedProduct.productId == productId && verifiedProduct.isAvailableToThisPlayer) { verified = true; } } if (!verified) { purchaseFailed(purchaseId, PurchaseError.UnavailableProduct, "this product is not available."); return; } var product = this.controller.products.WithID(productId); if (product != null) { if (product.availableToPurchase) { routerState = RouterState.Purchasing; // renew callback. callbacks = new Callbacks(product, purchaseId, string.Empty, purchaseSucceeded, purchaseFailed); this.controller.InitiatePurchase(product); } else { routerState = RouterState.PurchaseReady; purchaseFailed(purchaseId, PurchaseError.UnavailableProduct, "selected product is not available."); } } } }
private IEnumerator _Ready( Func <RequestProductInfosAs> getProductInfosAs, Func <object, ProductInfo[]> onLoadProducts, Action reloaded, Action <PurchaseReadyError, int, string> failedToReady ) { if (routerState == RouterState.PurchaseReady) { // IAP features are already running. // no need to reload. reloaded(); yield break; } this.readyPurchase = reloaded; this.failedToReady = failedToReady; routerState = RouterState.LoadingProducts; var connectionId = PurchaseSettings.PURCHASE_CONNECTIONID_READY_PREFIX + Guid.NewGuid().ToString(); var url = PurchaseSettings.PURCHASE_URL_READY; var getAs = getProductInfosAs(); var cor = HttpGet( connectionId, url, (conId, data) => { if (data is string) { var productsFromStr = onLoadProducts((string)data); this.verifiedProducts = productsFromStr; ReadyIAPFeature(productsFromStr); return; } var products = onLoadProducts((byte[])data); this.verifiedProducts = products; ReadyIAPFeature(products); }, (conId, code, reason) => { routerState = RouterState.FailedToGetProducts; this.failedToReady(PurchaseReadyError.FailedToGetProducts, code, reason); }, getAs ); while (cor.MoveNext()) { yield return(null); } }
public Router(WendingMachine machine) { _machine = machine; _state = new DefaultState(this); _dependencies = new Dictionary <Type, object>() { { typeof(WendingMachine), _machine }, { typeof(Router), this } }; }
/// <summary> /// Called when Unity IAP is ready to make purchases. /// </summary> public void OnInitialized(IStoreController controller, IExtensionProvider extensions) { this.controller = controller; this.extensions = extensions; routerState = RouterState.PurchaseReady; if (readyPurchase != null) { readyPurchase(); } }
private void TryFinalizeShutdown() { if ((_state == RouterState.Client || _shuttingDown) && _connections.Count == 0) { try { NetworkTransport.RemoveHost(_hostId); _hostId = -1; _clientId = -1; Stopped(); } finally { _shuttingDown = false; _state = RouterState.None; } } }
/// <summary> /// Start a network server. /// </summary> /// <param name="port"></param> /// <param name="maxConnections"></param> /// <returns></returns> public bool StartServer(int port, int maxConnections) { if (_state != RouterState.None || _shuttingDown) { throw new InvalidOperationException(); } if ((_hostId = NetworkTransport.AddHost(new HostTopology(_connectionConfig, maxConnections), port)) >= 0) { _state = RouterState.Server; Started(); return(true); } else { return(false); } }
/** * constructor. */ public LocalPurchaseRouter(ProductInfo[] productInfos, Action onReadyPurchase, Action <PurchaseError, string> onReadyFailed, Action <string> onPurchaseDoneInBackground) { this.verifiedProducts = productInfos; this.readyPurchase = onReadyPurchase; this.failedToReady = onReadyFailed; this.purchasedInBackground = onPurchaseDoneInBackground; /* * set store kind by platform. */ #if UNITY_EDITOR this.storeKind = "dummy";//AppleAppStore.Name; #elif UNITY_IOS this.storeKind = AppleAppStore.Name; #elif UNITY_ANDROID this.storeKind = GooglePlay.Name; #endif routerState = RouterState.LoadingStore; var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance()); foreach (var productInfo in productInfos) { builder.AddProduct( productInfo.productId, ProductType.Consumable, new IDs { { productInfo.platformProductId, storeKind } } ); } /* * check network connectivity. because Unity IAP never tells offline. */ if (Application.internetReachability == NetworkReachability.NotReachable) { failedToReady(PurchaseError.Offline, "network is offline."); return; } UnityPurchasing.Initialize(this, builder); }
public async Task Test_StartAsync_Calls_ResumeAsync_On_IRouter_When_State_Is_Available() { var router = Substitute.For <IRouter>(); var stateStore = Substitute.For <IObjectStateStore>(); var routerParams = new RouterConfig(); var routerState = new RouterState(); var state = new ObjectState() { State = routerState }; stateStore.LoadStateAsync().Returns(state); Register(routerParams); Register(stateStore); Register(router); await AppHost.StartAsync(); ((IReActivatable)router).Received(1).ResumeAsync(routerState); }
private IEnumerator _Ready( Func <string, ProductInfo[]> onLoadProducts, Action reloaded, Action <PurchaseError, string, AutoyaStatus> reloadFailed ) { if (routerState == RouterState.PurchaseReady) { // IAP features are already running. // no need to reload. reloaded(); yield break; } this.readyPurchase = reloaded; this.failedToReady = reloadFailed; routerState = RouterState.LoadingProducts; var connectionId = PurchaseSettings.PURCHASE_CONNECTIONID_READY_PREFIX + Guid.NewGuid().ToString(); var url = PurchaseSettings.PURCHASE_URL_READY; var cor = HttpGet( connectionId, url, (conId, data) => { var products = onLoadProducts(data); this.verifiedProducts = products; ReadyIAPFeature(products); }, (conId, code, reason, autoyaStatus) => { routerState = RouterState.FailedToLoadProducts; failedToReady(PurchaseError.UnknownError, reason, autoyaStatus); } ); while (cor.MoveNext()) { yield return(null); } }
/// <summary> /// Called when Unity IAP encounters an unrecoverable initialization error. /// /// Note that this will not be called if Internet is unavailable; Unity IAP /// will attempt initialization until it becomes available. /// </summary> public void OnInitializeFailed(InitializationFailureReason error) { routerState = RouterState.FailedToLoadStore; switch (error) { case InitializationFailureReason.AppNotKnown: { failedToReady(PurchaseError.UnityIAP_Initialize_AppNowKnown, "The store reported the app as unknown."); break; } case InitializationFailureReason.NoProductsAvailable: { failedToReady(PurchaseError.UnityIAP_Initialize_NoProductsAvailable, "No products available for purchase."); break; } case InitializationFailureReason.PurchasingUnavailable: { failedToReady(PurchaseError.UnityIAP_Initialize_PurchasingUnavailable, "In-App Purchases disabled in device settings."); break; } } }
/// <summary> /// Connect to a server. /// </summary> /// <param name="ipAddress"></param> /// <param name="port"></param> public void Connect(IPAddress address, int port) { if (_state != RouterState.None || _shuttingDown) { throw new InvalidOperationException(); } _hostId = NetworkTransport.AddHost(new HostTopology(_connectionConfig, 1)); byte error; _clientId = NetworkTransport.Connect(_hostId, address.ToString(), port, 0, out error); if (error == (byte)NetworkError.Ok) { _state = RouterState.Client; Started(); } else { NetworkTransport.RemoveHost(_hostId); } }
public async Task Test_Clears_Stored_State_When_ResumeAsync_Fails_On_Router() { var router = Substitute.For <IRouter>(); var stateStore = Substitute.For <IObjectStateStore>(); var routerParams = new RouterConfig(); var routerState = new RouterState(); var state = new ObjectState() { State = routerState }; router.CloseApp.Returns(Observable.Never <Unit>()); stateStore.LoadStateAsync().Returns(state); router.ResumeAsync(Arg.Any <object>()).Throws <Exception>(); Register(routerParams); Register(stateStore); Register(router); await AppHost.StartAsync(); stateStore.Received(1).SaveStateAsync(null); }
public async Task Test_Does_Not_Save_State_When_Router_Notifies_CloseApp() { var closeApp = new Subject <Unit>(); var router = Substitute.For <IRouter>(); var stateStore = Substitute.For <IObjectStateStore>(); var routerParams = new RouterBuilder() .When <TestViewModel>(r => r.Navigate()) .Build(); var routerState = new RouterState(); router.CloseApp.Returns(closeApp); ((IReActivatable)router).GetStateAsync().Returns(routerState); Register(() => new TestViewModel()); Register(routerParams); Register(stateStore); Register(router); await AppHost.StartAsync(); closeApp.OnNext(Unit.Default); stateStore.DidNotReceive().SaveStateAsync(Arg.Is <ObjectState>(os => os.State == routerState)); }
/// <summary> /// Immediately shutdown without notifying connections. /// </summary> public void ShutdownImmediate() { if (_state != RouterState.None) { try { _shuttingDown = true; ShuttingDown(); var connections = new LinkedList <Connection>(_connections); foreach (var conn in connections) { ((IConnectionInternal)conn).TransportLayerDisconnected(); } NetworkTransport.RemoveHost(_hostId); _hostId = -1; _clientId = -1; Stopped(); } finally { _shuttingDown = false; _state = RouterState.None; } } }
/** * start purchase. */ public IEnumerator PurchaseAsync( string purchaseId, string productId, Action <string> purchaseSucceeded, Action <string, PurchaseError, int, string> purchaseFailed ) { if (Application.internetReachability == NetworkReachability.NotReachable) { if (purchaseFailed != null) { purchaseFailed(purchaseId, PurchaseError.Offline, -1, "network is offline."); } yield break; } if (routerState != RouterState.PurchaseReady) { switch (routerState) { case RouterState.GettingTransaction: case RouterState.Purchasing: { if (purchaseFailed != null) { purchaseFailed(purchaseId, PurchaseError.AlreadyPurchasing, -1, "purchasing another product now. wait then retry."); } break; } case RouterState.RetryFailed: { if (purchaseFailed != null) { purchaseFailed(purchaseId, PurchaseError.RetryFailed, -1, "purchasing completed and send it to server is retried and totally failed."); } break; } default: { if (purchaseFailed != null) { purchaseFailed(purchaseId, PurchaseError.UnknownError, -1, "state is:" + routerState); } break; } } yield break; } if (verifiedProducts != null) { var verified = false; foreach (var verifiedProduct in verifiedProducts) { if (verifiedProduct.productId == productId && verifiedProduct.isAvailableToThisPlayer) { verified = true; } } if (!verified) { if (purchaseFailed != null) { purchaseFailed(purchaseId, PurchaseError.UnavailableProduct, -1, "this product is not available. productId:" + productId); } yield break; } } // renew callback. callbacks = new Callbacks(null, string.Empty, string.Empty, tId => { }, (tId, error, code, reason) => { }); /* * start getting ticket for purchase. */ var ticketUrl = PurchaseSettings.PURCHASE_URL_TICKET; var data = onTicketRequest(productId); routerState = RouterState.GettingTransaction; var connectionId = PurchaseSettings.PURCHASE_CONNECTIONID_TICKET_PREFIX + Guid.NewGuid().ToString(); if (data is string || data is byte[]) { var cor = HttpPost( connectionId, ticketUrl, data, (conId, resultData) => { var ticketId = onTicketResponse(resultData); TicketReceived(purchaseId, productId, ticketId, purchaseSucceeded, purchaseFailed); }, (conId, code, reason) => { routerState = RouterState.PurchaseReady; if (purchaseFailed != null) { purchaseFailed(purchaseId, PurchaseError.TicketGetError, code, reason); } } ); while (cor.MoveNext()) { yield return(null); } // done sending. yield break; } throw new Exception("request data should be string or byte[]."); }
private IEnumerator RetryCoroutine(Callbacks callbacks, PurchaseEventArgs e) { var count = 0; var retryFailedHttpCode = -1; var retryFailedHttpReason = string.Empty; retry: { var waitSec = Mathf.Pow(count, 2); count++; yield return(new WaitForSeconds(waitSec)); var purchasedUrl = PurchaseSettings.PURCHASE_URL_PURCHASE; var data = onPurchaseDeployRequest(new TicketAndReceipt(callbacks.ticketId, e.purchasedProduct.receipt)); var connectionId = PurchaseSettings.PURCHASE_CONNECTIONID_PURCHASE_PREFIX + Guid.NewGuid().ToString(); IEnumerator cor = null; if (data is string || data is byte[]) { cor = HttpPost( connectionId, purchasedUrl, data, (conId, responseData) => { var product = e.purchasedProduct; controller.ConfirmPendingPurchase(e.purchasedProduct); routerState = RouterState.PurchaseReady; if (callbacks.purchaseSucceeded != null) { callbacks.purchaseSucceeded(); } }, (conId, code, reason) => { // still in RetrySending state. // update failed httpCode for show last failed reason. retryFailedHttpCode = code; retryFailedHttpReason = reason; } ); } else { throw new Exception("request data should be string or byte[]."); } while (cor.MoveNext()) { yield return(null); } if (routerState != RouterState.RetrySending) { // retry finished. yield break; } // still in retry. if (count == PurchaseSettings.PURCHASED_MAX_RETRY_COUNT) { routerState = RouterState.RetryFailed; if (callbacks.purchaseFailed != null) { callbacks.purchaseFailed(PurchaseError.RetryFailed, retryFailedHttpCode, retryFailedHttpReason); } yield break; } // continue retry. goto retry; } }
/// <summary> /// Called when a purchase completes. /// /// May be called at any time after OnInitialized(). /// </summary> public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e) { if (callbacks.p == null) { SendPaid(e); return(PurchaseProcessingResult.Pending); } if (e.purchasedProduct.transactionID != callbacks.p.transactionID) { SendPaid(e); return(PurchaseProcessingResult.Pending); } /* * this process is the purchase just retrieving now. * proceed deploy asynchronously. */ switch (routerState) { case RouterState.Purchasing: { var purchasedUrl = PurchaseSettings.PURCHASE_URL_PURCHASE; var data = onPurchaseDeployRequest(new TicketAndReceipt(callbacks.ticketId, e.purchasedProduct.receipt)); var connectionId = PurchaseSettings.PURCHASE_CONNECTIONID_PURCHASE_PREFIX + Guid.NewGuid().ToString(); if (data is string || data is byte[]) { var cor = HttpPost( connectionId, purchasedUrl, data, (conId, responseData) => { var product = e.purchasedProduct; controller.ConfirmPendingPurchase(e.purchasedProduct); routerState = RouterState.PurchaseReady; if (callbacks.purchaseSucceeded != null) { callbacks.purchaseSucceeded(); } }, (conId, code, reason) => { // OK以外のコードについてはcompleteを行わず、リトライ。 routerState = RouterState.RetrySending; StartRetry(callbacks, e); } ); enumExecutor(cor); break; } throw new Exception("request data should be string or byte[]."); } default: { // maybe never comes here. if (callbacks.purchaseFailed != null) { callbacks.purchaseFailed(PurchaseError.UnknownError, -1, "failed to deploy purchased item case 2. state:" + routerState); } break; } } /* * always pending. */ return(PurchaseProcessingResult.Pending); }
public RouterProcess(PID router, RouterState state) { _router = router; _state = state; }
public RouterProcess(ActorSystem system, RouterState state, IMailbox mailbox) : base(system, mailbox) => _state = state;
private async Task OnNewRouterStateAsync(RouterState routerState) { if (navigationPage == null) { return; } var current = navigationPage.Navigation.NavigationStack.Select(page => page.GetType()).ToList(); var desired = routerState.Stack.Select(el => pageMappings[el.ViewModelName]).ToList(); //if match do nothing if (current.SequenceEqual(desired)) { return; } var biggestCount = Math.Max(current.Count, desired.Count); var pagesToBeRemoved = new List <Page>(); var pagesToBeAdded = new List <Type>(); var pagesToBeReplaced = new Dictionary <int, Type>(); //by index FindDifference(); await ApplyDifferenceAsync(); void FindDifference() { for (int i = 0; i < biggestCount; i++) { var currentPageType = current.ElementAtOrDefault(i); var desiredPageType = desired.ElementAtOrDefault(i); //if same, do nothing if (currentPageType == desiredPageType) { continue; } //add page else if (currentPageType == null) { pagesToBeAdded.Add(desiredPageType); } //remove page else if (desiredPageType == null) { var pageToRemove = navigationPage.Navigation.NavigationStack[i]; pagesToBeRemoved.Add(pageToRemove); } //replace page else { pagesToBeReplaced.Add(i, desiredPageType); } } } async Task ApplyDifferenceAsync() { navigating = true; //replace var lastDesiredIndex = desired.Count - 1; foreach (var indexToReplace in pagesToBeReplaced.Keys) { var pageToRemove = navigationPage.Navigation.NavigationStack[indexToReplace]; var typeToAdd = pagesToBeReplaced[indexToReplace]; var pageToAdd = (Page)Activator.CreateInstance(typeToAdd); if (indexToReplace == lastDesiredIndex) { //if matches last desired page => use proper navigation navigationPage.Navigation.PushAsync(pageToAdd); //push new } else { navigationPage.Navigation.InsertPageBefore(pageToAdd, pageToRemove); } navigationPage.Navigation.RemovePage(pageToRemove); } //remove //remove middle if (pagesToBeRemoved.Count > 0) { for (int i = 0; i < pagesToBeRemoved.Count - 1; i++) { var pageToRemove = pagesToBeRemoved[i]; navigationPage.Navigation.RemovePage(pageToRemove); } //pop last await navigationPage.Navigation.PopAsync(); } //add //navigate to last page if (pagesToBeAdded.Count > 0) { var lastTypeToAdd = pagesToBeAdded[pagesToBeAdded.Count - 1]; var lastPageToAdd = (Page)Activator.CreateInstance(lastTypeToAdd); await navigationPage.Navigation.PushAsync(lastPageToAdd); //insert before for (int i = 0; i < pagesToBeAdded.Count - 1; i++) { var typeToAdd = pagesToBeAdded[i]; var pageToAdd = (Page)Activator.CreateInstance(typeToAdd); navigationPage.Navigation.InsertPageBefore(pageToAdd, lastPageToAdd); } } navigating = false; } }
public RouterActor(RouterConfig config, RouterState routerState, AutoResetEvent wg) { _config = config; _routerState = routerState; _wg = wg; }
public void Logout() { _state = new DefaultState(this); }
public void Login() { _state = new AdminState(this); }
/// <summary> /// Called when a purchase fails. /// </summary> public void OnPurchaseFailed(Product i, PurchaseFailureReason failReason) { // no retrieving product == not purchasing. if (callbacks.p == null) { // do nothing here. return; } // transactionID does not match to retrieving product's transactionID, // it's not the product which should be notice to user. if (i.transactionID != callbacks.p.transactionID) { // do nothing here. return; } /* * this purchase failed product is just retrieving purchase. */ /* * detect errors. */ var error = PurchaseError.UnityIAP_Purchase_Unknown; var reason = string.Empty; switch (failReason) { case PurchaseFailureReason.PurchasingUnavailable: { error = PurchaseError.UnityIAP_Purchase_PurchasingUnavailable; reason = "The system purchasing feature is unavailable."; break; } case PurchaseFailureReason.ExistingPurchasePending: { error = PurchaseError.UnityIAP_Purchase_ExistingPurchasePending; reason = "A purchase was already in progress when a new purchase was requested."; break; } case PurchaseFailureReason.ProductUnavailable: { error = PurchaseError.UnityIAP_Purchase_ProductUnavailable; reason = "The product is not available to purchase on the store."; break; } case PurchaseFailureReason.SignatureInvalid: { error = PurchaseError.UnityIAP_Purchase_SignatureInvalid; reason = "Signature validation of the purchase's receipt failed."; break; } case PurchaseFailureReason.UserCancelled: { error = PurchaseError.UnityIAP_Purchase_UserCancelled; reason = "The user opted to cancel rather than proceed with the purchase."; break; } case PurchaseFailureReason.PaymentDeclined: { error = PurchaseError.UnityIAP_Purchase_PaymentDeclined; reason = "There was a problem with the payment."; break; } case PurchaseFailureReason.DuplicateTransaction: { error = PurchaseError.UnityIAP_Purchase_DuplicateTransaction; reason = "A duplicate transaction error when the transaction has already been completed successfully."; break; } case PurchaseFailureReason.Unknown: { error = PurchaseError.UnityIAP_Purchase_Unknown; reason = "A catch-all for unrecognized purchase problems."; break; } } switch (routerState) { default: { // maybe never comes here. routerState = RouterState.PurchaseReady; if (callbacks.purchaseFailed != null) { callbacks.purchaseFailed(error, -1, reason); } break; } case RouterState.Purchasing: case RouterState.RetrySending: { routerState = RouterState.PurchaseReady; if (callbacks.purchaseFailed != null) { callbacks.purchaseFailed(error, -1, reason); } break; } } // set failed ticketId to log. this will be used if Paid is occured. var currentTransactionId = string.Empty; if (i != null && !string.IsNullOrEmpty(i.transactionID)) { onMemoryFailedLog[i.transactionID] = callbacks.ticketId; currentTransactionId = i.transactionID; } /* * send failed/cancelled ticketId if possible. */ var purchaseCancelledUrl = PurchaseSettings.PURCHASE_URL_CANCEL; var data = onPurchaseFailedRequest(new PurchaseFailed(callbacks.ticketId, currentTransactionId, reason)); var connectionId = PurchaseSettings.PURCHASE_CONNECTIONID_CANCEL_PREFIX + Guid.NewGuid().ToString(); var cor = HttpPost( connectionId, purchaseCancelledUrl, data, (conId, responseData) => { // do nothing. }, (conId, code, errorReason) => { // do nothing. } ); enumExecutor(cor); }
/// <summary> /// Called when a purchase fails. /// </summary> public void OnPurchaseFailed(Product i, PurchaseFailureReason failReason) { // no retrieving product == not purchasing. if (callbacks.p == null) { // do nothing here. return; } // transactionID does not match to retrieving product's transactionID, // it's not the product which should be notice to user. if (i.transactionID != callbacks.p.transactionID) { // do nothing here. return; } /* * this purchase failed product is just retrieving purchase. */ /* * detect errors. */ var error = PurchaseError.UnityIAP_Purchase_Unknown; var reason = string.Empty; switch (failReason) { case PurchaseFailureReason.PurchasingUnavailable: { error = PurchaseError.UnityIAP_Purchase_PurchasingUnavailable; reason = "The system purchasing feature is unavailable."; break; } case PurchaseFailureReason.ExistingPurchasePending: { error = PurchaseError.UnityIAP_Purchase_ExistingPurchasePending; reason = "A purchase was already in progress when a new purchase was requested."; break; } case PurchaseFailureReason.ProductUnavailable: { error = PurchaseError.UnityIAP_Purchase_ProductUnavailable; reason = "The product is not available to purchase on the store."; break; } case PurchaseFailureReason.SignatureInvalid: { error = PurchaseError.UnityIAP_Purchase_SignatureInvalid; reason = "Signature validation of the purchase's receipt failed."; break; } case PurchaseFailureReason.UserCancelled: { error = PurchaseError.UnityIAP_Purchase_UserCancelled; reason = "The user opted to cancel rather than proceed with the purchase."; break; } case PurchaseFailureReason.PaymentDeclined: { error = PurchaseError.UnityIAP_Purchase_PaymentDeclined; reason = "There was a problem with the payment."; break; } case PurchaseFailureReason.DuplicateTransaction: { error = PurchaseError.UnityIAP_Purchase_DuplicateTransaction; reason = "A duplicate transaction error when the transaction has already been completed successfully."; break; } case PurchaseFailureReason.Unknown: { error = PurchaseError.UnityIAP_Purchase_Unknown; reason = "A catch-all for unrecognized purchase problems."; break; } } switch (routerState) { default: { Debug.LogError("ここにくるケースを見切れていない2。"); if (callbacks.purchaseFailed != null) { callbacks.purchaseFailed(error, reason); } break; } case RouterState.Purchasing: { if (callbacks.purchaseFailed != null) { callbacks.purchaseFailed(error, reason); } routerState = RouterState.PurchaseReady; break; } } }
/// <summary> /// Called when a purchase completes. /// /// May be called at any time after OnInitialized(). /// </summary> public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs e) { if (callbacks.p == null) { var isValid = ValidateReceipt(e); if (isValid) { purchasedInBackground(e.purchasedProduct.definition.id); } return(PurchaseProcessingResult.Complete); } if (e.purchasedProduct.transactionID != callbacks.p.transactionID) { var isValid = ValidateReceipt(e); if (isValid) { purchasedInBackground(e.purchasedProduct.definition.id); } return(PurchaseProcessingResult.Complete); } /* * this process is the process for the purchase which this router is just retrieving. * proceed deploy asynchronously. */ switch (routerState) { case RouterState.Purchasing: { // start local validation. var isValid = ValidateReceipt(e); if (isValid) { if (callbacks.purchaseSucceeded != null) { callbacks.purchaseSucceeded(); } } else { if (callbacks.purchaseFailed != null) { callbacks.purchaseFailed(PurchaseError.InvalidReceipt, "receipt validation failed. state:" + routerState); } } routerState = RouterState.PurchaseReady; // complete anyway. nothing to do. return(PurchaseProcessingResult.Complete); } default: { if (callbacks.purchaseFailed != null) { callbacks.purchaseFailed(PurchaseError.UnknownError, "failed to deploy purchased item case 3. state:" + routerState); } break; } } /* * always pending. */ return(PurchaseProcessingResult.Pending); }