public ActionResult Confirm() { //Assign value to form field from session CustomCart cart = new CustomCart().Current(); CustomForm customForm = new CustomForm(); customForm.FirstName = cart.BillingFirstnames; customForm.LastName = cart.BillingSurname; customForm.Address1 = cart.BillingAddress1; customForm.Address2 = cart.BillingAddress2; customForm.City = cart.BillingCity; customForm.PostCode = cart.BillingPostCode; customForm.Country = cart.BillingCountry; customForm.Phone = cart.Phone; customForm.DOB = Convert.ToDateTime(cart.DOB); SagePayFormIntegration sagePayFormIntegration = new SagePayFormIntegration(); IFormPayment request = sagePayFormIntegration.FormPaymentRequest(); SetSagePayAPIData(request); var errors = sagePayFormIntegration.Validation(request); if (errors == null || errors.Count == 0) { sagePayFormIntegration.ProcessRequest(request); ViewBag.Crypt = request.Crypt; } else { ViewBag.Error = "Some error occurred"; } return(View(customForm)); }
private void SetSagePayAPIData(IFormPayment request) { var isCollectRecipientDetails = SagePaySettings.IsCollectRecipientDetails; CustomCart cart = new CustomCart().Current(); request.VpsProtocol = SagePaySettings.ProtocolVersion; request.TransactionType = SagePaySettings.DefaultTransactionType; request.Vendor = SagePaySettings.VendorName; request.VendorTxCode = SagePayFormIntegration.GetNewVendorTxCode(); request.Amount = 1; //Custom value set request.Currency = SagePaySettings.Currency; request.SuccessUrl = SagePaySettings.SiteFqdn + "Payment/Result?customParams=Transaction Details For Success"; request.FailureUrl = SagePaySettings.SiteFqdn + "Payment/Result?customParams=Transaction Details For Failure"; request.Description = cart.Description; request.BillingSurname = cart.BillingSurname; request.BillingFirstnames = cart.BillingFirstnames; request.BillingAddress1 = cart.BillingAddress1 + " " + cart.BillingAddress2; request.BillingCity = cart.BillingCity; request.BillingCountry = cart.BillingCountry; request.DeliverySurname = cart.DeliverySurname; request.DeliveryFirstnames = cart.DeliveryFirstnames; request.DeliveryAddress1 = cart.DeliveryAddress1 + " " + cart.DeliveryAddress2; request.DeliveryCity = cart.DeliveryCity; request.DeliveryCountry = cart.DeliveryCountry; //Optional request.BillingPostCode = cart.BillingPostCode; request.DeliveryPostCode = cart.DeliveryPostCode; request.BasketXml = cart.BasketXml; request.VendorEmail = SagePaySettings.VendorEmail; request.SendEmail = SagePaySettings.SendEmail; request.EmailMessage = SagePaySettings.EmailMessage; request.AllowGiftAid = SagePaySettings.AllowGiftAid; request.ApplyAvsCv2 = SagePaySettings.ApplyAvsCv2; request.Apply3dSecure = SagePaySettings.Apply3dSecure; request.BillingAgreement = ""; request.ReferrerId = SagePaySettings.ReferrerID; request.SurchargeXml = SagePaySettings.SurchargeXML; //set vendor data request.VendorData = ""; }
public ActionResult Result(string customParams, string crypt = "") { try { IFormPaymentResult PaymentStatusResult; SagePayFormIntegration sagePayFormIntegration = new SagePayFormIntegration(); PaymentStatusResult = sagePayFormIntegration.ProcessResult(crypt); ViewBag.StatusResult = PaymentStatusResult; DataObject tempObj = ((DataObject)PaymentStatusResult); ViewBag._customParams = customParams; } catch (Exception ex) { string errorMessage = ex.Message + "<<<<::::::::::::::::>>>>"; errorMessage += ex.StackTrace + "<<<<::::::::::::::::>>>>" + ex.Source + "<<<<::::::::::::::::>>>>"; if (ex.InnerException != null) { errorMessage += ex.InnerException.Message; } ViewBag.Error = errorMessage; } return(View()); }
/// <summary> /// Create a dictionary with credentials for SagePay service. /// </summary> /// <param name="settings"></param> /// <returns></returns> //private static Dictionary<string, string> CreateSagePayApiConfig(SagePayProcessorSettings settings) //{ // return new Dictionary<string, string> // { // {"mode", GetModeString(settings.LiveMode)}, // {"account.vendorName", settings.VendorName}, // {"account.encyptionPassword", settings.EncyptionPassword}, // {"account.apiVersion", settings.ApiVersion} // }; //} /// <summary> /// Processes the Authorize and AuthorizeAndCapture transactions /// </summary> /// <param name="invoice">The <see cref="IInvoice"/> to be paid</param> /// <param name="payment">The <see cref="Core.Models.IPayment"/> record</param> /// <param name="args"></param> /// <returns>The <see cref="Core.Gateways.Payment.IPaymentResult"/></returns> public IPaymentResult InitializePayment(IInvoice invoice, IPayment payment, ProcessorArgumentCollection args) { try { // Gather SagePay settings info and formulate it into a Dictionary for posting to the gateway var sagePayFormIntegration = new SagePayFormIntegration(Settings); var request = sagePayFormIntegration.FormPaymentRequest(); SetSagePayApiData(request, invoice, payment); // Do basic validation as per the SagePay kit var errors = sagePayFormIntegration.Validation(request); if (errors.Count > 0) { return(new PaymentResult(Attempt <IPayment> .Fail(payment, base.CreateErrorResult(errors)), invoice, true)); } // Use the SagePay methods to encrypt the form so it can be posted sagePayFormIntegration.ProcessRequest(request); // Prepare a HTTP post var content = new FormUrlEncodedContent( new Dictionary <string, string> { { "VPSProtocol", Settings.ApiVersion }, { "TxType", Constants.TransactionType }, { "Vendor", Settings.VendorName }, //{"Profile", "LOW"}, // Provider setting? { "Crypt", request.Crypt } }); try { // Post the form to SagePay VSP var formPaymentUrl = string.Format("https://{0}.sagepay.com/gateway/service/vspform-register.vsp", Settings.Environment); // TEST form post //var formPaymentUrl = string.Format("https://{0}.sagepay.com/showpost/showpost.asp", GetModeString(Settings.LiveMode)); var result = new HttpClient().PostAsync(formPaymentUrl, content).Result; // Store transaction details in ExtendedData payment.ExtendedData.SetValue(Constants.ExtendedDataKeys.VendorTransactionCode, request.VendorTxCode); // Flag an error in the backoffice if the result is not successful if (!result.IsSuccessStatusCode) { return(new PaymentResult(Attempt <IPayment> .Fail(payment, CreateErrorResult(result.RequestMessage.Content)), invoice, true)); } // Process the response from SagePay - this contains the redirect URL for the customer to complete their payment. var redirectUrl = result.RequestMessage.RequestUri.ToString(); payment.ExtendedData.SetValue(Constants.ExtendedDataKeys.SagePayPaymentUrl, redirectUrl); } catch (Exception ex) { LogHelper.Error <SagePayFormPaymentProcessor>("SagePay form post failed. Crypt value: " + request.Crypt, ex); } // Store our site return URL and cancel URL in extendedData so it can be used in the callback var returnUrl = GetWebsiteUrl() + Settings.ReturnUrl; payment.ExtendedData.SetValue(Constants.ExtendedDataKeys.ReturnUrl, returnUrl); var cancelUrl = GetWebsiteUrl() + Settings.CancelUrl; payment.ExtendedData.SetValue(Constants.ExtendedDataKeys.CancelUrl, cancelUrl); return(new PaymentResult(Attempt <IPayment> .Succeed(payment), invoice, true)); } catch (Exception ex) { return(new PaymentResult(Attempt <IPayment> .Fail(payment, ex), invoice, true)); } }
//TODO: refactor away to a Service that wraps the SagePay kit horribleness private void SetSagePayApiData(IFormPayment request, IInvoice invoice, IPayment payment) { // Get Merchello data var billingAddress = invoice.GetBillingAddress(); var shippingAddress = billingAddress; // Shipment - only use a shipping address if there is shipment info in the invoice var shipmentLineItem = invoice.ShippingLineItems().FirstOrDefault(); if (shipmentLineItem != null) { var shipment = shipmentLineItem.ExtendedData.GetShipment <InvoiceLineItem>(); shippingAddress = shipment.GetDestinationAddress(); } // SagePay details request.VpsProtocol = Settings.ProtocolVersion; request.TransactionType = Settings.TransactionType; request.Vendor = Settings.VendorName; request.VendorTxCode = SagePayFormIntegration.GetNewVendorTxCode(); request.Amount = payment.Amount; request.Currency = invoice.CurrencyCode(); request.Description = "Goods from " + Settings.VendorName; // TODO: Is there a basket summary I can access? Or convert the Basket to a sagepay format // Set ReturnUrl and CancelUrl of SagePay request to SagePayApiController. Func <string, string> adjustUrl = (url) => { if (!url.StartsWith("http")) { url = GetWebsiteUrl() + (url[0] == '/' ? "" : "/") + url; } url = url.Replace("{invoiceKey}", invoice.Key.ToString(), StringComparison.InvariantCultureIgnoreCase); url = url.Replace("{paymentKey}", payment.Key.ToString(), StringComparison.InvariantCultureIgnoreCase); return(url); }; request.SuccessUrl = adjustUrl("/umbraco/MerchelloSagePay/SagePayApi/SuccessPayment?InvoiceKey={invoiceKey}&PaymentKey={paymentKey}"); request.FailureUrl = adjustUrl("/umbraco/MerchelloSagePay/SagePayApi/AbortPayment?InvoiceKey={invoiceKey}&PaymentKey={paymentKey}"); // Billing details request.BillingSurname = billingAddress.TrySplitLastName(); request.BillingFirstnames = billingAddress.TrySplitFirstName(); request.BillingAddress1 = billingAddress.Address1; request.BillingAddress2 = billingAddress.Address2; request.BillingPostCode = billingAddress.PostalCode; request.BillingCity = billingAddress.Locality; request.BillingCountry = invoice.BillToCountryCode; request.CustomerEmail = billingAddress.Email; // Shipping details request.DeliverySurname = shippingAddress.TrySplitLastName(); request.DeliveryFirstnames = shippingAddress.TrySplitFirstName(); request.DeliveryAddress1 = shippingAddress.Address1; request.DeliveryCity = shippingAddress.Locality; request.DeliveryCountry = shippingAddress.CountryCode; request.DeliveryPostCode = shippingAddress.PostalCode; //Optional //request.CustomerName = cart.Billing.FirstNames + " " + cart.Billing.Surname; //request.VendorEmail = Settings.VendorEmail; //request.SendEmail = Settings.SendEmail; //request.EmailMessage = Settings.EmailMessage; //request.BillingAddress2 = billingAddress.Address2; //request.BillingPostCode = billingAddress.PostalCode; //request.BillingState = billingAddress.Region; //request.BillingPhone = billingAddress.Phone; //request.DeliveryAddress2 = shippingAddress.Address2; //request.DeliveryPostCode = shippingAddress.PostalCode; //request.DeliveryState = shippingAddress.Region; //request.DeliveryPhone = shippingAddress.Phone; }
public HttpResponseMessage SuccessPayment(Guid invoiceKey, Guid paymentKey, string crypt) { // Decrypt sagepay querystring data message if (string.IsNullOrEmpty(crypt)) { var ex = new NullReferenceException(string.Format("Invalid argument exception. Arguments: crypt={0}", crypt)); LogHelper.Error <SagePayApiController>("Payment not authorized.", ex); throw ex; } var sagePayFormIntegration = new SagePayFormIntegration(_formProcessor.Settings); var paymentResult = sagePayFormIntegration.ProcessResult(crypt); if (paymentResult.Status != ResponseStatus.OK && paymentResult.Status != ResponseStatus.AUTHENTICATED && paymentResult.Status != ResponseStatus.REGISTERED) { //var ex = new Exception(string.Format("Invalid payment status. Detail: {0}", paymentResult.StatusDetail)); //LogHelper.Error<SagePayApiController>("Sagepay error processing payment.", ex); return(ShowError(paymentResult.StatusDetail)); } // Query merchello for associated invoice and payment objects var invoice = _merchelloContext.Services.InvoiceService.GetByKey(invoiceKey); var payment = _merchelloContext.Services.PaymentService.GetByKey(paymentKey); if (invoice == null || payment == null) { var ex = new NullReferenceException(string.Format("Invalid argument exception. Arguments: invoiceKey={0}, paymentKey={1}", invoiceKey, paymentKey)); LogHelper.Error <SagePayApiController>("Payment not authorized.", ex); throw ex; } // Get a ref to the customer so the invoice Key can be stored in their extended data. // This can be retrieved on the receipt page //var customer = _merchelloContext.Services.CustomerService.GetByKey(invoice.CustomerKey.Value); //customer.ExtendedData.SetValue(Constants.ExtendedDataKeys.InvoiceKey, invoice.Key.ToString()); // Store some SagePay data in payment payment.ReferenceNumber = paymentResult.VpsTxId; payment.ExtendedData.SetValue(Constants.ExtendedDataKeys.SagePayTransactionCode, paymentResult.VpsTxId); // Authorize and save payment var authorizeResult = _formProcessor.AuthorizePayment(invoice, payment); _merchelloContext.Services.GatewayProviderService.Save(payment); if (!authorizeResult.Payment.Success) { LogHelper.Error <SagePayApiController>("Payment is not authorized.", authorizeResult.Payment.Exception); _merchelloContext.Services.GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Denied, "SagePay: request capture authorization error: " + authorizeResult.Payment.Exception.Message, 0); return(ShowError(authorizeResult.Payment.Exception.Message)); } _merchelloContext.Services.GatewayProviderService.ApplyPaymentToInvoice(payment.Key, invoice.Key, AppliedPaymentType.Debit, "SagePay: capture authorized", 0); // Capture payment var providerKeyGuid = new Guid(Constants.GatewayProviderSettingsKey); var paymentGatewayMethod = _merchelloContext.Gateways.Payment.GetPaymentGatewayMethods().First(item => item.PaymentMethod.ProviderKey == providerKeyGuid); var captureResult = paymentGatewayMethod.CapturePayment(invoice, payment, payment.Amount, null); if (!captureResult.Payment.Success) { LogHelper.Error <SagePayApiController>("Payment not captured.", captureResult.Payment.Exception); return(ShowError(captureResult.Payment.Exception.Message)); } // Redirect to ReturnUrl (with token replacement for an alternative means of order retrieval) var returnUrl = payment.ExtendedData.GetValue(Constants.ExtendedDataKeys.ReturnUrl); var response = Request.CreateResponse(HttpStatusCode.Moved); response.Headers.Location = new Uri(returnUrl.Replace("%INVOICE%", invoice.Key.ToString().EncryptWithMachineKey())); return(response); }