bool DoTransactionDetailsMatchPurchaseInfo(SKPaymentTransaction transaction, JsonValue purchaseInfoDict) { Console.WriteLine("DoTransactionDetailsMatchPurchaseInfo " + transaction.TransactionIdentifier); if (transaction == null || purchaseInfoDict == null) { return(false); } int failCount = 0; if (transaction.Payment.ProductIdentifier != purchaseInfoDict ["product-id"].ToString().Trim('"')) //HACK: { failCount++; } if (transaction.TransactionIdentifier != purchaseInfoDict ["transaction-id"].ToString().Trim('"')) //HACK: { failCount++; } // Optionally add more checks here... if (failCount > 0) { Console.WriteLine("IsTransactionIdUnique failed {0} tests", failCount); return(false); } return(true); }
public static InAppBillingPurchase ToIABPurchase(this SKPaymentTransaction transaction) { var p = transaction?.OriginalTransaction ?? transaction; if (p == null) { return(null); } #if __IOS__ || __TVOS__ var finalToken = p.TransactionReceipt?.GetBase64EncodedString(NSDataBase64EncodingOptions.None); if (string.IsNullOrEmpty(finalToken)) { finalToken = transaction.TransactionReceipt?.GetBase64EncodedString(NSDataBase64EncodingOptions.None); } #else var finalToken = string.Empty; #endif return(new InAppBillingPurchase { TransactionDateUtc = NSDateToDateTimeUtc(transaction.TransactionDate), Id = p.TransactionIdentifier, ProductId = p.Payment?.ProductIdentifier ?? string.Empty, State = p.GetPurchaseState(), PurchaseToken = finalToken }); }
async Task CompleteTransactionAsync(SKPaymentTransaction t) { if (t == null) { return; } if (t.TransactionState == SKPaymentTransactionState.Failed) { Console.WriteLine("STORE ERROR CompleteTransaction: {0} {1} {2}", t.TransactionState, t.TransactionIdentifier, t.TransactionDate); foreach (var a in FailActions) { await a(t); } } else { Console.WriteLine("STORE CompleteTransaction: {0} {1} {2} {3}", t.Payment.ProductIdentifier, t.TransactionState, t.TransactionIdentifier, t.TransactionDate); foreach (var a in CompletionActions) { await a(t); } } Console.WriteLine("STORE FinishTransaction()"); SKPaymentQueue.DefaultQueue.FinishTransaction(t); }
public void RestoreTransaction(SKPaymentTransaction transaction) { var productId = transaction.OriginalTransaction.Payment.ProductIdentifier; AdViewController.Purchase(productId); FinishTransaction(transaction, true); }
// /// <summary> // /// Indicates whether this transaction has any downloads. // /// </summary> // [Obsolete("Use the hasDownloads property.")] // public readonly bool HasDownloads = false; /// <summary> /// Initializes a new instance of the <see cref="U3DXT.iOS.IAP.TransactionEventArgs"/> class. /// </summary> /// <param name="transaction">Transaction.</param> /// <param name="error">Error.</param> public TransactionEventArgs(SKPaymentTransaction transaction, NSError error = null) { this.transaction = transaction; try { hasDownloads = (transaction.downloads != null); } catch (Exception) { } if (error != null) { this.error = error; } else { this.error = transaction.error; } if ((transaction.transactionState == SKPaymentTransactionState.Restored) && (transaction.originalTransaction != null)) { transaction = transaction.originalTransaction; } productID = transaction.payment.productIdentifier; quantity = transaction.payment.quantity; // this.HasDownloads = this.hasDownloads; // this.Error = this.error; // this.ProductID = this.productID; // this.Quantity = this.quantity; }
// called when the transaction status is updated public override void UpdatedTransactions (SKPaymentQueue queue, SKPaymentTransaction[] transactions) { Console.WriteLine ("Updating Transactions in Custom Payment Observer"); foreach (SKPaymentTransaction transaction in transactions) { switch (transaction.TransactionState) { case SKPaymentTransactionState.Purchased: theManager.CompleteTransaction (transaction); Console.WriteLine ("purchased status"); break; case SKPaymentTransactionState.Failed: theManager.FailedTransaction (transaction); Console.WriteLine ("failed status"); break; case SKPaymentTransactionState.Restored: theManager.RestoreTransaction (transaction); Console.WriteLine ("restored status"); break; default: Console.WriteLine ("other status"); break; } } }
public void FinishTransaction(SKPaymentTransaction transaction, bool wasSuccessful) { try { Logger.Log("FinishTransaction thread: " + System.Threading.Thread.CurrentThread.Name + " ID:" + System.Threading.Thread.CurrentThread.ManagedThreadId); Logger.Log("Finishing Transaction..."); // remove the transaction from the payment queue. THIS IS IMPORTANT - LET'S APPLE KNOW WE'RE DONE !!!! SKPaymentQueue.DefaultQueue.FinishTransaction(transaction); Logger.Log("Transaction Finished!"); using (var pool = new NSAutoreleasePool()) { NSDictionary userInfo = NSDictionary.FromObjectsAndKeys(new NSObject[] { transaction }, new NSObject[] { new NSString("transaction") }); if (wasSuccessful) { NSNotificationCenter.DefaultCenter.PostNotificationName(InAppPurchaseManagerTransactionSucceededNotification, this, userInfo); } else { NSNotificationCenter.DefaultCenter.PostNotificationName(InAppPurchaseManagerTransactionFailedNotification, this, userInfo); } } } catch (Exception ex) { Logger.Log("ERROR: FinishTransaction: " + ex); } }
public static PurchaseState GetPurchaseState(this SKPaymentTransaction transaction) { if (transaction?.TransactionState == null) { return(PurchaseState.Unknown); } switch (transaction.TransactionState) { case SKPaymentTransactionState.Restored: return(PurchaseState.Restored); case SKPaymentTransactionState.Purchasing: return(PurchaseState.Purchasing); case SKPaymentTransactionState.Purchased: return(PurchaseState.Purchased); case SKPaymentTransactionState.Failed: return(PurchaseState.Failed); case SKPaymentTransactionState.Deferred: return(PurchaseState.Deferred); } return(PurchaseState.Unknown); }
private void RestoreTransaction(SKPaymentTransaction transaction) { var productId = transaction.OriginalTransaction.Payment.ProductIdentifier;; _defaultValueService.Set(productId, true); OnPurchaseSuccess(transaction.OriginalTransaction.Payment); }
// /// <summary> // /// Indicates whether this transaction has any downloads. // /// </summary> // [Obsolete("Use the hasDownloads property.")] // public readonly bool HasDownloads = false; /// <summary> /// Initializes a new instance of the <see cref="U3DXT.iOS.IAP.TransactionEventArgs"/> class. /// </summary> /// <param name="transaction">Transaction.</param> /// <param name="error">Error.</param> public TransactionEventArgs(SKPaymentTransaction transaction, NSError error = null) { this.transaction = transaction; try { hasDownloads = (transaction.downloads != null); } catch (Exception) { } if (error != null) this.error = error; else this.error = transaction.error; if ((transaction.transactionState == SKPaymentTransactionState.Restored) && (transaction.originalTransaction != null)) { transaction = transaction.originalTransaction; } productID = transaction.payment.productIdentifier; quantity = transaction.payment.quantity; // this.HasDownloads = this.hasDownloads; // this.Error = this.error; // this.ProductID = this.productID; // this.Quantity = this.quantity; }
public override async void UpdatedTransactions (SKPaymentQueue queue, SKPaymentTransaction[] transactions) { if (transactions == null) return; try { foreach (var t in transactions) { try { Console.WriteLine ("STORE Transaction: {0} {1} {2} {3} {4}", t.Payment.ProductIdentifier, t.TransactionState, t.TransactionIdentifier, t.TransactionDate, t.Error); switch (t.TransactionState) { case SKPaymentTransactionState.Purchased: productsPurchased.Add (t); await CompleteTransactionAsync (t); break; case SKPaymentTransactionState.Restored: productsRestored.Add (t); await CompleteTransactionAsync (t); break; case SKPaymentTransactionState.Failed: await CompleteTransactionAsync (t); break; } } catch (Exception ex) { Log.Error (ex); } } } catch (Exception ex) { Log.Error (ex); } }
public void RestoreTransaction(SKPaymentTransaction transaction) { // Restored Transactions always have an 'original transaction' attached var productId = transaction.OriginalTransaction.Payment.ProductIdentifier; // Record the restore var newPurchase = new InAppPurchase { OrderId = transaction.OriginalTransaction.TransactionIdentifier, ProductId = transaction.OriginalTransaction.Payment.ProductIdentifier, PurchaseTime = NSDateToDateTime(transaction.OriginalTransaction.TransactionDate) }; App.ViewModel.Purchases.Add(newPurchase); // Remove the transaction from the payment queue. // IMPORTANT: Let's ios know we're done SKPaymentQueue.DefaultQueue.FinishTransaction(transaction); // Send out a notification that we’ve finished the transaction using (var pool = new NSAutoreleasePool()) { NSDictionary userInfo = NSDictionary.FromObjectsAndKeys(new NSObject[] { transaction }, new NSObject[] { new NSString("transaction") }); NSNotificationCenter.DefaultCenter.PostNotificationName(InAppRestoreProductsNotification, this, userInfo); } }
private void FailedTransaction(SKPaymentTransaction transaction) { SKPaymentQueue.DefaultQueue.FinishTransaction(transaction); var errorString = transaction.Error != null ? transaction.Error.LocalizedDescription : "Unable to process transaction!"; OnPurchaseError(new Exception(errorString)); }
void PurchaseSuccessCallback(SKPaymentTransaction transaction, InAppProduct product) { if (product.ProductIdentifier == Constants.PURCHASE_ID[(int)Constants.PURCHASE_TYPE.VIEW]) { ViewDropDetail(); } }
/// <summary> /// Called when the transaction status is updated /// </summary> public override void UpdatedTransactions (SKPaymentQueue queue, SKPaymentTransaction[] transactions) { Console.WriteLine ("UpdatedTransactions"); foreach (SKPaymentTransaction transaction in transactions) { switch (transaction.TransactionState) { case SKPaymentTransactionState.Purchased: if (transaction.Downloads != null && transaction.Downloads.Length > 0) { // complete the transaction AFTER downloading SKPaymentQueue.DefaultQueue.StartDownloads (transaction.Downloads); } else { // complete the transaction now theManager.CompleteTransaction(transaction); } break; case SKPaymentTransactionState.Failed: theManager.FailedTransaction(transaction); break; case SKPaymentTransactionState.Restored: theManager.RestoreTransaction(transaction); break; default: break; } } }
public void CompleteTransaction(SKPaymentTransaction transaction) { Console.WriteLine("CompleteTransaction {0}", transaction.TransactionIdentifier); string productId = transaction.Payment.ProductIdentifier; FinishTransaction(transaction, true); }
// // saves a record of the transaction by storing the receipt to disk // public void recordTransaction(SKPaymentTransaction transaction) { if (transaction.Payment.ProductIdentifier == InAppPurchaseProUpgradeProductId) { NSUserDefaults.StandardUserDefaults.SetNativeField("proUpgradeTransactionReceipt", transaction.TransactionReceipt); NSUserDefaults.StandardUserDefaults.Synchronize(); } }
private void CompleteTransaction(SKPaymentTransaction transaction) { var productId = transaction.Payment.ProductIdentifier; _defaultValueService.Set(productId, true); Console.WriteLine("CompleteTransaction " + productId); OnPurchaseSuccess(transaction.Payment); }
public void CompleteTransaction(SKPaymentTransaction transaction) { Console.WriteLine("CompleteTransaction " + transaction.TransactionIdentifier); var productId = transaction.Payment.ProductIdentifier; // Register the purchase, so it is remembered for next time PhotoFilterManager.Purchase(productId); FinishTransaction(transaction, true); }
public void FailedTransaction (SKPaymentTransaction transaction) { //SKErrorPaymentCancelled == 2 string errorDescription = transaction.Error.Code == 2 ? "User CANCELLED FailedTransaction" : "FailedTransaction"; Console.WriteLine("{0} Code={1} {2}", errorDescription, transaction.Error.Code, transaction.Error.LocalizedDescription); FinishTransaction(transaction, false); }
public void FailedTransaction(SKPaymentTransaction transaction) { //SKErrorPaymentCancelled == 2 // string errorDescription = transaction.Error.Code == 2 ? "User CANCELLED FailedTransaction" : "FailedTransaction"; // Console.WriteLine("{0} Code={1} {2}", errorDescription, transaction.Error.Code, transaction.Error.LocalizedDescription); FinishTransaction(transaction, false); }
private static void _OnFailedBuy(SKPaymentTransaction transaction, NSError error = null) { if (_transactionFailedHandlers != null) { _transactionFailedHandlers(null, new TransactionEventArgs(transaction, error)); } _FinishTransaction(transaction); }
public void CompleteTransaction (SKPaymentTransaction transaction) { Console.WriteLine ("CompleteTransaction {0}" + transaction.TransactionIdentifier); string productId = transaction.Payment.ProductIdentifier; // Register the purchase, so it is remembered for next time CompleteTransaction (productId); FinishTransaction (transaction, true); }
public void CompleteTransaction(SKPaymentTransaction transaction) { Console.WriteLine("CompleteTransaction {0}", transaction.TransactionIdentifier); string productId = transaction.Payment.ProductIdentifier; // Register the purchase, so it is remembered for next time CompleteTransaction(productId); FinishTransaction(transaction, true); }
public virtual void RestoreTransaction(SKPaymentTransaction transaction) { // Restored Transactions always have an 'original transaction' attached Console.WriteLine("RestoreTransaction {0}; OriginalTransaction {1}", transaction.TransactionIdentifier, transaction.OriginalTransaction.TransactionIdentifier); string productId = transaction.OriginalTransaction.Payment.ProductIdentifier; // Register the purchase, so it is remembered for next time RestoreTransaction(productId); FinishTransaction(transaction, true); }
public virtual void RestoreTransaction(SKPaymentTransaction transaction) { // Restored Transactions always have an 'original transaction' attached Console.WriteLine("RestoreTransaction {0}; OriginalTransaction {1}", transaction.TransactionIdentifier, transaction.OriginalTransaction.TransactionIdentifier); //string productId = transaction.OriginalTransaction.Payment.ProductIdentifier; IAP.ProcessRestoredItem(transaction); //UtilsIOS.ShowToast("Restored", UIColor.Green, 5.0f); //AppDelegate.Restore(productId); FinishTransaction(transaction, true); }
public void FinishTransaction(SKPaymentTransaction transaction, bool wasSuccessful) { Console.WriteLine ("FinishTransaction {0}", wasSuccessful); // remove the transaction from the payment queue. SKPaymentQueue.DefaultQueue.FinishTransaction (transaction); // THIS IS IMPORTANT - LET'S APPLE KNOW WE'RE DONE !!!! NSDictionary userInfo = new NSDictionary ("transaction", transaction); var notificationKey = wasSuccessful ? InAppPurchaseManagerTransactionSucceededNotification : InAppPurchaseManagerTransactionFailedNotification; NSNotificationCenter.DefaultCenter.PostNotificationName (notificationKey, this, userInfo); }
public void FailedTransaction(SKPaymentTransaction transaction) { //SKErrorPaymentCancelled == 2 if (transaction.Error.Code == 2) // user cancelled Console.WriteLine("User CANCELLED FailedTransaction Code=" + transaction.Error.Code + " " + transaction.Error.LocalizedDescription); else // error! Console.WriteLine("FailedTransaction Code=" + transaction.Error.Code + " " + transaction.Error.LocalizedDescription); FinishTransaction(transaction,false); }
public void RestoreTransaction(SKPaymentTransaction transaction) { // Restored Transactions always have an 'original transaction' attached Console.WriteLine("RestoreTransaction " + transaction.TransactionIdentifier + "; OriginalTransaction " + transaction.OriginalTransaction.TransactionIdentifier); var productId = transaction.OriginalTransaction.Payment.ProductIdentifier; // Register the purchase, so it is remembered for next time PhotoFilterManager.Purchase(productId); // it's as though it was purchased again FinishTransaction(transaction, true); }
// private void DidReceiveData (object sender, UploadDataCompletedEventArgs e) // { // Console.WriteLine ("DidReceiveData"); // if (e.Result == null | e.Cancelled) { // Console.WriteLine ("DidReceiveData failed " + e.Error.Message); // } else { // var responseString = System.Text.Encoding.UTF8.GetString(e.Result); // Console.WriteLine ("VerificationController-response string:" +responseString); // bool isOK = DoesTransactionInfoMatchReceipt (responseString); // } // // required: some sort of callback to the purchase manager // } #endregion bool IsTransactionAndItsReceiptValid(SKPaymentTransaction transaction) { if (!(transaction != null && transaction.TransactionReceipt != null && transaction.TransactionReceipt.Length > 0)) { return(false); // transaction is not valid } // Pull the purchase info out, and save it in the dictionary for // later in the verification stage var receiptDict = JsonValue.Parse(transaction.TransactionReceipt.ToString().Replace(" = ", " : ")); //HACK: var transactionPurchaseInfo = receiptDict["purchase-info"].ToString(); var decodedPurchaseInfo = DecodeBase64(transactionPurchaseInfo); var purchaseInfoDict = JsonValue.Parse(decodedPurchaseInfo.ToString().Replace(" = ", " : ")); //HACK: var transactionId = purchaseInfoDict["transaction-id"].ToString().Trim('"'); //HACK: var purchaseDateString = purchaseInfoDict["purchase-date"].ToString().Trim('"'); //HACK: var signature = receiptDict["signature"].ToString(); Console.WriteLine("IsTransactionAndItsReceiptValid? {0}, {1}", transactionId, purchaseDateString); var dateFormat = "yyyy-MM-dd HH:mm:ss GMT"; purchaseDateString = purchaseDateString.Replace("Etc/", ""); var purchaseDate = DateTime.ParseExact(purchaseDateString, dateFormat, System.Globalization.CultureInfo.InvariantCulture); if (!IsTransactionIdUnique(transactionId)) { return(false); // we've seen this transaction before } // HACK: this hasn't been implemented in MonoTouch yet var result = CheckReceiptSecurity(transactionPurchaseInfo, signature, purchaseDate); if (!result) { return(false); } if (!DoTransactionDetailsMatchPurchaseInfo(transaction, purchaseInfoDict)) { return(false); } // remember that we've seen it SaveTransactionId(transactionId); // save for future reference transactionsReceiptStorageDictionary.SetValueForKey(new NSString(purchaseInfoDict.ToString()), new NSString(transactionId)); return(true); }
private void RestoreTransaction(SKPaymentTransaction transaction) { var productId = transaction?.OriginalTransaction?.Payment?.ProductIdentifier; if (productId == null) { throw new Exception("Unable to restore transaction as iTunes returned an empty product identifier!"); } _defaultValueService.Set(productId, true); }
void PurchaseSuccessCallback(SKPaymentTransaction transaction, InAppProduct product) { if (product.ProductIdentifier == Constants.PURCHASE_ID[(int)Constants.PURCHASE_TYPE.DROP]) { CreateDrop(ItemModel.parseItem); } else if (product.ProductIdentifier == Constants.PURCHASE_ID[(int)Constants.PURCHASE_TYPE.EXPIRY]) { SetNoExpiry(); } }
public void FinishTransaction(SKPaymentTransaction transaction, bool wasSuccessful) { Console.WriteLine("FinishTransaction {0}", wasSuccessful); // remove the transaction from the payment queue. SKPaymentQueue.DefaultQueue.FinishTransaction(transaction); // THIS IS IMPORTANT - LET'S APPLE KNOW WE'RE DONE !!!! NSDictionary userInfo = new NSDictionary("transaction", transaction); var notificationKey = wasSuccessful ? InAppPurchaseManagerTransactionSucceededNotification : InAppPurchaseManagerTransactionFailedNotification; NSNotificationCenter.DefaultCenter.PostNotificationName(notificationKey, this, userInfo); }
private void CompleteTransaction(SKPaymentTransaction transaction) { var productId = transaction?.Payment?.ProductIdentifier; if (productId == null) { throw new Exception("Unable to complete transaction as iTunes returned an empty product identifier!"); } CrossSettings.Current.AddOrUpdateValue(productId, true); _actionSource?.TrySetResult(true); }
private void CompleteTransaction(SKPaymentTransaction transaction) { var productId = transaction?.Payment?.ProductIdentifier; if (productId == null) { throw new Exception("Unable to complete transaction as iTunes returned an empty product identifier!"); } _defaultValueService.Set(productId, true); _actionSource?.TrySetResult(true); }
public virtual void RestoreTransaction(SKPaymentTransaction transaction) { // Restored Transactions always have an 'original transaction' attached Console.WriteLine("RestoreTransaction {0}; OriginalTransaction {1}", transaction.TransactionIdentifier, transaction.OriginalTransaction.TransactionIdentifier); string productId = transaction.OriginalTransaction.Payment.ProductIdentifier; if (OnRestoreTransaction != null) { OnRestoreTransaction(this, null); } FinishTransaction(transaction, true); }
public static string ProcessRestoredItem(SKPaymentTransaction transaction) { string restoredID = transaction.Payment.ProductIdentifier; Console.WriteLine(" ** RESTORING {0} ", restoredID); bool restored = transaction.TransactionState == SKPaymentTransactionState.Restored; if (!restored) { return(""); } return(restoredID); }
public void CompleteTransaction(SKPaymentTransaction transaction) { Console.WriteLine("CompleteTransaction " + transaction.TransactionIdentifier); var productId = transaction.Payment.ProductIdentifier; if (productId == ConsumableViewController.Buy5ProductId) CreditManager.Add(5); else if (productId == ConsumableViewController.Buy10ProductId) CreditManager.Add(10); else Console.WriteLine ("Shouldn't happen, there are only two products"); FinishTransaction(transaction, true); }
// // called when a transaction has failed // public void failedTransaction(SKPaymentTransaction transaction) { //SKErrorPaymentCancelled == 2 if (transaction.Error.Code != 2) { // error! this.finishTransaction(transaction,false); } else { // this is fine, the user just cancelled, so don’t notify SKPaymentQueue.DefaultQueue.FinishTransaction(transaction); } }
partial void VerifyTransaction(NSObject sender) { // You MUST obtain the SKPaymentTransaction here // That you want to validate against Beeblex Service SKPaymentTransaction skTrans = new SKPaymentTransaction(); // Initialize your BBXIAPTransaction with the SKPaymentTransaction you got // If you do not provide a Valid SKPaymentTransaction you will get a // MonoTouch.Foundation.MonoTouchException // Because you need a transaction that is either purchased or restored. BBXIAPTransaction bbxTransaction = new BBXIAPTransaction(skTrans); // Here the you validate the SKPaymentTransaction. bbxTransaction.Validate((error) => { if (bbxTransaction.TransactionVerified) { if (bbxTransaction.TransactionIsDuplicate) { // The transaction is valid, but duplicate - it has already been // sent to Beeblex in the past. // Do Something Here } else { // The transaction has been successfully validated // and is unique. // Do Something Here } } else { // Check whether this is a validation error, or if something // went wrong with Beeblex. // Do Something Here if (bbxTransaction.HasServerError) { // The error was not caused by a problem with the data, but is // most likely due to some transient networking issues. // Do Something Here } else { // The transaction supplied to the validation service was not valid according to Apple. // Do Something Here } } }); }
public override void UpdatedTransactions(SKPaymentQueue queue, SKPaymentTransaction[] transactions) { foreach (var transaction in transactions) { switch (transaction.TransactionState) { case SKPaymentTransactionState.Purchased: case SKPaymentTransactionState.Restored: OnTransactionPurchased(transaction); break; case SKPaymentTransactionState.Failed: OnTransactionFailed(transaction); break; } } }
// // removes the transaction from the queue and posts a notification with the transaction result // public void finishTransaction(SKPaymentTransaction transaction, bool wasSuccessful) { // remove the transaction from the payment queue. SKPaymentQueue.DefaultQueue.FinishTransaction(transaction); NSDictionary userInfo = NSDictionary.FromObjectsAndKeys(new NSObject[] {transaction},new NSObject[] { new NSString("transaction")}); if(wasSuccessful) { // send out a notification that we’ve finished the transaction NSNotificationCenter.DefaultCenter.PostNotificationName(InAppPurchaseManagerTransactionSucceededNotification,this,userInfo); } else { // send out a notification for the failed transaction NSNotificationCenter.DefaultCenter.PostNotificationName(InAppPurchaseManagerTransactionFailedNotification,this,userInfo); } }
public void FinishTransaction(SKPaymentTransaction transaction, bool wasSuccessful) { Console.WriteLine("FinishTransaction " + wasSuccessful); // remove the transaction from the payment queue. SKPaymentQueue.DefaultQueue.FinishTransaction(transaction); // THIS IS IMPORTANT - LET'S APPLE KNOW WE'RE DONE !!!! using (var pool = new NSAutoreleasePool()) { NSDictionary userInfo = NSDictionary.FromObjectsAndKeys(new NSObject[] {transaction},new NSObject[] {new NSString("transaction")}); if (wasSuccessful) { // send out a notification that we’ve finished the transaction NSNotificationCenter.DefaultCenter.PostNotificationName(InAppPurchaseManagerTransactionSucceededNotification,this,userInfo); } else { // send out a notification for the failed transaction NSNotificationCenter.DefaultCenter.PostNotificationName(InAppPurchaseManagerTransactionFailedNotification,this,userInfo); } } }
public void CompleteTransaction (SKPaymentTransaction transaction) { Console.WriteLine ("CompleteTransaction " + transaction.TransactionIdentifier); var productId = transaction.Payment.ProductIdentifier; // Register the purchase, so it is remembered for next time PhotoFilterManager.Purchase(productId); FinishTransaction (transaction, true); /* if (ReceiptValidation.VerificationController.SharedInstance.VerifyPurchase (transaction)) { Console.WriteLine ("Verified!"); // Register the purchase, so it is remembered for next time PhotoFilterManager.Purchase(productId); FinishTransaction (transaction, true); } else { Console.WriteLine ("NOT Verified :("); FinishTransaction (transaction, false); } */ }
async Task CompleteTransactionAsync (SKPaymentTransaction t) { if (t == null) return; if (t.TransactionState == SKPaymentTransactionState.Failed) { Console.WriteLine ("STORE ERROR CompleteTransaction: {0} {1} {2}", t.TransactionState, t.TransactionIdentifier, t.TransactionDate); foreach (var a in FailActions) { await a (t); } } else { Console.WriteLine ("STORE CompleteTransaction: {0} {1} {2} {3}", t.Payment.ProductIdentifier, t.TransactionState, t.TransactionIdentifier, t.TransactionDate); foreach (var a in CompletionActions) { await a (t); } } Console.WriteLine ("STORE FinishTransaction()"); SKPaymentQueue.DefaultQueue.FinishTransaction (t); }
// called when the transaction status is updated public override void UpdatedTransactions(SKPaymentQueue queue, SKPaymentTransaction[] transactions) { Console.WriteLine("UpdatedTransactions"); foreach (SKPaymentTransaction transaction in transactions) { switch (transaction.TransactionState) { case SKPaymentTransactionState.Purchased: theManager.CompleteTransaction(transaction); break; case SKPaymentTransactionState.Failed: theManager.FailedTransaction(transaction); break; case SKPaymentTransactionState.Restored: theManager.RestoreTransaction(transaction); break; default: break; } } }
/// <summary> /// Called once transaction gets to SKPaymentTransactionState.Purchased /// or SKPaymentTransactionState.Restored (StoreKit has called UpdatedTransactions) /// </summary> /// <returns> /// <c>true</c>, if verification is okay, <c>false</c> if there was a problem. /// </returns> public bool VerifyPurchase (SKPaymentTransaction transaction) { Console.WriteLine ("VerifyPurchase " + transaction.TransactionIdentifier); if (ITC_CONTENT_PROVIDER_SHARED_SECRET == "") throw new NotImplementedException("Shared secret has not been specified at ITC_CONTENT_PROVIDER_SHARED_SECRET"); bool isOK = IsTransactionAndItsReceiptValid (transaction); if (!isOK) // something wrong with transaction return isOK; var jsonObjectString = EncodeBase64 (transaction.TransactionReceipt.ToString ()); var payload = @"{""receipt-data"" : """+jsonObjectString+@""", ""password"" : """+ITC_CONTENT_PROVIDER_SHARED_SECRET+@"""}"; // Use ITMS_SANDBOX_VERIFY_RECEIPT_URL while testing against the sandbox. var serverURL = ITMS_SANDBOX_VERIFY_RECEIPT_URL; //ITMS_PROD_VERIFY_RECEIPT_URL; Console.WriteLine ("VerifyPurchase payload " + payload); // using .NET WebClient rather than NSURLConnection, so no trust validation... WebClient client = new WebClient(); // Earlier port used async, was hard to keep the SKPaymentTransaction around to call Finish on later... //client.UploadDataCompleted += DidReceiveData; //client.UploadDataAsync (new Uri(serverURL), null,System.Text.Encoding.UTF8.GetBytes (payload), null); try { // make it synchronous var response = client.UploadData (serverURL, System.Text.Encoding.UTF8.GetBytes (payload)); // ...and wait... var responseString = System.Text.Encoding.UTF8.GetString(response); Console.WriteLine ("VerificationController response string:" +responseString); isOK = DoesTransactionInfoMatchReceipt (responseString); } catch (System.Net.WebException e) { Console.WriteLine ("VerifyPurchase failed" + e.Message); isOK = false; } return isOK; }
// called when the transaction status is updated public override void UpdatedTransactions (SKPaymentQueue queue, SKPaymentTransaction[] transactions) { Console.WriteLine ("UpdatedTransactions"); foreach (SKPaymentTransaction transaction in transactions) { switch (transaction.TransactionState) { case SKPaymentTransactionState.Purchased: theManager.CompleteTransaction(transaction); break; case SKPaymentTransactionState.Failed: theManager.FailedTransaction(transaction); break; // Consumable products do not get Restored, so this is not implemented in this sample. // case SKPaymentTransactionState.Restored: // theManager.RestoreTransaction(transaction); // break; default: break; } } }
public void FailedTransaction(SKPaymentTransaction transaction) { //SKErrorPaymentCancelled == 2 if (transaction.Error.Code == 2) // user cancelled { Debug.WriteLine("User CANCELLED FailedTransaction Code=" + transaction.Error.Code + " " + transaction.Error.LocalizedDescription); } else // error! { Debug.WriteLine("FailedTransaction Code=" + transaction.Error.Code + " " + transaction.Error.LocalizedDescription); } // Remove the transaction from the payment queue. // IMPORTANT: Let's ios know we're done SKPaymentQueue.DefaultQueue.FinishTransaction(transaction); // Send out a notification for the failed transaction using (var pool = new NSAutoreleasePool()) { NSDictionary userInfo = NSDictionary.FromObjectsAndKeys(new NSObject[] { transaction }, new NSObject[] { new NSString("transaction") }); NSNotificationCenter.DefaultCenter.PostNotificationName(InAppPurchaseProductErrorNotification, this, userInfo); } }
public virtual void RestoreTransaction (SKPaymentTransaction transaction) { // Restored Transactions always have an 'original transaction' attached Console.WriteLine("RestoreTransaction {0}; OriginalTransaction {1}",transaction.TransactionIdentifier, transaction.OriginalTransaction.TransactionIdentifier); string productId = transaction.OriginalTransaction.Payment.ProductIdentifier; // Register the purchase, so it is remembered for next time RestoreTransaction (productId); FinishTransaction(transaction, true); }
private static void _FinishTransaction(SKPaymentTransaction transaction) { SKPaymentQueue.DefaultQueue().FinishTransaction(transaction); _HideActivityIndicator(); }
private void FailedTransaction (SKPaymentTransaction transaction) { SKPaymentQueue.DefaultQueue.FinishTransaction(transaction); var errorString = transaction.Error != null ? transaction.Error.LocalizedDescription : "Unable to process transaction!"; OnPurchaseError(new Exception(errorString)); }
private static void _OnBought(SKPaymentTransaction transaction) { if ((transaction.payment != null) && (transaction.payment.productIdentifier != null)) { _boughtProducts.Add(transaction.payment.productIdentifier); _WriteCache(); if (_transactionCompletedHandlers != null) _transactionCompletedHandlers(null, new TransactionEventArgs(transaction)); } _FinishTransaction(transaction); }
private static bool _HasFinishedDownloads(SKPaymentTransaction transaction) { foreach (var downloadObj in transaction.downloads) { var download = downloadObj as SKDownload; if ((download.downloadState == SKDownloadState.Active) || (download.downloadState == SKDownloadState.Paused) || (download.downloadState == SKDownloadState.Waiting)) { return false; } } return true; }
private static void _OnFailedBuy(SKPaymentTransaction transaction, NSError error = null) { if (_transactionFailedHandlers != null) _transactionFailedHandlers(null, new TransactionEventArgs(transaction, error)); _FinishTransaction(transaction); }
private void FailedTransaction (SKPaymentTransaction transaction) { var errorString = transaction.Error != null ? transaction.Error.LocalizedDescription : "Unable to process transaction!"; OnPurchaseError(transaction.Payment, new Exception(errorString)); }
public override void UpdatedTransactions(SKPaymentQueue queue, SKPaymentTransaction[] transactions) { foreach (SKPaymentTransaction transaction in transactions) { try { switch (transaction.TransactionState) { case SKPaymentTransactionState.Purchased: _inAppPurchases.CompleteTransaction(transaction); SKPaymentQueue.DefaultQueue.FinishTransaction(transaction); break; case SKPaymentTransactionState.Failed: _inAppPurchases.FailedTransaction(transaction); SKPaymentQueue.DefaultQueue.FinishTransaction(transaction); break; case SKPaymentTransactionState.Restored: _inAppPurchases.RestoreTransaction(transaction); SKPaymentQueue.DefaultQueue.FinishTransaction(transaction); break; default: break; } } catch (Exception e) { _inAppPurchases._errorSubject.OnNext(e); } } }
public void RestoreTransaction(SKPaymentTransaction transaction) { // Restored Transactions always have an 'original transaction' attached Console.WriteLine("RestoreTransaction " + transaction.TransactionIdentifier + "; OriginalTransaction " + transaction.OriginalTransaction.TransactionIdentifier); var productId = transaction.OriginalTransaction.Payment.ProductIdentifier; // Register the purchase, so it is remembered for next time HostedProductManager.Purchase(productId); // it's as though it was purchased again FinishTransaction(transaction, true); }
private void RestoreTransaction (SKPaymentTransaction transaction) { var productId = transaction.OriginalTransaction.Payment.ProductIdentifier;; _defaultValueService.Set(productId, true); Console.WriteLine("RestoreTransaction " + productId); OnPurchaseSuccess(transaction.OriginalTransaction.Payment); }