Esempio n. 1
0
        public void MarkOrderAsPaid(int orderId)
        {
            Order order = Order.GetOrder(orderId);

            OrderController orderController = new OrderController(new StoreContext(HttpContext.Current.Request, order.StoreId.Value));

            orderController.UpdateOrderStatus(order, order.OrderStatus, PaymentStatusName.Completed);

            //--- Delete the stored Credit Card number, even though it's encrypted we don't need the full # anymore
            order.CreditCardNumberEncrypted = string.Empty;
            order.CreditCardExpiration      = string.Empty;
            order.CreditCardSecurityCode    = string.Empty;
            order.Save();

            PaymentTransaction newTransaction = new PaymentTransaction();

            newTransaction.OrderId              = order.Id;
            newTransaction.PaymentProviderId    = this.ProviderId;
            newTransaction.GatewayUrl           = "";
            newTransaction.GatewayTransactionId = "";
            newTransaction.GatewayResponse      = "Marked as Paid";
            newTransaction.GatewayDebugResponse = "";
            newTransaction.Amount = order.Total;
            newTransaction.Save();
        }
Esempio n. 2
0
        public override HttpWebResponse SubmitDirectPaymentRequest(Order order, CreditCardInfo creditCardInfo)
        {
            order.EncryptCreditCardNumber(creditCardInfo.CardNumber);
            order.CreditCardSecurityCode = creditCardInfo.SecurityCode;
            order.PaymentStatus          = PaymentStatusName.Pending;

            order.Save();

            PaymentTransaction newTransaction = new PaymentTransaction();

            newTransaction.OrderId              = order.Id;
            newTransaction.PaymentProviderId    = this.ProviderId;
            newTransaction.GatewayUrl           = "";
            newTransaction.GatewayTransactionId = "";
            newTransaction.GatewayResponse      = "Payment Pending";
            newTransaction.GatewayDebugResponse = "";

            if (order.Total > 0)
            {
                // check for valid Credit Card
                CreditCardInfoValidator validator = new CreditCardInfoValidator();
                ValidationResult        results   = validator.Validate(creditCardInfo);
                if (!results.IsValid && results.Errors.Count > 0)
                {
                    newTransaction.GatewayResponse = "Credit Card Validation Error";
                    newTransaction.GatewayError    = results.Errors.ToList().ConvertAll(e => e.ErrorMessage).ToDelimitedString(", ");
                }
            }

            newTransaction.Save();

            return(null);
        }
Esempio n. 3
0
        public override HttpWebResponse SubmitDirectPaymentRequest(Order order, CreditCardInfo creditCardInfo)
        {
            order.PaymentStatus  = PaymentStatusName.Pending;
            order.CustomerNotes += CustomerInstructions + " ";
            order.Save();

            PaymentTransaction newTransaction = new PaymentTransaction();

            newTransaction.OrderId              = order.Id;
            newTransaction.PaymentProviderId    = this.ProviderId;
            newTransaction.GatewayUrl           = "";
            newTransaction.GatewayTransactionId = "";
            newTransaction.GatewayResponse      = "Payment Pending";
            newTransaction.GatewayDebugResponse = "";
            newTransaction.Save();

            return(null);
        }
Esempio n. 4
0
        public void MarkOrderAsPaid(int orderId)
        {
            Order order = Order.GetOrder(orderId);

            OrderController orderController = new OrderController(new StoreContext(HttpContext.Current.Request, order.StoreId.Value));

            orderController.UpdateOrderStatus(order, order.OrderStatus, PaymentStatusName.Completed);

            PaymentTransaction newTransaction = new PaymentTransaction();

            newTransaction.OrderId              = order.Id;
            newTransaction.PaymentProviderId    = this.ProviderId;
            newTransaction.GatewayUrl           = "";
            newTransaction.GatewayTransactionId = "";
            newTransaction.GatewayResponse      = "Marked as Paid";
            newTransaction.GatewayDebugResponse = "";
            newTransaction.Amount = order.Total;
            newTransaction.Save();
        }
        public override PaymentStatusName ProcessDirectPaymentResponse(Order order, HttpWebResponse response)
        {
            string responseString = HttpHelper.WebResponseToString(response);

            // Decode the response fields from PayPal API
            string[] encodedPairs = responseString.Split('&');
            Dictionary <string, string> fields = new Dictionary <string, string>(encodedPairs.Length);

            foreach (string field in encodedPairs)
            {
                string[] pair  = field.Split('=');
                string   name  = HttpUtility.UrlDecode(pair[0]);
                string   value = HttpUtility.UrlDecode(pair[1]);

                fields[name] = value;
            }

            // parse response fields into variables
            string    ack     = fields["ACK"];
            AckValues ackType = WA.Enum <AckValues> .TryParseOrDefault(ack, AckValues.Failure);

            int?    orderId       = WA.Parser.ToInt(fields.TryGetValueOrEmpty("CUSTOM"));
            string  transactionId = fields.TryGetValueOrEmpty("TRANSACTIONID");
            decimal?amount        = WA.Parser.ToDecimal(fields.TryGetValueOrEmpty("AMT"));

            string error1Code     = fields.TryGetValueOrEmpty("L_ERRORCODE0");
            string error1ShortMsg = fields.TryGetValueOrEmpty("L_SHORTMESSAGE0");
            string error1LongMsg  = fields.TryGetValueOrEmpty("L_LONGMESSAGE0");
            string error1Severity = fields.TryGetValueOrEmpty("L_SEVERITYCODE0");

            PaymentTransaction newTransaction = new PaymentTransaction();

            newTransaction.OrderId              = order.Id;
            newTransaction.PaymentProviderId    = this.ProviderId;
            newTransaction.GatewayUrl           = ProviderUrl;
            newTransaction.GatewayTransactionId = transactionId;
            newTransaction.GatewayDebugResponse = HttpUtility.UrlDecode(responseString);
            newTransaction.Amount = amount;

            PaymentStatusName paymentStatus = order.PaymentStatus;

            if (ackType == AckValues.Success || ackType == AckValues.SuccessWithWarning)
            {
                bool paymentAmountMatches = (amount.GetValueOrDefault(-1) == order.Total.Value);
                if (paymentAmountMatches)
                {
                    newTransaction.GatewayResponse = ackType.ToString();
                    paymentStatus = PaymentStatusName.Completed;
                }
                else
                {
                    newTransaction.GatewayResponse = ackType.ToString() + " Amount from Payment Provider does not match the Order amount.";
                    paymentStatus = PaymentStatusName.Pending;
                }

                if (ackType == AckValues.SuccessWithWarning)
                {
                    newTransaction.GatewayError = ackType.ToString() + string.Format(@" ErrorCode: {0}, ShortMsg: {1}, LongMsg: {2}, SeverityCode: {3}", error1Code, error1ShortMsg, error1LongMsg, error1Severity);
                }
            }
            else if (ackType == AckValues.Failure || ackType == AckValues.FailureWithWarning || ackType == AckValues.Warning)
            {
                newTransaction.GatewayError = ackType.ToString() + string.Format(@" ErrorCode: {0}, ShortMsg: {1}, LongMsg: {2}, SeverityCode: {3}", error1Code, error1ShortMsg, error1LongMsg, error1Severity);
                paymentStatus = PaymentStatusName.ProviderError;
            }
            else
            {
                newTransaction.GatewayError = ack + " Invalid / Unknown Response from Payment Provider";
                paymentStatus = PaymentStatusName.ProviderError;
            }

            newTransaction.Save();

            return(paymentStatus);
        }
        // Step 3.
        public PaymentStatusName DoExpressCheckoutPayment(Order order, Dictionary <string, string> payPalVariables)
        {
            string token   = payPalVariables["token"];
            string payerId = payPalVariables["PayerID"];

            Dictionary <string, string> vars = new Dictionary <string, string>();

            vars["METHOD"]  = "DoExpressCheckoutPayment";
            vars["VERSION"] = "60.0";

            vars["USER"]      = ApiUsername;
            vars["PWD"]       = ApiPassword;
            vars["SIGNATURE"] = ApiSignature;

            vars["TOKEN"]   = token;
            vars["PAYERID"] = payerId;

            IEnumerable <OrderItem> orderitems = order.OrderItemCollectionByOrderId;
            int itemNumber = 0;

            foreach (OrderItem orderItem in orderitems)
            {
                string orderItemAttributes = orderItem.GetProductFieldDataPlainTextDisplayString();

                vars["L_NAME" + itemNumber]   = orderItem.Name.Left(127);
                vars["L_DESC" + itemNumber]   = (!string.IsNullOrEmpty(orderItemAttributes) ? " (" + orderItemAttributes + ")" : "").Left(127);
                vars["L_AMT" + itemNumber]    = orderItem.PriceForSingleItem.ToString("N2");
                vars["L_QTY" + itemNumber]    = orderItem.Quantity.Value.ToString("N0");
                vars["L_NUMBER" + itemNumber] = (!string.IsNullOrEmpty(orderItem.Sku) ? " (" + orderItem.Sku + ")" : "");

                itemNumber++;
            }

            vars["PAYMENTACTION"] = "Sale";
            vars["AMT"]           = order.Total.Value.ToString("N2");
            vars["CURRENCYCODE"]  = order.UpToStoreByStoreId.Currency.Code;

            // Send Http POST to PayPal
            HttpWebResponse webResponse    = HttpHelper.HttpPost(ProviderUrl, vars);
            string          responseString = HttpHelper.WebResponseToString(webResponse);

            // Decode the response fields from PayPal API
            Dictionary <string, string> fields = HttpHelper.DecodeVarsFromHttpString(responseString);

            // parse response fields into variables
            string    ack     = fields["ACK"];
            AckValues ackType = WA.Enum <AckValues> .TryParseOrDefault(ack, AckValues.Failure);

            string  correlationId = fields.TryGetValueOrEmpty("CORRELATIONID");
            string  transactionId = fields.TryGetValueOrEmpty("TOKEN");
            decimal?amount        = WA.Parser.ToDecimal(fields.TryGetValueOrEmpty("AMT"));
            decimal?taxAmount     = WA.Parser.ToDecimal(fields.TryGetValueOrEmpty("TAXAMT"));
            // TODO - do we need shipping amount too?


            PaymentTransaction newTransaction = new PaymentTransaction();

            newTransaction.OrderId              = order.Id;
            newTransaction.PaymentProviderId    = this.ProviderId;
            newTransaction.GatewayUrl           = ProviderUrl;
            newTransaction.GatewayTransactionId = transactionId;
            newTransaction.GatewayResponse      = vars["METHOD"] + ": " + ack;
            newTransaction.GatewayDebugResponse = HttpUtility.UrlDecode(responseString);

            PaymentStatusName paymentStatus = order.PaymentStatus;

            if (ackType == AckValues.Success || ackType == AckValues.SuccessWithWarning)
            {
                bool paymentAmountMatches = (amount.GetValueOrDefault(-1) == order.Total.Value);
                if (paymentAmountMatches)
                {
                    paymentStatus         = PaymentStatusName.Completed;
                    newTransaction.Amount = amount;
                }
                else
                {
                    newTransaction.GatewayError = string.Format("Payment amount does not match Order Total. Order total {0:N2}. Payment amount {1:N2}", order.Total, amount);
                    if (amount >= order.Total)
                    {
                        paymentStatus         = PaymentStatusName.Completed;
                        newTransaction.Amount = amount;
                    }
                    else
                    {
                        paymentStatus = PaymentStatusName.Pending;
                    }
                }
            }
            else
            {
                newTransaction.GatewayError = ack + " Invalid / Unknown Response from Payment Provider";
                paymentStatus = PaymentStatusName.ProviderError;
            }
            newTransaction.Save();

            return(paymentStatus);
        }
        // Step 2.
        private Dictionary <string, string> GetExpressCheckoutDetails(Order order, string payPalToken)
        {
            // TODO - implement this so we can get and update the Tax, Shipping, etc. amounts for the order

            Dictionary <string, string> vars = new Dictionary <string, string>();

            vars["METHOD"]  = "GetExpressCheckoutDetails";
            vars["VERSION"] = "60.0";

            vars["USER"]      = ApiUsername;
            vars["PWD"]       = ApiPassword;
            vars["SIGNATURE"] = ApiSignature;

            vars["TOKEN"] = payPalToken;

            IEnumerable <OrderItem> orderitems = order.OrderItemCollectionByOrderId;
            int itemNumber = 0;

            foreach (OrderItem orderItem in orderitems)
            {
                string orderItemAttributes = orderItem.GetProductFieldDataPlainTextDisplayString();

                vars["L_NAME" + itemNumber]   = orderItem.Name.Left(127);
                vars["L_DESC" + itemNumber]   = (!string.IsNullOrEmpty(orderItemAttributes) ? " (" + orderItemAttributes + ")" : "").Left(127);
                vars["L_AMT" + itemNumber]    = orderItem.PriceForSingleItem.ToString("N2");
                vars["L_QTY" + itemNumber]    = orderItem.Quantity.Value.ToString("N0");
                vars["L_NUMBER" + itemNumber] = (!string.IsNullOrEmpty(orderItem.Sku) ? " (" + orderItem.Sku + ")" : "");

                itemNumber++;
            }

            // Send Http POST to PayPal
            HttpWebResponse webResponse    = HttpHelper.HttpPost(ProviderUrl, vars);
            string          responseString = HttpHelper.WebResponseToString(webResponse);

            // Decode the response fields from PayPal API
            Dictionary <string, string> fields = HttpHelper.DecodeVarsFromHttpString(responseString);

            // parse response fields into variables
            string    ack     = fields.TryGetValueOrEmpty("ACK");
            AckValues ackType = WA.Enum <AckValues> .TryParseOrDefault(ack, AckValues.Failure);

            PaymentTransaction newTransaction = new PaymentTransaction();

            newTransaction.OrderId              = order.Id;
            newTransaction.PaymentProviderId    = this.ProviderId;
            newTransaction.GatewayUrl           = ProviderUrl;
            newTransaction.GatewayTransactionId = payPalToken;
            newTransaction.GatewayResponse      = vars["METHOD"] + ": " + ack;
            newTransaction.GatewayDebugResponse = HttpUtility.UrlDecode(responseString);
            //newTransaction.Amount = order.Total;

            if (ackType == AckValues.Success || ackType == AckValues.SuccessWithWarning)
            {
                // nothing
            }
            else
            {
                newTransaction.GatewayError = ack + " Invalid / Unknown Response from Payment Provider";
            }
            newTransaction.Save();


            return(fields);
        }
        // Step 1.
        public string SetExpressCheckoutAndGetToken(Order order, string cancelUrl, string returnUrl)
        {
            Dictionary <string, string> vars = new Dictionary <string, string>();

            vars["METHOD"]  = "SetExpressCheckout";
            vars["VERSION"] = "60.0";

            vars["USER"]      = ApiUsername;
            vars["PWD"]       = ApiPassword;
            vars["SIGNATURE"] = ApiSignature;

            vars["RETURNURL"] = returnUrl;
            vars["CANCELURL"] = cancelUrl;

            //vars["CUSTOM"] = order.Id.HasValue ? order.Id.Value.ToString().Left(256) : "";
            //vars["INVNUM"] = order.Id.HasValue ? order.Id.Value.ToString().Left(127) : "";
            vars["CUSTOM"] = order.OrderNumber.Left(256);
            vars["INVNUM"] = order.OrderNumber.Left(127);

            vars["PAYMENTACTION"] = "Sale";
            vars["AMT"]           = order.Total.Value.ToString("N2");
            vars["CURRENCYCODE"]  = order.UpToStoreByStoreId.Currency.Code;

            if (order.HasNonEmptyShippingAddress())
            {
                // Address Override (for when user choose PayPal on the Payment Screen, instead of the "check out with paypal" button)
                vars["ADDROVERRIDE"] = "1";

                vars["SHIPTONAME"]        = order.ShipRecipientName + (!string.IsNullOrEmpty(order.ShipRecipientBusinessName) ? " " + order.ShipRecipientBusinessName : "");
                vars["SHIPTOSTREET"]      = order.ShipAddress1;
                vars["SHIPTOSTREET2"]     = order.ShipAddress2;
                vars["SHIPTOCITY"]        = order.ShipCity;
                vars["SHIPTOSTATE"]       = order.ShipRegion;
                vars["SHIPTOZIP"]         = order.ShipPostalCode;
                vars["SHIPTOCOUNTRYCODE"] = order.ShipCountryCode;
            }

            IEnumerable <OrderItem> orderitems = order.OrderItemCollectionByOrderId;
            int itemNumber = 0;

            foreach (OrderItem orderItem in orderitems)
            {
                string orderItemAttributes = orderItem.GetProductFieldDataPlainTextDisplayString();

                vars["L_NAME" + itemNumber]   = orderItem.Name.Left(127);
                vars["L_DESC" + itemNumber]   = (!string.IsNullOrEmpty(orderItemAttributes) ? " (" + orderItemAttributes + ")" : "").Left(127);
                vars["L_AMT" + itemNumber]    = orderItem.PriceForSingleItem.ToString("N2");
                vars["L_QTY" + itemNumber]    = orderItem.Quantity.Value.ToString("N0");
                vars["L_NUMBER" + itemNumber] = (!string.IsNullOrEmpty(orderItem.Sku) ? " (" + orderItem.Sku + ")" : "");

                itemNumber++;
            }

            // Send Http POST to PayPal
            HttpWebResponse webResponse    = HttpHelper.HttpPost(ProviderUrl, vars);
            string          responseString = HttpHelper.WebResponseToString(webResponse);

            // Decode the response fields from PayPal API
            Dictionary <string, string> fields = HttpHelper.DecodeVarsFromHttpString(responseString);

            // parse response fields into variables
            string    ack     = fields["ACK"];
            AckValues ackType = WA.Enum <AckValues> .TryParseOrDefault(ack, AckValues.Failure);

            string correlationId = fields.TryGetValueOrEmpty("CORRELATIONID");
            string transactionId = fields.TryGetValueOrEmpty("TOKEN");

            //string error1Code = fields.TryGetValueOrEmpty("L_ERRORCODE0");
            //string error1ShortMsg = fields.TryGetValueOrEmpty("L_SHORTMESSAGE0");
            //string error1LongMsg = fields.TryGetValueOrEmpty("L_LONGMESSAGE0");
            //string error1Severity = fields.TryGetValueOrEmpty("L_SEVERITYCODE0");

            PaymentTransaction newTransaction = new PaymentTransaction();

            newTransaction.OrderId              = order.Id;
            newTransaction.PaymentProviderId    = this.ProviderId;
            newTransaction.GatewayUrl           = ProviderUrl;
            newTransaction.GatewayTransactionId = transactionId;
            newTransaction.GatewayResponse      = vars["METHOD"] + ": " + ack;
            newTransaction.GatewayDebugResponse = HttpUtility.UrlDecode(responseString);
            newTransaction.Amount = order.Total;

            string token = "";

            if (ackType == AckValues.Success || ackType == AckValues.SuccessWithWarning)
            {
                token = transactionId;
            }
            else
            {
                token = "";
                newTransaction.GatewayError = ack + " Invalid / Unknown Response from Payment Provider";
            }
            newTransaction.Save();

            return(token);
        }
Esempio n. 9
0
        public void ProcessRequest(HttpContext context)
        {
            try
            {
                CardNumber = "";
                // Remove non-digits
                for (int i = 0; i < Provider.Request["CardNumber"].Length; i++)
                {
                    if (char.IsDigit(Provider.Request["CardNumber"], i))
                    {
                        CardNumber += Provider.Request["CardNumber"][i].ToString();
                    }
                }

                int year = 0;
                int.TryParse(Provider.Request["ExpiryYear"], out year);
                if (year < DateTime.Now.Year)
                {
                    throw new Exception("Son kullanma tarihi yanlış");
                }

                int month = 0;
                int.TryParse(Provider.Request["ExpiryMonth"], out month);
                if (!(month >= 1 && month <= 12))
                {
                    throw new Exception("Son kullanma tarihi yanlış");
                }

                ExpiryDate = Provider.Request["ExpiryYear"] + Provider.Request["ExpiryMonth"];
                CVV2       = Provider.Request["CVV2"];

                if (CVV2.Length != 3 || !CVV2.CanConvertToInteger())
                {
                    throw new Exception("CCV2 kodu hatalı");
                }

                CardType = (CardType)Enum.Parse(typeof(CardType), Provider.Request["CardType"]);
                string cardValid = Utility.ValidateCreditCardNumber(CardType, CardNumber);

                if (cardValid != "")
                {
                    context.Response.Write("HATA: " + cardValid);
                    return;
                }


                if (Transact())
                {
                    try
                    {
                        PaymentTransaction s = new PaymentTransaction();
                        s.Amount       = AmountInCents;
                        s.CheckoutType = CheckoutTypes.CreditCard;
                        s.Result       = Response;
                        s.Save();
                    }
                    catch (Exception ex)
                    {
                        string msg = (AmountInCents / 100d) + " TL tahsil edildi. Bu bilgi bir hata nedeniyle veritabanına kaydedilemedi. Lütfen bu bilgiyi manuel olarak kaydediniz.";
                        Provider.SendMail("Tahsilat yapıldı ama sisteme kaydedilemedi!!!", msg);
                        Provider.Log("Error", "Checkout", msg);
                    }

                    context.Response.Write("OK");
                }
                else
                {
                    context.Response.Write("HATA: Ödemenizin onaylanmasında bir hata oluştu.");
                    Provider.Log("Error", "Checkout", (AmountInCents / 100d) + " TL tahsil edilmek istendi ama servisten " + ResponseErrorNo + " nolu hata döndü. (" + ResponseErrorMessage + ")");
                }
            }
            catch (Exception ex)
            {
                context.Response.Write("HATA: " + ex.Message);
                Provider.Log("Error", "Checkout", ex.Message + (ex.InnerException != null ? "(" + ex.InnerException.Message + ")" : ""));
            }
        }
        public override PaymentStatusName ProcessDirectPaymentResponse(Order order, HttpWebResponse response)
        {
            // returned values are returned as a stream, then read into a string
            string responseString = HttpHelper.WebResponseToString(response);

            // the response string is broken into an array
            // The split character specified here must match the delimiting character specified above
            string[] fields = responseString.Split(fieldDelimiterChar);

            ResponseCode responseCode = WA.Enum <ResponseCode> .TryParseOrDefault(fields[0], ResponseCode.Error);

            string  responseSubcode    = fields[1];
            int?    responseReasonCode = WA.Parser.ToInt(fields[2]);
            string  responseReasonText = fields[3]; // could show this to the customer
            string  authorizationCode  = fields[4];
            string  avsResponse        = fields[5];
            string  transactionId      = fields[6];
            int?    orderId            = WA.Parser.ToInt(fields[7]); // "Invoice Number" in Auth.Net docs
            string  description        = fields[8];
            decimal?amount             = WA.Parser.ToDecimal(fields[9]);
            string  method             = fields[10];
            string  transactionType    = fields[11];
            string  customerId         = fields[12];
            //.... fields omitted here....
            string md5Hash          = fields[37];
            string cardCodeResponse = fields[38]; // result of CCV verification
            string cavvResponse     = fields[39]; // Cardholder Authentication Verification Response

            // Custom Merchant-Defined Fields (Pg. 36/37 of Auth.Net Docs)
            if (fields.Length >= 69) // custom fields start at position 69
            {
                // grab any add'l merchant-defined fields here...
            }

            PaymentTransaction newTransaction = new PaymentTransaction();

            newTransaction.OrderId              = order.Id;
            newTransaction.PaymentProviderId    = this.ProviderId;
            newTransaction.GatewayUrl           = ProviderUrl;
            newTransaction.GatewayTransactionId = transactionId;
            newTransaction.GatewayDebugResponse = responseString;
            newTransaction.Amount = amount;

            PaymentStatusName paymentStatus = order.PaymentStatus;

            if (responseCode == ResponseCode.Approved)
            {
                bool paymentAmountMatches = (amount.GetValueOrDefault(-1) == order.Total.Value);

                if (paymentAmountMatches)
                {
                    newTransaction.GatewayResponse = "Approved";
                    paymentStatus = PaymentStatusName.Completed;
                }
                else
                {
                    newTransaction.GatewayResponse = "Payment amount does not match the order amount.";
                    paymentStatus = PaymentStatusName.Pending;
                }
            }
            else if (responseCode == ResponseCode.Declined)
            {
                newTransaction.GatewayError = string.Format("Payment was declined. {1} (Response Reason Code: {0}).", responseReasonCode, responseReasonText);
                paymentStatus = PaymentStatusName.Denied;
            }
            else if (responseCode == ResponseCode.Error)
            {
                newTransaction.GatewayError = string.Format("{1} (Response Reason Code: {0}).", responseReasonCode, responseReasonText);
                paymentStatus = PaymentStatusName.ProviderError;
            }
            else if (responseCode == ResponseCode.HeldForReview)
            {
                newTransaction.GatewayError = string.Format("Payment has been held for review by Authorize.Net. {1} (Response Reason Code: {0}).", responseReasonCode, responseReasonText);
                paymentStatus = PaymentStatusName.Pending;
            }
            else
            {
                newTransaction.GatewayError = "Invalid / Unknown Response from Payment Provider";
                paymentStatus = PaymentStatusName.ProviderError;
            }

            newTransaction.Save();

            return(paymentStatus);
        }
        public override Dictionary <string, string> CreateOffsitePaymentRequestVariables(Order order, StoreUrls storeUrls)
        {
            Dictionary <string, string> fields = new Dictionary <string, string>();

            fields["cmd"]      = "_cart";
            fields["upload"]   = "1";
            fields["business"] = EmailAddress;
            fields["custom"]   = order.Id.Value.ToString();
            //fields["custom"] = order.OrderNumber;

            string siteWebRoot       = storeUrls.PortalUrlRoot;
            string moduleRootWebPath = storeUrls.ModuleFolderUrlRoot;

            fields["shopping_url"] = storeUrls.CategoryHome();
            fields["return"]       = storeUrls.CheckoutCompleteForOrder(order.CreatedFromCartId.Value, string.Empty, new List <string>()
            {
                "ppstdreturn=true"
            });                                                                                                                                            // URL the user is returned to after PayPal Checkout is complete
            // BEFORE 7/1/2011 FIX
            //fields["notify_url"] = string.Format("{0}DesktopModules/DNNspot-Store/PayPal/PayPalIpnHandler.aspx", moduleRootWebPath);

            fields["notify_url"] = string.Format("{0}PayPal/PayPalIpnHandler.aspx", moduleRootWebPath);

            fields["currency_code"] = order.UpToStoreByStoreId.Currency.Code;

            // populate the Cart/Order Items
            IEnumerable <OrderItem> orderitems = order.OrderItemCollectionByOrderId;
            int itemNumber = 1;

            foreach (OrderItem orderItem in orderitems)
            {
                string orderItemAttributes = orderItem.GetProductFieldDataPlainTextDisplayString();

                if (!orderItem.UpToProductByProductId.IsTaxable.GetValueOrDefault(true))
                {
                    fields["tax_rate_" + itemNumber] = "0.00";
                }
                else
                {
                    //fields["tax_rate_" + itemNumber] = TaxRegion.GetTaxRate(cart.StoreId.GetValueOrDefault(-1), taxCountry, taxRegion);
                }

                fields["item_name_" + itemNumber] = orderItem.Name + (!string.IsNullOrEmpty(orderItemAttributes) ? " (" + orderItemAttributes + ")" : "");
                //fields["amount_" + itemNumber] = orderItem.PriceTotal.Value.ToString("N2"); // WRONG! "PriceTotal" includes the Qty. multiplier!
                fields["amount_" + itemNumber]      = orderItem.PriceForSingleItem.ToString("N2");
                fields["quantity_" + itemNumber]    = orderItem.Quantity.Value.ToString("N0");
                fields["item_number_" + itemNumber] = orderItem.Sku;

                itemNumber++;
            }
            if (order.DiscountAmount.GetValueOrDefault(0) > 0)
            {
                fields["discount_amount_cart"] = order.DiscountAmount.GetValueOrDefault(0).ToString("F2");
            }

            if (order.ShippingAmount.HasValue && ShippingLogic == "Store")
            {
                //fields["shipping"] = order.ShippingAmount.Value.ToString("N2"); // doesn't seem to be honored by PayPal for cart uploads...
                fields["handling_cart"] = order.ShippingAmount.Value.ToString("N2");
            }

            if (order.HasNonEmptyShippingAddress())
            {
                fields["address1"] = order.ShipAddress1.ChopAt(100);
                fields["address2"] = order.ShipAddress2.ChopAt(100);
                fields["city"]     = order.ShipCity.ChopAt(40);
                fields["state"]    = order.ShipRegion;
                fields["zip"]      = order.ShipPostalCode.ChopAt(32);
                fields["country"]  = order.ShipCountryCode.ChopAt(2);
            }

            PaymentTransaction newTransaction = new PaymentTransaction();

            newTransaction.OrderId              = order.Id;
            newTransaction.PaymentProviderId    = this.ProviderId;
            newTransaction.GatewayUrl           = ProviderUrl;
            newTransaction.GatewayTransactionId = "";
            newTransaction.GatewayResponse      = "CreateOffsitePaymentRequest";
            newTransaction.GatewayDebugResponse = fields.ImplodeToList("=").ToDelimitedString(", ");
            newTransaction.Save();

            return(fields);
        }
        public override PaymentStatusName ProcessOffsitePaymentResponse(Order order, HttpRequest request)
        {
            //---- Need to validate the incoming request with PayPal so we know it's authentic
            Dictionary <string, string> requestParams = HttpHelper.DecodeParamsFromHttpRequest(request);
            string requestDataString = HttpHelper.EncodeVarsForHttpPostString(requestParams);

            // send our modified request back to PayPal for validation
            string          postData       = requestDataString + "&cmd=_notify-validate";
            HttpWebResponse payPalResponse = HttpHelper.HttpPost(ProviderUrl, postData);

            string payPalResponseString = HttpHelper.WebResponseToString(payPalResponse);

            // Parse response into some variables
            NameValueCollection fields = request.Params;
            string paymentStatus       = fields["payment_status"];
            string transactionId       = fields["txn_id"];
            string receiverEmail       = fields["receiver_email"];
            string businessEmail       = fields["business"];

            int?    orderId              = WA.Parser.ToInt(fields["custom"]);
            decimal?paymentAmount        = WA.Parser.ToDecimal(fields["mc_gross"]); // amount before PayPal fee is subtracted
            decimal?payPalTransactionFee = WA.Parser.ToDecimal(fields["mc_fee"]);
            decimal shippingAmount       = WA.Parser.ToDecimal(fields["mc_shipping"]).GetValueOrDefault(0);
            decimal handlingAmount       = WA.Parser.ToDecimal(fields["mc_handling"]).GetValueOrDefault(0);
            decimal taxAmount            = WA.Parser.ToDecimal(fields["tax"]).GetValueOrDefault(0);

            string firstName = fields["first_name"] ?? "";
            string lastName  = fields["last_name"] ?? "";
            string email     = fields["payer_email"] ?? "";
            string phone     = fields["contact_phone"] ?? "";

            string shipName        = fields["address_name"] ?? "";
            string shipAddress1    = fields["address_street"] ?? "";
            string shipCity        = fields["address_city"] ?? "";
            string shipRegion      = fields["address_state"] ?? "";
            string shipPostalCode  = fields["address_zip"] ?? "";
            string shipCountryCode = fields["address_country_code"] ?? "";

            PaymentStatusName paymentStatusName = order.PaymentStatus;
            bool isValidReceiverEmail           = (receiverEmail == EmailAddress) || (businessEmail == EmailAddress);

            PaymentTransaction newTransaction = new PaymentTransaction();

            newTransaction.OrderId              = orderId;
            newTransaction.PaymentProviderId    = this.ProviderId;
            newTransaction.GatewayUrl           = ProviderUrl;
            newTransaction.GatewayTransactionId = transactionId;
            newTransaction.GatewayResponse      = paymentStatus;
            newTransaction.GatewayDebugResponse = requestDataString;
            newTransaction.Amount = paymentAmount;

            if (payPalResponseString != "VERIFIED")
            {
                newTransaction.GatewayError = "Invalid/Unknown response or response could not be validated as authentic";
                newTransaction.Save();

                return(PaymentStatusName.ProviderError);
            }
            if (!isValidReceiverEmail)
            {
                newTransaction.GatewayError = "Receiver Email does not match PayPal Account";
                newTransaction.Save();

                return(PaymentStatusName.ProviderError);
            }

            //Order pendingOrder = Order.GetOrder(orderId);
            if (payPalResponseString == "VERIFIED")
            {
                // check if we have already processed this transaction successfully
                // we might already have processed the IPN callback, and the user clicks "return to store"
                // which would trigger another transaction
                PaymentTransaction priorTransaction = PaymentTransaction.GetMostRecentByTransactionId(transactionId);
                if (priorTransaction != null && priorTransaction.OrderId == orderId)
                {
                    // we have a duplicate transaction, we should NOT process this new one
                    return(order.PaymentStatus);
                }

                //check the payment_status is Completed
                bool paymentStatusComplete = (paymentStatus.ToLower() == "completed");

                if (paymentAmount.GetValueOrDefault(-1) < order.Total.Value)
                {
                    newTransaction.GatewayError = string.Format("Payment amount does not match Order Total. Order total {0:N2}. Payment amount {1:N2}", order.Total, paymentAmount);
                    newTransaction.Save();
                    return(PaymentStatusName.ProviderError);
                }

                //if (paymentStatusComplete && paymentAmountMatches && receiverEmailMatches)
                if (paymentStatusComplete)
                {
                    newTransaction.GatewayResponse = "Verified Payment Completed";
                    if (request.RawUrl.Contains("PayPalIpnHandler.aspx"))
                    {
                        newTransaction.GatewayResponse += " via IPN";
                    }
                    else if (request.RawUrl.Contains("Checkout-Complete.aspx"))
                    {
                        newTransaction.GatewayResponse += " via return button from PayPal";
                    }
                    paymentStatusName = PaymentStatusName.Completed;

                    //---- Update the Order
                    order.CustomerFirstName = firstName;
                    order.CustomerLastName  = lastName;
                    order.CustomerEmail     = email;

                    order.ShipRecipientName = shipName;
                    order.ShipAddress1      = shipAddress1;
                    //order.ShipAddress2 = shipAddress2;
                    order.ShipCity        = shipCity;
                    order.ShipRegion      = shipRegion;
                    order.ShipPostalCode  = shipPostalCode;
                    order.ShipCountryCode = shipCountryCode;
                    order.ShipTelephone   = phone;

                    order.BillAddress1 = shipAddress1;
                    //order.BillAddress2 = shipAddress2;
                    order.BillCity        = shipCity;
                    order.BillRegion      = shipRegion;
                    order.BillPostalCode  = shipPostalCode;
                    order.BillCountryCode = shipCountryCode;
                    order.BillTelephone   = phone;

                    // PayPal 'paymentAmount' is the total amount paid by customer
                    // so we need to do some basic math to get the other order amounts...
                    order.ShippingAmount = shippingAmount + handlingAmount;
                    order.TaxAmount      = taxAmount;
                    order.SubTotal       = paymentAmount - (order.ShippingAmount + order.TaxAmount);
                    order.Total          = paymentAmount;

                    order.Save();
                }
                newTransaction.Save();
            }

            return(paymentStatusName);
        }