/// <summary> /// Hack to prevent "Unable to cast object of type 'Microsoft.Owin.FormCollection' /// to type 'Microsoft.Owin.IFormCollection'" exception, when internalized version /// does not match the current project's one. /// </summary> public static async Task<IFormCollection> ReadFormSafeAsync(this IOwinContext context) { var inputStream = context.Request.Body; var t = inputStream.GetType(); //var disableBuffering = t.GetMethod("DisableBuffering",BindingFlags.NonPublic | BindingFlags.Instance); //disableBuffering.Invoke(context.Request.Body, null); //var f_stream = t.GetField("_stream",BindingFlags.NonPublic | BindingFlags.Instance); //var _stream = (Stream) f_stream.GetValue(inputStream); var f_request = t.GetField("_request",BindingFlags.NonPublic | BindingFlags.Instance); var _request = (HttpRequestBase) f_request.GetValue(inputStream); var dic = new Dictionary<string, string[]>(); foreach (var k in _request.Form.AllKeys) { var v = _request.Form.Get(k); var values_array = v.Split(','); dic.Add(k, values_array); } var form = new FormCollection(dic); return form; }
protected override void ProcessContext(object context) { var ctx = (IOwinContext) context; IFormCollection forms = null; if (string.Equals(ctx.Request.Method, "post", StringComparison.OrdinalIgnoreCase)) { var task = ctx.Request.ReadFormAsync(); task.Wait(); forms = task.Result; } else { forms = new FormCollection(new Dictionary<string, string[]>()); } foreach (var i in forms) { Dobj.Set(Forms, i.Key, i.Value); } foreach (var i in ctx.Request.Cookies) { Dobj.Set(Cookies, i.Key, i.Value); } Headers = new Dobj(); foreach (var i in ctx.Request.Headers.Keys) { Dobj.Set(Headers, i, ctx.Request.Headers[i]); } Body = ctx.Request.Body; ContentType = ctx.Request.ContentType; Url = new RequestUrl(ctx.Request.Uri); }
public IHttpActionResult ProcessPayment(FormCollection parameters) { //first get the payment processor var paymentMethodName = parameters.Get(PaymentParameterNames.PaymentMethodTypeName); if (string.IsNullOrEmpty(paymentMethodName)) { VerboseReporter.ReportError("Invalid payment method", "process_payment"); return RespondFailure(); } //the transaction amount decimal amount; var amountString = parameters.Get(PaymentParameterNames.Amount) ?? "0"; decimal.TryParse(amountString, out amount); PaymentMethodType methodType; if (System.Enum.TryParse(paymentMethodName, out methodType)) { methodType = PaymentMethodType.CreditCard; } //get the payment processor now var paymentProcessor = _paymentProcessingService.GetPaymentProcessorPlugin(amount, methodType); if (paymentProcessor == null) { VerboseReporter.ReportError("Invalid payment method", "process_payment"); return RespondFailure(); } //convert form collection to dictionary to check if parameters are valid var formCollectionDictionary = parameters.ToDictionary(pair => pair.Key, pair => (object)pair.Value); var isValid = paymentProcessor.AreParametersValid(formCollectionDictionary); UserPaymentMethod paymentMethod = null; if (!isValid) { //the parameters are not valid. but that may also mean that the user is selecting an already saved payment method //and so he wouldn't have sent that data again var savedPaymentMethodIdString = parameters.Get(PaymentParameterNames.UserSavedPaymentMethodId); int savedPaymentMethodId; if (int.TryParse(savedPaymentMethodIdString, out savedPaymentMethodId)) { var userPaymentMethods = _paymentMethodService.Get(x => x.UserId == ApplicationContext.Current.CurrentUser.Id && x.Id == savedPaymentMethodId, null); if (userPaymentMethods.Any()) { paymentMethod = userPaymentMethods.First(); isValid = true; } } //still invalid? something is not right then. if (!isValid) { VerboseReporter.ReportError("Invalid parameters to process payment", "process_payment"); return RespondFailure(); } } //we save the payment method in our database if it's CreditCard if (paymentProcessor.Supports(PaymentMethodType.CreditCard)) { if (paymentMethod == null) { #region saving payment method to database var creditCardNumber = parameters.Get(PaymentParameterNames.CardNumber); //let's validate the card for level 1 check (luhn's test) first before storing var isCardValid = PaymentCardHelper.IsCardNumberValid(creditCardNumber); //card number if (!isCardValid) { VerboseReporter.ReportError("Invalid card number", "process_payment"); return RespondFailure(); } //expiration date var expireMonth = parameters.Get(PaymentParameterNames.ExpireMonth); var expireYear = parameters.Get(PaymentParameterNames.ExpireYear); if (!expireYear.IsInteger() || !expireMonth.IsInteger()) { VerboseReporter.ReportError("Invalid expiration month or year", "process_payment"); return RespondFailure(); } //card issuer var cardIssuer = PaymentCardHelper.GetCardTypeFromNumber(creditCardNumber); if (!cardIssuer.HasValue) { VerboseReporter.ReportError("Unsupported card provider", "process_payment"); return RespondFailure(); } var nameOnCard = parameters.Get(PaymentParameterNames.NameOnCard); //encrypt credit card info to store in db var key = ConfigurationManager.AppSettings.Get("EncryptionKey"); var salt = ConfigurationManager.AppSettings.Get("Salt"); var cardNumber = _cryptographyService.Encrypt(creditCardNumber, key, salt); //encrypt the card info //fine if the card is valid, but is the card number already in our record, then not possible to save the same again if (_paymentMethodService.DoesCardNumberExist(cardNumber)) { VerboseReporter.ReportError("The card number is already saved in records", "process_payment"); return RespondFailure(); } paymentMethod = new UserPaymentMethod() { UserId = ApplicationContext.Current.CurrentUser.Id, IsVerified = false, PaymentMethodType = PaymentMethodType.CreditCard, CardIssuerType = cardIssuer.ToString().ToLowerInvariant(), CardNumber = creditCardNumber, CardNumberMasked = PaymentCardHelper.MaskCardNumber(creditCardNumber), NameOnCard = nameOnCard, }; //save this payment method _paymentMethodService.Insert(paymentMethod); #endregion } } //we need to see if we should only authorize or capture as well //the idea is if it's a sponsorship context, it's better to authorize the payment transaction and capture later when //the sponsorship is accepted //we thought of initially only authorizing sponsorship transactions and capture when it's accepted. //but that flow doesn't seem to work quite well, thoughts? var authorizeOnly = false; // (parameters.Get(PaymentParameterNames.PaymentContext) ?? string.Empty) == "sponsor"; //so we are ready for payment processing, let's create a paymenttrasaction for storing in our db var paymentTransaction = new PaymentTransaction() { IsLocalTransaction = true, PaymentStatus = PaymentStatus.Pending, TransactionAmount = amount, TransactionGuid = Guid.NewGuid(), CreatedOn = DateTime.UtcNow, UserIpAddress = WebHelper.GetClientIpAddress() }; _paymentTransactionService.Insert(paymentTransaction); //now proceed further with the payment //create the transaction request var transactionRequest = new TransactionRequest() { Amount = amount, CurrencyIsoCode = "USD",//TODO: SET CURRENCY AS SELECTED BY USER PaymentProcessorSystemName = paymentProcessor.PluginInfo.SystemName, UserId = ApplicationContext.Current.CurrentUser.Id, Parameters = formCollectionDictionary, TransactionUniqueId = paymentTransaction.TransactionGuid.ToString() }; var response = paymentProcessor.Process(transactionRequest, authorizeOnly); //update values of transaction parameters for future reference paymentTransaction.TransactionCodes = response.ResponseParameters; //update payment transaction _paymentTransactionService.Update(paymentTransaction); if (response.Success) { //let's verify the payment method first if it's not if (paymentMethod != null && !paymentMethod.IsVerified) { paymentMethod.IsVerified = true; _paymentMethodService.Update(paymentMethod); } //now since the response was success, we can actually assign some credits to the user var creditCount = amount * (1 / _paymentSettings.CreditExchangeRate); var credit = new Credit() { PaymentTransactionId = paymentTransaction.Id, CreatedOnUtc = DateTime.UtcNow, CreditCount = creditCount, CreditExchangeRate = _paymentSettings.CreditExchangeRate, //if it's authorize only transaction, we assign the credits, but they won't be usable before they are approved by capture CreditTransactionType = CreditTransactionType.Issued, CreditType = CreditType.Transactional, IsExpired = false }; //save credit _creditService.Insert(credit); //get total available credits of user var usableCreditCount = _creditService.GetUsableCreditsCount(ApplicationContext.Current.CurrentUser.Id); return RespondSuccess(new { UsableCreditCount = usableCreditCount }); } VerboseReporter.ReportError("An error occured while processing payment", "process_payment"); return RespondFailure(); }
public IHttpActionResult UpdateArtistData(FormCollection parameters) { var IdStr = parameters["id"]; int Id; if (int.TryParse(IdStr, out Id)) { var artistPage = _artistPageService.Get(Id); if (CanEdit(artistPage)) { //find the key that'll be updated var key = parameters["key"]; var value = parameters["value"]; switch (key) { case "Name": artistPage.Name = value; break; case "Description": artistPage.Biography = value; break; case "ShortDescription": artistPage.ShortDescription = value; break; case "Gender": artistPage.Gender = value; break; case "HomeTown": artistPage.HomeTown = value; break; } _artistPageService.Update(artistPage); return Response(new { success = true }); } else { return Response(new { success = false, message = "Unauthorized" }); } } else { return Response(new { success = false, message = "Invalid artist" }); } }
public IHttpActionResult UpdateViews(FormCollection _) { UpdateViews(); return this.Ok(); }