Пример #1
0
        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));
        }
Пример #2
0
        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 = "";
        }
Пример #3
0
 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());
 }
Пример #4
0
        /// <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));
            }
        }
Пример #5
0
        //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;
        }
Пример #6
0
        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);
        }