public void Cleanup(AppliedPaymentMethodCleanupContext context) { // Only finalize the process if this is an Amazon Payments order. if (context.PaymentMethod != AppLogic.ro_PMAmazonPayments) { return; } // Currently, Amazon only needs to clean up the checkout context if there's an error. // Successful orders will trigger the checkout process to clear the context. if (context.Status == AppLogic.ro_OK) { return; } var updatedPersistedCheckoutContext = new PersistedCheckoutContextBuilder() .From(PersistedCheckoutContextProvider.LoadCheckoutContext(context.Customer)) .WithoutAmazonPayments() .WithoutAcceptJsCreditCard() .WithoutAcceptJsECheck() .WithoutOffsiteRequiredBillingAddressId() .WithoutOffsiteRequiredShippingAddressId() .Build(); PersistedCheckoutContextProvider.SaveCheckoutContext(context.Customer, updatedPersistedCheckoutContext); context.Customer.UpdateCustomer(requestedPaymentMethod: string.Empty); }
public ActionResult AmazonPayments(bool clearSession = false) { var customer = HttpContext.GetCustomer(); if (!PaymentOptionProvider.PaymentMethodSelectionIsValid(AppLogic.ro_PMAmazonPayments, customer)) { NoticeProvider.PushNotice( message: AppLogic.GetString("checkout.paymentmethodnotallowed"), type: NoticeType.Failure); return(RedirectToAction(ActionNames.Index, ControllerNames.Checkout)); } var model = new AmazonPaymentsViewModel( residenceTypeOptions: SelectListBuilder.BuildResidenceTypeSelectList(ResidenceTypes.Residential.ToString()), clientId: AmazonPaymentsApiProvider.Configuration.ClientId, merchantId: AmazonPaymentsApiProvider.Configuration.MerchantId, scriptUrl: AmazonPaymentsApiProvider.Configuration.ScriptUrl); if (clearSession) { var updatedPersistedCheckoutContext = new PersistedCheckoutContextBuilder() .From(PersistedCheckoutContextProvider.LoadCheckoutContext(customer)) .WithoutAmazonPayments() .WithoutOffsiteRequiredBillingAddressId() .WithoutOffsiteRequiredShippingAddressId() .Build(); PersistedCheckoutContextProvider.SaveCheckoutContext(customer, updatedPersistedCheckoutContext); customer.UpdateCustomer(requestedPaymentMethod: string.Empty); return(Redirect(Url.Action(ActionNames.Index, ControllerNames.Checkout))); } return(View(model)); }
public ActionResult AmazonPaymentsComplete(AmazonPaymentsViewModel model) { var customer = HttpContext.GetCustomer(); var orderDetails = AmazonPaymentsApiProvider .GetOrderDetails(model.AmazonOrderReferenceId) .GetOrderReferenceDetailsResult .OrderReferenceDetails; var shippingAddress = orderDetails .Destination .PhysicalDestination; var city = shippingAddress.City; var countryCode = shippingAddress.CountryCode; var countryName = AppLogic.GetCountryNameFromTwoLetterISOCode(countryCode); var stateName = shippingAddress.StateOrRegion ?? string.Empty; var stateAbbreviation = AppLogic.GetStateAbbreviation(stateName, countryName); var postalCode = shippingAddress.PostalCode; if (!ModelState.IsValid) { var newModel = new AmazonPaymentsViewModel( residenceTypeOptions: SelectListBuilder.BuildResidenceTypeSelectList(ResidenceTypes.Residential.ToString()), clientId: model.ClientId, merchantId: model.MerchantId, scriptUrl: model.ScriptUrl); return(View(ViewNames.AmazonPayments, newModel)); } var amazonAddress = Address.FindOrCreateOffSiteAddress( customerId: customer.CustomerID, city: city, stateAbbreviation: string.IsNullOrEmpty(stateAbbreviation) ? stateName : stateAbbreviation, postalCode: postalCode, countryName: string.IsNullOrEmpty(countryName) ? countryCode : countryName, offSiteSource: AppLogic.ro_PMAmazonPayments, residenceType: model.ResidenceType ); customer.SetPrimaryAddress(amazonAddress.AddressID, AddressTypes.Billing); customer.SetPrimaryAddress(amazonAddress.AddressID, AddressTypes.Shipping); var updatedPersistedCheckoutContext = new PersistedCheckoutContextBuilder() .From(PersistedCheckoutContextProvider.LoadCheckoutContext(customer)) .WithAmazonPayments(new AmazonPaymentsDetails(model.AmazonOrderReferenceId)) .WithOffsiteRequiredBillingAddressId(amazonAddress.AddressID) .WithOffsiteRequiredShippingAddressId(amazonAddress.AddressID) .Build(); PersistedCheckoutContextProvider.SaveCheckoutContext(customer, updatedPersistedCheckoutContext); customer.UpdateCustomer(requestedPaymentMethod: AppLogic.ro_PMAmazonPayments); return(RedirectToAction(ActionNames.Index, ControllerNames.Checkout)); }
public ActionResult AcceptJsECheck(AcceptJsEcheckPostModel model) { var customer = HttpContext.GetCustomer(); // Save the validated eCheck details into the persisted checkout state. // ECheckDetails are null because we have already sent data to AcceptJs. // All we need now is the DataValue and DataDescriptor to complete the transaction. var updatedPersistedCheckoutContext = new PersistedCheckoutContextBuilder() .From(PersistedCheckoutContextProvider.LoadCheckoutContext(customer)) .WithECheck( eCheck: new ECheckDetails( nameOnAccount: null, accountNumber: null, routingNumber: null, accountType: null)) .WithAcceptJsECheck( acceptJsECheck: new AcceptJsDetailsECheck( dataValue: model.DataValue, dataDescriptor: model.DataDescriptor, eCheckDisplayAccountNumberLastFour: model.ECheckDisplayAccountNumberLastFour, eCheckDisplayAccountType: model.ECheckDisplayAccountType)) .WithoutOffsiteRequiredBillingAddressId() .WithoutOffsiteRequiredShippingAddressId() .Build(); PersistedCheckoutContextProvider.SaveCheckoutContext(customer, updatedPersistedCheckoutContext); customer.UpdateCustomer(requestedPaymentMethod: AppLogic.ro_PMECheck); return(RedirectToAction(ActionNames.Index, ControllerNames.Checkout)); }
public void Cleanup(AppliedPaymentMethodCleanupContext context) { // Only finalize the process if this is a PayPal Express order. if (context.PaymentMethod != AppLogic.ro_PMPayPalExpress) { return; } // Currently, PayPal Express only needs to clean up the checkout context if there's an error. // Successful orders will trigger the checkout process to clear the context. if (context.Status == AppLogic.ro_OK) { return; } var updatedPersistedCheckoutContext = new PersistedCheckoutContextBuilder() .From(PersistedCheckoutContextProvider.LoadCheckoutContext(context.Customer)) .WithoutPayPalExpress() .Build(); PersistedCheckoutContextProvider.SaveCheckoutContext(context.Customer, updatedPersistedCheckoutContext); DB.ExecuteSQL( sql: "update Customer set RequestedPaymentMethod = null where CustomerId = @customerId", parameters: new System.Data.SqlClient.SqlParameter("@customerId", context.Customer.CustomerID)); }
public ActionResult BraintreeCreditCard(FormCollection collection) { var customer = HttpContext.GetCustomer(); var updatedPersistedCheckoutContext = new PersistedCheckoutContextBuilder() .From(PersistedCheckoutContextProvider.LoadCheckoutContext(customer)) .WithCreditCard(new CreditCardDetails( name: customer.Name, number: null, issueNumber: null, cardType: collection["braintreeCardType"], expirationDate: null, startDate: null, cvv: null)) .WithBraintree(new BraintreeDetails( nonce: collection["braintreeNonce"], token: collection["braintreeToken"], paymentMethod: Gateway.BraintreeCreditCardKey, //This is the Braintree payment method, not ours threeDSecureApproved: false)) .WithoutOffsiteRequiredBillingAddressId() .WithoutOffsiteRequiredShippingAddressId() .Build(); PersistedCheckoutContextProvider.SaveCheckoutContext(customer, updatedPersistedCheckoutContext); customer.UpdateCustomer(requestedPaymentMethod: AppLogic.ro_PMCreditCard); return(RedirectToAction(ActionNames.Index, ControllerNames.Checkout)); }
public ActionResult AcceptJsCreditCard(AcceptJsCreditCardViewModel model) { var customer = HttpContext.GetCustomer(); // Save the validated credit card details into the persisted checkout state var updatedPersistedCheckoutContext = new PersistedCheckoutContextBuilder() .From(PersistedCheckoutContextProvider.LoadCheckoutContext(customer)) .WithCreditCard( creditCard: new CreditCardDetails( name: customer.Name, number: model.LastFour, //Put this here so that it can display in the payment summary section of the checkout page issueNumber: null, cardType: null, expirationDate: null, startDate: null, cvv: null)) .WithAcceptJsCreditCard( acceptJsCreditCard: new AcceptJsDetailsCreditCard( dataValue: model.DataValue, dataDescriptor: model.DataDescriptor, lastFour: model.LastFour, expirationMonth: model.ExpirationDate.Split('/')[0], //No special handling to check for empty values here. expirationYear: model.ExpirationDate.Split('/')[1])) // Better to explode here because expiration dates are required. .WithoutOffsiteRequiredBillingAddressId() .WithoutOffsiteRequiredShippingAddressId() .Build(); PersistedCheckoutContextProvider.SaveCheckoutContext(customer, updatedPersistedCheckoutContext); customer.UpdateCustomer(requestedPaymentMethod: AppLogic.ro_PMCreditCard); return(RedirectToAction(ActionNames.Index, ControllerNames.Checkout)); }
public ActionResult SagePayPiCreditCard(FormCollection collection) { var cardErrorSegments = collection["sagePayPiCardError"] .ParseAsDelimitedList('|'); if (cardErrorSegments.FirstOrDefault() == "ERROR") { var error = cardErrorSegments .Skip(1) .FirstOrDefault(); if (string.IsNullOrEmpty(error) || error.Contains("\"httpErrorCode\":401")) { NoticeProvider.PushNotice(StringResourceProvider.GetString("sagepaypi.payment.addingdetailserror"), NoticeType.Failure); return(RedirectToAction(ActionNames.Index, ControllerNames.Checkout)); } var sagePayPi = new SagePayPi(); var errorObject = Newtonsoft.Json.Linq.JObject.Parse(error); var errorDetails = sagePayPi.GetResponseError(errorObject, "errors"); var errorMessage = string.Format("{0} {1}", StringResourceProvider.GetString("sagepaypi.payment.carderrorprompt"), errorDetails); NoticeProvider.PushNotice(errorMessage, NoticeType.Failure); return(RedirectToAction(ActionNames.Index, ControllerNames.Checkout)); } var customer = HttpContext.GetCustomer(); var session = new CustomerSession(customer.CustomerID); session[AppLogic.SagePayPiMerchantSessionKey] = collection["sagePayPiMerchantSessionKey"]; var updatedPersistedCheckoutContext = new PersistedCheckoutContextBuilder() .From(PersistedCheckoutContextProvider.LoadCheckoutContext(customer)) .WithCreditCard(new CreditCardDetails( name: null, number: null, issueNumber: null, cardType: collection["sagePayPiCardType"], expirationDate: null, startDate: null, cvv: null)) .WithSagePayPi(new SagePayPiDetails( cardIdentifier: collection["sagePayPiCardIdentifier"], merchantSessionId: collection["sagePayPiMerchantSessionKey"], paymentMethod: Gateway.SagePayPiCreditCardKey, //This is the Sage Pay PI payment method, not ours threeDSecureApproved: false)) .WithoutOffsiteRequiredBillingAddressId() .WithoutOffsiteRequiredShippingAddressId() .Build(); PersistedCheckoutContextProvider.SaveCheckoutContext(customer, updatedPersistedCheckoutContext); customer.UpdateCustomer(requestedPaymentMethod: AppLogic.ro_PMCreditCard); return(RedirectToAction(ActionNames.Index, ControllerNames.Checkout)); }
void UpdateOver13(bool?over13Selected, Customer customer) { if (!over13Selected.HasValue) { return; } var updatedPersistedCheckoutContext = new PersistedCheckoutContextBuilder() .From(PersistedCheckoutContextProvider.LoadCheckoutContext(customer)) .WithOver13Checked(over13Selected.Value) .Build(); PersistedCheckoutContextProvider.SaveCheckoutContext(customer, updatedPersistedCheckoutContext); }
void UpdateTermsAndConditions(bool?termsAndConditionAccepted, Customer customer) { if (!termsAndConditionAccepted.HasValue) { return; } var updatedPersistedCheckoutContext = new PersistedCheckoutContextBuilder() .From(PersistedCheckoutContextProvider.LoadCheckoutContext(customer)) .WithTermsAndConditionsAccepted(termsAndConditionAccepted.Value) .Build(); PersistedCheckoutContextProvider.SaveCheckoutContext(customer, updatedPersistedCheckoutContext); }
public ActionResult AmazonPaymentsCallback(string session, string access_token, string token_type, string expires_in, string scope) { // Get an email back from amazon and update the checkout context with it if we don't already have an email on the checkout context. var customer = HttpContext.GetCustomer(); var persistedCheckoutContext = PersistedCheckoutContextProvider.LoadCheckoutContext(customer); if (string.IsNullOrEmpty(persistedCheckoutContext.Email)) { if (string.IsNullOrEmpty(access_token)) { return(View(ViewNames.AmazonPayments, new { clearSession = true })); } var userProfile = AmazonPaymentsApiProvider.GetUserProfile(access_token); if (userProfile != null && !string.IsNullOrEmpty(userProfile.Email)) { var updatedPersistedCheckoutContext = new PersistedCheckoutContextBuilder() .From(persistedCheckoutContext) .WithEmail(userProfile.Email) .Build(); PersistedCheckoutContextProvider.SaveCheckoutContext(customer, updatedPersistedCheckoutContext); } } var residenceType = ResidenceTypes.Residential; if (customer.PrimaryShippingAddress != null && customer.PrimaryShippingAddress.ResidenceType != ResidenceTypes.Unknown) { residenceType = customer.PrimaryShippingAddress.ResidenceType; } var model = new AmazonPaymentsViewModel( residenceTypeOptions: SelectListBuilder.BuildResidenceTypeSelectList(residenceType.ToString()), clientId: AmazonPaymentsApiProvider.Configuration.ClientId, merchantId: AmazonPaymentsApiProvider.Configuration.MerchantId, scriptUrl: AmazonPaymentsApiProvider.Configuration.ScriptUrl) { ResidenceType = residenceType, CheckoutStep = AmazonPaymentsCheckoutStep.SelectAddress }; return(View(ViewNames.AmazonPayments, model)); }
public ActionResult SetPaymentMethod(string selectedPaymentMethod = null) { var customer = HttpContext.GetCustomer(); var updatedPersistedCheckoutContext = new PersistedCheckoutContextBuilder() .From(PersistedCheckoutContextProvider.LoadCheckoutContext(customer)) .WithoutOffsiteRequiredBillingAddressId() .WithoutOffsiteRequiredShippingAddressId() .Build(); PersistedCheckoutContextProvider.SaveCheckoutContext(customer, updatedPersistedCheckoutContext); //Update the customer record if (selectedPaymentMethod != null && selectedPaymentMethod != customer.RequestedPaymentMethod) { customer.UpdateCustomer(requestedPaymentMethod: selectedPaymentMethod); } return(RedirectToAction(ActionNames.Index, ControllerNames.Checkout)); }
public ActionResult PurchaseOrder(PurchaseOrderViewModel model) { if (!ModelState.IsValid) { return(RedirectToAction(ActionNames.Index, ControllerNames.Checkout)); } var customer = HttpContext.GetCustomer(); var updatedPersistedCheckoutContext = new PersistedCheckoutContextBuilder() .From(PersistedCheckoutContextProvider.LoadCheckoutContext(customer)) .WithPurchaseOrder(new PurchaseOrderDetails(model.PONumber)) .WithoutAmazonPayments() .WithoutOffsiteRequiredBillingAddressId() .WithoutOffsiteRequiredShippingAddressId() .Build(); PersistedCheckoutContextProvider.SaveCheckoutContext(customer, updatedPersistedCheckoutContext); customer.UpdateCustomer(requestedPaymentMethod: AppLogic.ro_PMPurchaseOrder); return(RedirectToAction(ActionNames.Index, ControllerNames.Checkout)); }
public ActionResult BraintreeThreeDSecurePass(string nonce) { var customer = HttpContext.GetCustomer(); var checkoutContext = PersistedCheckoutContextProvider.LoadCheckoutContext(customer); var cart = CachedShoppingCartProvider.Get(customer, CartTypeEnum.ShoppingCart, AppLogic.StoreID()); var orderNumber = customer.ThisCustomerSession.SessionUSInt("3Dsecure.OrderNumber"); var updatedCheckoutContext = new PersistedCheckoutContextBuilder() .From(checkoutContext) .WithBraintree(new BraintreeDetails( nonce: nonce, //We got a new nonce after the 3dSecure request token: checkoutContext.Braintree.Token, paymentMethod: checkoutContext.Braintree.PaymentMethod, threeDSecureApproved: true)) .WithoutOffsiteRequiredBillingAddressId() .WithoutOffsiteRequiredShippingAddressId() .Build(); PersistedCheckoutContextProvider.SaveCheckoutContext(customer, updatedCheckoutContext); customer.ThisCustomerSession[AppLogic.Braintree3dSecureKey] = "true"; customer.ThisCustomerSession[AppLogic.BraintreeNonceKey] = nonce; customer.ThisCustomerSession[AppLogic.BraintreePaymentMethod] = checkoutContext.Braintree.PaymentMethod; var status = Gateway.MakeOrder(string.Empty, AppLogic.TransactionMode(), cart, orderNumber, string.Empty, string.Empty, string.Empty, string.Empty); ClearThreeDSecureSessionInfo(customer); if (status == AppLogic.ro_OK) { return(RedirectToAction( ActionNames.Confirmation, ControllerNames.CheckoutConfirmation, new { orderNumber = orderNumber })); } NoticeProvider.PushNotice(string.Format(StringResourceProvider.GetString("secureprocess.aspx.5"), status), NoticeType.Failure); return(RedirectToAction(ActionNames.Index, ControllerNames.Checkout)); }
public ActionResult BraintreeThreeDSecureFail() { var customer = HttpContext.GetCustomer(); var persistedCheckoutContext = PersistedCheckoutContextProvider.LoadCheckoutContext(customer); var updatedPersistedCheckoutContext = new PersistedCheckoutContextBuilder() .From(persistedCheckoutContext) .WithBraintree(new BraintreeDetails( nonce: persistedCheckoutContext.Braintree.Nonce, token: persistedCheckoutContext.Braintree.Token, paymentMethod: persistedCheckoutContext.Braintree.PaymentMethod, threeDSecureApproved: false)) .WithoutOffsiteRequiredBillingAddressId() .WithoutOffsiteRequiredShippingAddressId() .Build(); PersistedCheckoutContextProvider.SaveCheckoutContext(customer, updatedPersistedCheckoutContext); NoticeProvider.PushNotice(StringResourceProvider.GetString("braintree.liabilityshiftfailed"), NoticeType.Failure); return(RedirectToAction(ActionNames.Index, ControllerNames.Checkout)); }
public ActionResult ShippingEstimate(ShippingEstimateViewModel model) { if (!ModelState.IsValid) { return(RedirectToAction(ActionNames.Index, ControllerNames.Checkout)); } // Add the estimate partial address to the checkout context so that we can use that later to display rates if there is no customer address var customer = HttpContext.GetCustomer(); var shippingEstimateDetails = new ShippingEstimateDetails( country: model.Country, city: model.City, state: model.State, postalCode: model.PostalCode); var updatedPersistedCheckoutContext = new PersistedCheckoutContextBuilder() .From(PersistedCheckoutContextProvider.LoadCheckoutContext(customer)) .WithShippingEstimate(shippingEstimateDetails) .Build(); PersistedCheckoutContextProvider.SaveCheckoutContext(customer, updatedPersistedCheckoutContext); return(RedirectToAction(ActionNames.Index, ControllerNames.Checkout)); }
public ActionResult SagePayPiPaRes(string paRes, string mD) { var orderStatus = StringResourceProvider.GetString("sagepaypi.error.unknownerror"); var sagePayPi = new SagePayPi(); var customer = HttpContext.GetCustomer(); var session = new CustomerSession(customer.CustomerID); var orderNumber = customer.ThisCustomerSession.SessionUSInt("3Dsecure.OrderNumber"); var useLiveTransactions = AppConfigProvider.GetAppConfigValue <bool>("UseLiveTransactions"); var transactionUrl = string.Format( "{0}transactions/{1}", useLiveTransactions ? AppConfigProvider.GetAppConfigValue("SagePayPi.LiveUrl") : AppConfigProvider.GetAppConfigValue("SagePayPi.TestUrl"), session[AppLogic.SagePayPiMd]); var threeDSecureTransactionUrl = $"{transactionUrl}/3d-secure"; var jsonObject = new JObject( new JProperty("paRes", paRes) ); var formattedResponse = JObject.Parse(sagePayPi.SagePayPiApiCall(jsonObject.ToString(), threeDSecureTransactionUrl, "POST")); var transactionResponseHasError = sagePayPi.ResponseHasError(formattedResponse, "status", "authenticated") && sagePayPi.ResponseHasError(formattedResponse, "status", "attemptonly"); if (transactionResponseHasError) { if (AppConfigProvider.GetAppConfigValue <bool>("sagepaypi.customerfriendlyerrors")) { NoticeProvider.PushNotice(string.Format( "{0} {1}", StringResourceProvider.GetString("sagepaypi.threedsecure.didnotauthenticate"), StringResourceProvider.GetString("sagepaypi.error.reentercarddetails")), NoticeType.Failure); } else { orderStatus = sagePayPi.GetResponseError(formattedResponse, "status"); if (orderStatus.EqualsIgnoreCase(StringResourceProvider.GetString("sagepaypi.error.unknownresponseerror"))) { orderStatus = sagePayPi.GetResponseError(formattedResponse, "statusDetail"); } else { orderStatus = sagePayPi.GetThreeDSecureStatus(sagePayPi.GetResponseError(formattedResponse, "status")); } if (orderStatus.EqualsIgnoreCase(StringResourceProvider.GetString("sagepaypi.error.unknownresponseerror"))) { orderStatus = sagePayPi.GetResponseError(formattedResponse, "description"); } //display error when 3-D secure does not authenticate NoticeProvider.PushNotice(string.Format( "{0} {1} {2} {3}.", StringResourceProvider.GetString("sagepaypi.threedsecure.didnotauthenticate"), StringResourceProvider.GetString("sagepaypi.error.reentercarddetails"), StringResourceProvider.GetString("sagepaypi.status.reason"), orderStatus.TrimEnd('.')), NoticeType.Failure); } if (orderNumber > 0) { sagePayPi.LogFailedTransaction($"URL: {threeDSecureTransactionUrl}, Request: {jsonObject}", formattedResponse.ToString(), orderNumber); } sagePayPi.ClearPaymentMethod(customer.CustomerID); return(RedirectToAction(ActionNames.Index, ControllerNames.Checkout)); } //retrieve transaction var emptyObject = "{}"; var formattedTransactionResponse = JObject.Parse(sagePayPi.SagePayPiApiCall(emptyObject.ToString(), transactionUrl, "GET")); var formattedTransactionResponseHasError = sagePayPi.ResponseHasError(formattedTransactionResponse, "status", "ok") && sagePayPi.ResponseHasError(formattedTransactionResponse, "status", "attemptonly"); //if the transaction did not submit properly, return early, display an error from sage pay and do not make the order if (formattedTransactionResponseHasError) { var threeDSecureStatus = sagePayPi.GetThreeDSecureStatus(string.Empty); if (formattedTransactionResponse != null && formattedTransactionResponse["3DSecure"] != null && formattedTransactionResponse["3DSecure"]["status"] != null) { threeDSecureStatus = sagePayPi.GetThreeDSecureStatus(formattedTransactionResponse["3DSecure"]["status"].ToString()); } orderStatus = sagePayPi.GetResponseError(formattedTransactionResponse, "statusDetail"); if (orderStatus.EqualsIgnoreCase(StringResourceProvider.GetString("sagepaypi.error.unknownresponseerror"))) { orderStatus = sagePayPi.GetResponseError(formattedTransactionResponse, "description"); } if (AppConfigProvider.GetAppConfigValue <bool>("sagepaypi.customerfriendlyerrors")) { NoticeProvider.PushNotice(string.Format( "{0} {1}", StringResourceProvider.GetString("sagepaypi.threedsecure.didnotauthenticate"), StringResourceProvider.GetString("sagepaypi.error.reentercarddetails")), NoticeType.Failure); } else { NoticeProvider.PushNotice(string.Format( "{0}. {1} {2}. {3}", orderStatus.TrimEnd('.'), StringResourceProvider.GetString("sagepaypi.status.threedsecure"), threeDSecureStatus.TrimEnd('.'), StringResourceProvider.GetString("sagepaypi.error.reentercarddetails")), NoticeType.Failure); } if (orderNumber > 0) { sagePayPi.LogFailedTransaction($"GET Method - URL: {transactionUrl}", formattedTransactionResponse.ToString(), customer.ThisCustomerSession.SessionUSInt("3Dsecure.OrderNumber")); } sagePayPi.ClearPaymentMethod(customer.CustomerID); return(RedirectToAction(ActionNames.Index, ControllerNames.Checkout)); } var persistedCheckoutContext = PersistedCheckoutContextProvider.LoadCheckoutContext(customer); var cart = CachedShoppingCartProvider.Get(customer, CartTypeEnum.ShoppingCart, AppLogic.StoreID()); var updatedPersistedCheckoutContext = new PersistedCheckoutContextBuilder() .From(persistedCheckoutContext) .WithCreditCard(new CreditCardDetails( name: persistedCheckoutContext.CreditCard.Name, number: persistedCheckoutContext.CreditCard.Number, issueNumber: persistedCheckoutContext.CreditCard.IssueNumber, cardType: formattedTransactionResponse["paymentMethod"]["card"]["cardType"].ToString(), expirationDate: persistedCheckoutContext.CreditCard.ExpirationDate, startDate: persistedCheckoutContext.CreditCard.StartDate, cvv: persistedCheckoutContext.CreditCard.Cvv)) .WithSagePayPi(new SagePayPiDetails( cardIdentifier: persistedCheckoutContext.SagePayPi.CardIdentifier, merchantSessionId: persistedCheckoutContext.SagePayPi.MerchantSessionId, paymentMethod: persistedCheckoutContext.SagePayPi.PaymentMethod, //This is the Sage Pay PI payment method, not ours threeDSecureApproved: true)) .WithoutOffsiteRequiredBillingAddressId() .WithoutOffsiteRequiredShippingAddressId() .Build(); PersistedCheckoutContextProvider.SaveCheckoutContext(customer, updatedPersistedCheckoutContext); customer.ThisCustomerSession[AppLogic.SagePayPi3dSecureKey] = "true"; customer.ThisCustomerSession[AppLogic.SagePayPiPaymentMethod] = persistedCheckoutContext.SagePayPi.PaymentMethod; orderStatus = Gateway.MakeOrder(string.Empty, AppLogic.TransactionMode(), cart, orderNumber, string.Empty, string.Empty, string.Empty, string.Empty); ClearThreeDSecureSessionInfo(customer); if (orderStatus == AppLogic.ro_OK) { return(RedirectToAction( ActionNames.Confirmation, ControllerNames.CheckoutConfirmation, new { orderNumber = orderNumber })); } //display error if we reach this point, we should have redirected by now if (AppConfigProvider.GetAppConfigValue <bool>("sagepaypi.customerfriendlyerrors")) { NoticeProvider.PushNotice(string.Format( "{0} {1}", StringResourceProvider.GetString("sagepaypi.threedsecure.didnotauthenticate"), StringResourceProvider.GetString("sagepaypi.error.reentercarddetails")), NoticeType.Failure); } else { NoticeProvider.PushNotice(string.Format( "{0} {1}", string.Format(StringResourceProvider.GetString("secureprocess.aspx.5"), orderStatus.TrimEnd('.')), StringResourceProvider.GetString("sagepaypi.error.reentercarddetails")), NoticeType.Failure); } if (orderNumber > 0) { sagePayPi.LogFailedTransaction($"URL: {threeDSecureTransactionUrl}, Request: {jsonObject}", formattedResponse.ToString(), orderNumber); } sagePayPi.ClearPaymentMethod(customer.CustomerID); return(RedirectToAction(ActionNames.Index, ControllerNames.Checkout)); }
public ActionResult CreditCard(CheckoutCreditCardViewModel model) { // Convert model fields into validatable values var customer = HttpContext.GetCustomer(); var persistedCheckoutContext = PersistedCheckoutContextProvider.LoadCheckoutContext(customer); var number = !string.IsNullOrEmpty(model.Number) && model.Number.StartsWith("•") && persistedCheckoutContext.CreditCard != null ? persistedCheckoutContext.CreditCard.Number : model.Number.Replace(" ", ""); var issueNumber = !string.IsNullOrEmpty(model.IssueNumber) && model.IssueNumber.StartsWith("•") && persistedCheckoutContext.CreditCard != null ? persistedCheckoutContext.CreditCard.IssueNumber : model.IssueNumber; var expirationDate = ParseMonthYearString(model.ExpirationDate); var startDate = ParseMonthYearString(model.StartDate); var cvv = !string.IsNullOrEmpty(model.Cvv) && model.Cvv.StartsWith("•") && persistedCheckoutContext.CreditCard != null ? persistedCheckoutContext.CreditCard.Cvv : model.Cvv; // Run server-side credit card validation var validationConfiguration = new CreditCardValidationConfiguration( validateCreditCardNumber: AppLogic.AppConfigBool("ValidateCreditCardNumbers"), showCardStartDateFields: AppLogic.AppConfigBool("ShowCardStartDateFields"), cardExtraCodeIsOptional: AppLogic.AppConfigBool("CardExtraCodeIsOptional")); var validationContext = new CreditCardValidationContext( cardType: model.CardType, number: number, issueNumber: issueNumber, expirationDate: expirationDate, startDate: startDate, cvv: cvv); var validationResult = CreditCardValidationProvider.ValidateCreditCard(validationConfiguration, validationContext); // Update the ModelState with any validation issues if (!validationResult.Valid) { foreach (var field in validationResult.FieldErrors) { foreach (var error in field) { // This assumes that the model properties and the credit card validation field enum names match perfectly ModelState.AddModelError(field.Key.ToString(), error); } } } // Use POST redirect GET if there are any issues if (!ModelState.IsValid) { return(RedirectToAction(ActionNames.CreditCard, ControllerNames.CheckoutCreditCard)); } // Save the validated credit card details into the persisted checkout state var updatedPersistedCheckoutContext = new PersistedCheckoutContextBuilder() .From(persistedCheckoutContext) .WithCreditCard(new CreditCardDetails( name: model.Name, number: number, issueNumber: issueNumber, cardType: model.CardType, expirationDate: expirationDate, startDate: startDate, cvv: cvv)) .WithoutAmazonPayments() .WithoutOffsiteRequiredBillingAddressId() .WithoutOffsiteRequiredShippingAddressId() .Build(); PersistedCheckoutContextProvider.SaveCheckoutContext(customer, updatedPersistedCheckoutContext); // Save the StoreCCInDB setting if it was shown to the customer & their choice changed var siteIsStoringCCs = AppLogic.AppConfigBool("StoreCCInDB"); if (siteIsStoringCCs && model.SaveCreditCardNumber != customer.StoreCCInDB) { customer.UpdateCustomer(storeCreditCardInDb: siteIsStoringCCs && model.SaveCreditCardNumber); } // Update the customer record if (customer.RequestedPaymentMethod != AppLogic.ro_PMCreditCard) { customer.UpdateCustomer(requestedPaymentMethod: AppLogic.ro_PMCreditCard); } try { if (WalletProvider.WalletsAreEnabled() && model.SaveToWallet) { WalletProvider.CreatePaymentProfile( customer: customer, billingAddress: customer.PrimaryBillingAddress, cardType: model.CardType, number: number, cvv: cvv, expirationDate: expirationDate.Value); } } catch (WalletException walletException) { ModelState.AddModelError("SaveToWallet", walletException.Message); return(RedirectToAction(ActionNames.CreditCard, ControllerNames.CheckoutCreditCard)); } return(RedirectToAction(ActionNames.Index, ControllerNames.Checkout)); }
public ActionResult PayPalExpressReturn(string token) { var customer = HttpContext.GetCustomer(); var expressCheckoutDetails = Gateway.GetExpressCheckoutDetails(token, customer.CustomerID); if (string.IsNullOrEmpty(expressCheckoutDetails)) { // If nothing returned, abort the transaction. return(RedirectToAction(ActionNames.Index, ControllerNames.Checkout)); } if (expressCheckoutDetails.Equals("AVSFAILED", StringComparison.OrdinalIgnoreCase)) { NoticeProvider.PushNotice(AppLogic.GetString("paypal.express.avsconfirmedaddress.error"), NoticeType.Failure); return(RedirectToAction(ActionNames.Index, ControllerNames.Checkout)); } if (!customer.IsRegistered && !customer.IsOver13) { // Set the Over13Checked flag since PayPal is permitting the order process, so they don't get rejected. DB.ExecuteSQL( "update Customer set Over13Checked = 1 where CustomerID = @customerId", new SqlParameter("customerId", customer.CustomerID)); } if (customer.PrimaryBillingAddress.PaymentMethodLastUsed == AppLogic.ro_PMPayPalEmbeddedCheckout) { var orderNumber = DB.GetSqlN( "select max(OrderNumber) N from dbo.Orders where CustomerID = @customerId", new SqlParameter("customerId", customer.CustomerID)); return(RedirectToAction( ActionNames.Confirmation, ControllerNames.CheckoutConfirmation, new { orderNumber = orderNumber })); } customer.UpdateCustomer(requestedPaymentMethod: AppLogic.ro_PMPayPalExpress); var checkoutContext = PersistedCheckoutContextProvider.LoadCheckoutContext(customer); // During our call for customer details from paypal above we set the email on the customer record if they are not signed in already. // So let's pull that customer email into the checkout context var email = !string.IsNullOrEmpty(checkoutContext.Email) ? checkoutContext.Email : customer.EMail; var updatedPersistedCheckoutContext = new PersistedCheckoutContextBuilder() .From(PersistedCheckoutContextProvider.LoadCheckoutContext(customer)) .WithPayPalExpress(new PayPalExpressDetails( token: token, payerId: expressCheckoutDetails)) .WithoutAmazonPayments() .WithOffsiteRequiredBillingAddressId(customer.PrimaryBillingAddressID) //This was set while processing the PayPal return info earlier .WithOffsiteRequiredShippingAddressId(customer.PrimaryShippingAddressID) //This was set while processing the PayPal return info earlier .WithEmail(email) .Build(); PersistedCheckoutContextProvider.SaveCheckoutContext(customer, updatedPersistedCheckoutContext); return(RedirectToAction(ActionNames.Index, ControllerNames.Checkout)); }