Beispiel #1
0
        private void Page_Load(object sender, System.EventArgs e)
        {
            for (int i = 0; i < Request.Form.Count; i++)
            {
                string fValue = Server.UrlDecode(Request.Form[i]);

                switch (Request.Form.GetKey(i).ToLowerInvariant())
                {
                // Customer Variables
                case "payment_status": payment_status = fValue; break;

                case "txn_id": txn_id = fValue; break;

                case "custom": custom = fValue; break;

                case "invoice": invoice = fValue; break;

                case "pending_reason": pending_reason = fValue; break;

                case "address_name": address_name = fValue; break;

                case "address_street": address_street = fValue; break;

                case "address_city": address_city = fValue; break;

                case "address_state": address_state = fValue; break;

                case "address_zip": address_zip = fValue; break;

                case "address_country": address_country = fValue; break;

                case "payer_email": payer_email = fValue; break;

                case "parent_txn_id": parent_txn_id = fValue; break;
                }
            }

            int CustomerID = Localization.ParseNativeInt(custom);

            if (CustomerID > 0)
            {
                //Validate the post by querying PayPal
                byte[] param   = Request.BinaryRead(Request.ContentLength);
                string formStr = Encoding.ASCII.GetString(param);
                formStr += "&cmd=_notify-validate";

                string verify_url = String.Empty;

                if (AppLogic.AppConfigBool("UseLiveTransactions"))
                {
                    verify_url = AppLogic.AppConfig("PayPal.LiveServer");
                }
                else
                {
                    verify_url = AppLogic.AppConfig("PayPal.TestServer");
                }

                byte[] data = Encoding.ASCII.GetBytes(formStr);

                HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(verify_url);
                webRequest.Method        = "POST";
                webRequest.ContentType   = "application/x-www-form-urlencoded";
                webRequest.ContentLength = data.Length;

                Stream reqStream = webRequest.GetRequestStream();
                reqStream.Write(data, 0, data.Length);
                reqStream.Close();

                WebResponse webResponse;
                string      rawResponse = String.Empty;
                try
                {
                    webResponse = webRequest.GetResponse();
                    StreamReader sr = new StreamReader(webResponse.GetResponseStream());
                    rawResponse = sr.ReadToEnd();
                    sr.Close();
                    webResponse.Close();
                }
                catch (Exception exc)
                {
                    Response.Write("Error connecting with gateway. Please try again later.");
                    err_msg += exc.Message + "\n\n";
                }

                if (rawResponse.Equals("VERIFIED", StringComparison.InvariantCultureIgnoreCase))
                {
                    String status = AppLogic.ro_OK;

                    String TransactionState = AspDotNetStorefrontGateways.Processors.PayPalController.GetTransactionState(payment_status, pending_reason);

                    int ExistingOrderNumber = Localization.ParseNativeInt(invoice);

                    if (ExistingOrderNumber > 0 && !Order.OrderExists(ExistingOrderNumber))
                    { // It only is existing if it exists.
                        ExistingOrderNumber = 0;
                    }

                    if (ExistingOrderNumber == 0)
                    {
                        if (!String.IsNullOrEmpty(parent_txn_id))
                        {
                            ExistingOrderNumber = DB.GetSqlN("select min(ordernumber) N from orders where (paymentmethod = '" + AppLogic.ro_PMPayPal + "' OR paymentmethod = '" + AppLogic.ro_PMPayPalEmbeddedCheckout + "') AND charindex(" + DB.SQuote(parent_txn_id) + ",AuthorizationPNREF) > 0");
                        }
                        else
                        {
                            ExistingOrderNumber = DB.GetSqlN("select min(ordernumber) N from orders where (paymentmethod = '" + AppLogic.ro_PMPayPal + "' OR paymentmethod = '" + AppLogic.ro_PMPayPalEmbeddedCheckout + "') AND charindex(" + DB.SQuote(txn_id) + ",AuthorizationPNREF) > 0");
                        }
                    }

                    if (ExistingOrderNumber == 0) //last try - look up by paypal embedded checkout transaction
                    {
                        if (!String.IsNullOrEmpty(parent_txn_id))
                        {
                            ExistingOrderNumber = OrderTransaction.LookupOrderNumber(null, null, null, null, parent_txn_id, null, null);
                        }
                        else if (!String.IsNullOrEmpty(txn_id))
                        {
                            ExistingOrderNumber = OrderTransaction.LookupOrderNumber(null, null, null, null, txn_id, null, null);
                        }
                    }

                    // Order won't exist yet if they never followed the link from paypal back to the store.
                    if (ExistingOrderNumber == 0)
                    {
                        if (TransactionState == AppLogic.ro_TXStateAuthorized ||
                            TransactionState == AppLogic.ro_TXStatePending ||
                            TransactionState == AppLogic.ro_TXStateCaptured)
                        {
                            Customer     ThisCustomer = new Customer(CustomerID, true);
                            ShoppingCart cart         = new ShoppingCart(1, ThisCustomer, CartTypeEnum.ShoppingCart, 0, false);



                            // Cart will be empty if order already processed by paypalok.aspx
                            if (!cart.IsEmpty())
                            {
                                Address UseBillingAddress = new Address();
                                UseBillingAddress.LoadByCustomer(ThisCustomer.CustomerID, ThisCustomer.PrimaryBillingAddressID, AddressTypes.Billing);
                                UseBillingAddress.ClearCCInfo();
                                if (UseBillingAddress.PaymentMethodLastUsed != AppLogic.ro_PMPayPal && UseBillingAddress.PaymentMethodLastUsed != AppLogic.ro_PMPayPalEmbeddedCheckout)
                                {
                                    try
                                    {
                                        AppLogic.ValidatePM(AppLogic.ro_PMPayPal);
                                        UseBillingAddress.PaymentMethodLastUsed = AppLogic.ro_PMPayPal;
                                    }
                                    catch (Exception)
                                    {
                                        AppLogic.ValidatePM(AppLogic.ro_PMPayPalEmbeddedCheckout);
                                        UseBillingAddress.PaymentMethodLastUsed = AppLogic.ro_PMPayPalEmbeddedCheckout;
                                    }
                                }
                                UseBillingAddress.UpdateDB();

                                if (AppLogic.AppConfigBool("PayPal.RequireConfirmedAddress"))
                                {
                                    Address ShippingAddress = new Address();

                                    String[] StreetArray = address_street.Split(new string[1] {
                                        "\r\n"
                                    }, 2, StringSplitOptions.RemoveEmptyEntries);
                                    String Address1 = String.Empty;
                                    String Address2 = String.Empty;
                                    if (StreetArray.Length > 1)
                                    {
                                        Address1 = StreetArray[0];
                                        Address2 = StreetArray[1];
                                    }
                                    else
                                    {
                                        Address1 = address_street;
                                    }
                                    String[] NameArray = address_name.Split(new string[1] {
                                        " "
                                    }, 2, StringSplitOptions.RemoveEmptyEntries);
                                    String FirstName = String.Empty;
                                    String LastName  = String.Empty;
                                    if (NameArray.Length > 1)
                                    {
                                        FirstName = NameArray[0];
                                        LastName  = NameArray[1];
                                    }
                                    else
                                    {
                                        LastName = address_name;
                                    }
                                    string sql = String.Format("select top 1 AddressID as N from Address where Address1={0} and Address2={1} and City={2} and State={3} and Zip={4} and Country={5} and FirstName={6} and LastName={7} and CustomerID={8}",
                                                               DB.SQuote(Address1), DB.SQuote(Address2), DB.SQuote(address_city), DB.SQuote(address_state),
                                                               DB.SQuote(address_zip), DB.SQuote(address_country), DB.SQuote(FirstName), DB.SQuote(LastName), CustomerID);
                                    int ExistingAddressID = DB.GetSqlN(sql);

                                    if (ExistingAddressID == 0 || ThisCustomer.PrimaryShippingAddressID != ExistingAddressID)
                                    {
                                        string note      = "Note: Customer selected Ship-To address at PayPal.com";
                                        string ordernote = DB.GetSqlS("select OrderNotes S from Customer where CustomerID=" + ThisCustomer.CustomerID.ToString());
                                        if (!ordernote.Contains(note))
                                        {
                                            ordernote += System.Environment.NewLine + note;
                                            DB.ExecuteSQL("update Customer set OrderNotes=" + DB.SQuote(ordernote) + " where CustomerID=" + ThisCustomer.CustomerID.ToString());
                                        }
                                    }

                                    if (ExistingAddressID == 0)
                                    { // Does not exist
                                        ShippingAddress.CustomerID = CustomerID;
                                        ShippingAddress.FirstName  = FirstName;
                                        ShippingAddress.LastName   = LastName;
                                        ShippingAddress.Address1   = Address1;
                                        ShippingAddress.Address2   = Address2;
                                        ShippingAddress.City       = address_city;
                                        ShippingAddress.State      = address_state;
                                        ShippingAddress.Zip        = address_zip;
                                        ShippingAddress.Country    = address_country;
                                        ShippingAddress.EMail      = payer_email;
                                        ShippingAddress.InsertDB();

                                        ShippingAddress.MakeCustomersPrimaryAddress(AddressTypes.Shipping);
                                    }
                                    else
                                    { // Exists already
                                        ShippingAddress.LoadFromDB(ExistingAddressID);
                                        ShippingAddress.MakeCustomersPrimaryAddress(AddressTypes.Shipping);
                                    }
                                }

                                // Reload customer and cart so that we have the addresses right
                                ThisCustomer = new Customer(CustomerID, true);
                                cart         = new ShoppingCart(1, ThisCustomer, CartTypeEnum.ShoppingCart, 0, false);
                                decimal CartTotal = cart.Total(true);
                                decimal NetTotal  = CartTotal - CommonLogic.IIF(cart.Coupon.CouponType == CouponTypeEnum.GiftCard, CommonLogic.IIF(CartTotal < cart.Coupon.DiscountAmount, CartTotal, cart.Coupon.DiscountAmount), 0);
                                NetTotal = Localization.ParseNativeDecimal(Localization.CurrencyStringForGatewayWithoutExchangeRate(NetTotal));
                                decimal PaymentTotal = CommonLogic.FormNativeDecimal("mc_gross");

                                // Cart will be empty if order already processed by paypalok.aspx
                                if (!cart.IsEmpty() && NetTotal > 0.0M)
                                {
                                    //Process as AuthOnly first
                                    int OrderNumber = AppLogic.GetNextOrderNumber();
                                    status = Gateway.MakeOrder(String.Empty, AppLogic.ro_TXModeAuthOnly, cart, OrderNumber, String.Empty, String.Empty, txn_id, String.Empty);

                                    if (status == AppLogic.ro_OK)
                                    {
                                        if (TransactionState == AppLogic.ro_TXStateCaptured)
                                        { // Now, if paid for, process as Captured
                                            Gateway.ProcessOrderAsCaptured(OrderNumber);
                                            DB.ExecuteSQL("update orders set AuthorizationPNREF=AuthorizationPNREF+" + DB.SQuote("|CAPTURE=" + txn_id) + " where OrderNumber=" + OrderNumber.ToString());
                                        }
                                        else if (TransactionState == AppLogic.ro_TXStatePending)
                                        {
                                            DB.ExecuteSQL("update orders set TransactionState=" + DB.SQuote(AppLogic.ro_TXStatePending) + " where OrderNumber=" + OrderNumber.ToString());
                                        }
                                    }

                                    // The incoming payment should match the cart total, if they don't
                                    // the customer may have tampered with the cart to cheat, so flag as fraud
                                    // but keep new so the admin will have to review the order.
                                    if (Math.Abs(NetTotal - PaymentTotal) > 0.05M) // allow 0.05 descrepency to allow minor rounding errors
                                    {
                                        Order.MarkOrderAsFraud(OrderNumber, true);
                                        DB.ExecuteSQL("update orders set FraudedOn=getdate(), IsNew=1 where OrderNumber=" + OrderNumber.ToString());
                                    }
                                    else
                                    {
                                        // Finalize the order here since they may never click through to orderconfirmation.aspx
                                        Order  ord = new Order(OrderNumber, ThisCustomer.LocaleSetting);
                                        String PM  = AppLogic.CleanPaymentMethod(ord.PaymentMethod);
                                        if (!ord.AlreadyConfirmed)
                                        {
                                            DB.ExecuteSQL("update Customer set OrderOptions=NULL, OrderNotes=NULL, FinalizationData=NULL where CustomerID=" + CustomerID.ToString());

                                            if (ord.TransactionIsCaptured() && ord.HasGiftRegistryComponents())
                                            {
                                                ord.FinalizeGiftRegistryComponents();
                                            }
                                            AppLogic.SendOrderEMail(ThisCustomer, OrderNumber, false, PM, true, null, null);
                                            DB.ExecuteSQL("Update Orders set AlreadyConfirmed=1 where OrderNumber=" + OrderNumber.ToString());
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else  // we have an existing order
                    {
                        if (TransactionState == AppLogic.ro_TXStateVoided)
                        {
                            IPNVoid(ExistingOrderNumber);
                        }
                        else if (TransactionState == AppLogic.ro_TXStateCaptured)
                        {
                            IPNCapture(ExistingOrderNumber, txn_id, CommonLogic.FormNativeDecimal("mc_gross"));
                        }
                        else if (TransactionState == AppLogic.ro_TXStateRefunded)
                        {
                            IPNRefund(ExistingOrderNumber, txn_id, CommonLogic.FormNativeDecimal("mc_gross"));
                        }
                        else if (TransactionState == AppLogic.ro_TXStatePending)
                        { // eChecks could have had the order placed in Captured state with Express Checkout
                            DB.ExecuteSQL("update orders set CapturedOn=NULL, TransactionState=" + DB.SQuote(AppLogic.ro_TXStatePending) + " where OrderNumber=" + ExistingOrderNumber.ToString());
                        }

                        OrderTransactionCollection transactions = new OrderTransactionCollection(ExistingOrderNumber);
                        transactions.AddTransaction(TransactionState, null, null, null, txn_id, AppLogic.ro_PMPayPal + " IPN", null, CommonLogic.FormNativeDecimal("mc_gross"));
                    }
                }
                else
                {
                }
            }
        }
Beispiel #2
0
        public ActionResult Index(FormCollection collection)
        {
            SysLog.LogMessage(
                message: "Received a recurring payment notification from PayPal Express.",
                details: Gateway.ListFormCollectionKeyValuePairs(collection),
                messageType: MessageTypeEnum.Informational,
                messageSeverity: MessageSeverityEnum.Alert);

            if (!PostIsValid())
            {
                return(Content(string.Empty));
            }

            var paymentStatus       = collection["payment_status"] ?? string.Empty;
            var transactionId       = collection["txn_id"] ?? string.Empty;
            var pendingReason       = collection["pending_reason"] ?? string.Empty;
            var parentTransactionId = collection["parent_txn_id"] ?? string.Empty;
            var transactionType     = collection["txn_type"] ?? string.Empty;
            var payerId             = collection["payer_id"] ?? string.Empty;
            var profileId           = collection["recurring_payment_id"] ?? string.Empty;
            var subscriptionId      = collection["subscr_id"] ?? string.Empty;
            var paymentTotal        = CommonLogic.FormNativeDecimal("mc_gross");

            //Recurring notification
            if (transactionType.ToLowerInvariant().Contains("recurring") ||
                transactionType.ToLowerInvariant().Contains("subscr_cancel"))
            {
                HandlePayPalExpressCheckoutRecurringNotification(transactionType, payerId, profileId, subscriptionId);
            }

            // Normal notification
            var transactionState    = PayPalController.GetTransactionState(paymentStatus, pendingReason);
            var existingOrderNumber = GetPPECOriginalOrderNumber(profileId, subscriptionId);

            if (existingOrderNumber > 0 && !Order.OrderExists(existingOrderNumber))
            {
                existingOrderNumber = 0;
            }

            if (existingOrderNumber == 0)               //Was it a PayPal Express order?
            {
                existingOrderNumber = DB.GetSqlN(
                    string.Format("SELECT MIN(OrderNumber) N FROM Orders WHERE (PaymentMethod = '{0}') AND CHARINDEX({1}, AuthorizationPNREF) > 0",
                                  AppLogic.ro_PMPayPalExpress,
                                  string.IsNullOrEmpty(parentTransactionId)
                                                ? DB.SQuote(transactionId)
                                                : DB.SQuote(parentTransactionId)));
            }

            if (existingOrderNumber == 0)            //Last try - look up by paypal payments advanced checkout transaction
            {
                if (!string.IsNullOrEmpty(parentTransactionId))
                {
                    existingOrderNumber = OrderTransaction.LookupOrderNumber(null, null, null, null, parentTransactionId, null, null);
                }
                else if (!string.IsNullOrEmpty(transactionId))
                {
                    existingOrderNumber = OrderTransaction.LookupOrderNumber(null, null, null, null, transactionId, null, null);
                }
            }

            if (existingOrderNumber == 0)
            {
                return(Content(string.Empty));
            }

            if (transactionState == AppLogic.ro_TXStateVoided)
            {
                VoidPPOrder(existingOrderNumber);
            }
            else if (transactionState == AppLogic.ro_TXStateCaptured)
            {
                CapturePPOrder(existingOrderNumber, transactionId, paymentTotal);
            }
            else if (transactionState == AppLogic.ro_TXStateRefunded)
            {
                RefundPPOrder(existingOrderNumber, transactionId, paymentTotal);
            }
            else if (transactionState == AppLogic.ro_TXStatePending)
            {
                DB.ExecuteSQL(string.Format("UPDATE Orders SET CapturedOn = NULL, TransactionState = {0} WHERE OrderNumber = {1}", DB.SQuote(AppLogic.ro_TXStatePending), existingOrderNumber));
            }

            OrderTransactionCollection transactions = new OrderTransactionCollection(existingOrderNumber);

            transactions.AddTransaction(transactionState, null, null, null, transactionId, AppLogic.ro_PMPayPalExpress + " IPN", null, paymentTotal);

            return(Content(string.Empty));
        }
        string subscriptionID  = String.Empty; // PayPal Standard

        private void Page_Load(object sender, System.EventArgs e)
        {
            //String postData = String.IsNullOrEmpty(Request.Form.ToString()) ? Request.QueryString.ToString() : Request.Form.ToString();
            //SysLog.LogMessage("Paypal notification posted to.", postData, MessageTypeEnum.Informational, MessageSeverityEnum.Alert);

            for (int i = 0; i < Request.Form.Count; i++)
            {
                string fValue = Server.UrlDecode(Request.Form[i]);

                switch (Request.Form.GetKey(i).ToLowerInvariant())
                {
                // Customer Variables
                case "payment_status": payment_status = fValue; break;

                case "txn_id": txn_id = fValue; break;

                case "custom": custom = fValue; break;

                case "invoice": invoice = fValue; break;

                case "pending_reason": pending_reason = fValue; break;

                case "address_name": address_name = fValue; break;

                case "address_street": address_street = fValue; break;

                case "address_city": address_city = fValue; break;

                case "address_state": address_state = fValue; break;

                case "address_zip": address_zip = fValue; break;

                case "address_country": address_country = fValue; break;

                case "payer_email": payer_email = fValue; break;

                case "parent_txn_id": parent_txn_id = fValue; break;

                case "txn_type": txn_type = fValue; break;

                case "payer_id": payerID = fValue; break;

                case "recurring_payment_id": profileID = fValue; break;

                case "subscr_id": subscriptionID = fValue; break;
                }
            }

            // PayPal Express Checkout recurring notification
            if (txn_type.ToLowerInvariant().Contains("recurring") || txn_type.ToLowerInvariant().Contains("subscr_cancel") && PostIsValid())
            {
                HandlePayPalExpressCheckoutRecurringNotification();
            }

            // Non-recurring notification
            int CustomerID = Localization.ParseNativeInt(custom);

            if (CustomerID > 0 && PostIsValid())
            {
                String status = AppLogic.ro_OK;

                String TransactionState = AspDotNetStorefrontGateways.Processors.PayPalController.GetTransactionState(payment_status, pending_reason);

                int ExistingOrderNumber = Localization.ParseNativeInt(invoice);

                if (ExistingOrderNumber > 0 && !Order.OrderExists(ExistingOrderNumber))
                { // It only is existing if it exists.
                    ExistingOrderNumber = 0;
                }

                if (ExistingOrderNumber == 0)
                {
                    if (!String.IsNullOrEmpty(parent_txn_id))
                    {
                        ExistingOrderNumber = DB.GetSqlN("select min(ordernumber) N from orders where (paymentmethod = '" + AppLogic.ro_PMPayPal + "' OR paymentmethod = '" + AppLogic.ro_PMPayPalEmbeddedCheckout + "') AND charindex(" + DB.SQuote(parent_txn_id) + ",AuthorizationPNREF) > 0");
                    }
                    else
                    {
                        ExistingOrderNumber = DB.GetSqlN("select min(ordernumber) N from orders where (paymentmethod = '" + AppLogic.ro_PMPayPal + "' OR paymentmethod = '" + AppLogic.ro_PMPayPalEmbeddedCheckout + "') AND charindex(" + DB.SQuote(txn_id) + ",AuthorizationPNREF) > 0");
                    }
                }

                if (ExistingOrderNumber == 0) //last try - look up by paypal payments advanced checkout transaction
                {
                    if (!String.IsNullOrEmpty(parent_txn_id))
                    {
                        ExistingOrderNumber = OrderTransaction.LookupOrderNumber(null, null, null, null, parent_txn_id, null, null);
                    }
                    else if (!String.IsNullOrEmpty(txn_id))
                    {
                        ExistingOrderNumber = OrderTransaction.LookupOrderNumber(null, null, null, null, txn_id, null, null);
                    }
                }

                // Order won't exist yet if they never followed the link from paypal back to the store.
                if (ExistingOrderNumber == 0)
                {
                    if (TransactionState == AppLogic.ro_TXStateAuthorized ||
                        TransactionState == AppLogic.ro_TXStatePending ||
                        TransactionState == AppLogic.ro_TXStateCaptured)
                    {
                        Customer     ThisCustomer = new Customer(CustomerID, true);
                        ShoppingCart cart         = new ShoppingCart(1, ThisCustomer, CartTypeEnum.ShoppingCart, 0, false);



                        // Cart will be empty if order already processed by paypalok.aspx
                        if (!cart.IsEmpty())
                        {
                            Address UseBillingAddress = new Address();
                            UseBillingAddress.LoadByCustomer(ThisCustomer.CustomerID, ThisCustomer.PrimaryBillingAddressID, AddressTypes.Billing);
                            UseBillingAddress.ClearCCInfo();
                            if (UseBillingAddress.PaymentMethodLastUsed != AppLogic.ro_PMPayPal && UseBillingAddress.PaymentMethodLastUsed != AppLogic.ro_PMPayPalEmbeddedCheckout)
                            {
                                try
                                {
                                    AppLogic.ValidatePM(AppLogic.ro_PMPayPal);
                                    UseBillingAddress.PaymentMethodLastUsed = AppLogic.ro_PMPayPal;
                                }
                                catch (Exception)
                                {
                                    AppLogic.ValidatePM(AppLogic.ro_PMPayPalEmbeddedCheckout);
                                    UseBillingAddress.PaymentMethodLastUsed = AppLogic.ro_PMPayPalEmbeddedCheckout;
                                }
                            }
                            UseBillingAddress.UpdateDB();

                            if (AppLogic.AppConfigBool("PayPal.RequireConfirmedAddress"))
                            {
                                Address ShippingAddress = new Address();

                                String[] StreetArray = address_street.Split(new string[1] {
                                    "\r\n"
                                }, 2, StringSplitOptions.RemoveEmptyEntries);
                                String Address1 = String.Empty;
                                String Address2 = String.Empty;
                                if (StreetArray.Length > 1)
                                {
                                    Address1 = StreetArray[0];
                                    Address2 = StreetArray[1];
                                }
                                else
                                {
                                    Address1 = address_street;
                                }
                                String[] NameArray = address_name.Split(new string[1] {
                                    " "
                                }, 2, StringSplitOptions.RemoveEmptyEntries);
                                String FirstName = String.Empty;
                                String LastName  = String.Empty;
                                if (NameArray.Length > 1)
                                {
                                    FirstName = NameArray[0];
                                    LastName  = NameArray[1];
                                }
                                else
                                {
                                    LastName = address_name;
                                }
                                string sql = String.Format("select top 1 AddressID as N from Address where Address1={0} and Address2={1} and City={2} and State={3} and Zip={4} and Country={5} and FirstName={6} and LastName={7} and CustomerID={8}",
                                                           DB.SQuote(Address1), DB.SQuote(Address2), DB.SQuote(address_city), DB.SQuote(address_state),
                                                           DB.SQuote(address_zip), DB.SQuote(address_country), DB.SQuote(FirstName), DB.SQuote(LastName), CustomerID);
                                int ExistingAddressID = DB.GetSqlN(sql);

                                if (ExistingAddressID == 0 || ThisCustomer.PrimaryShippingAddressID != ExistingAddressID)
                                {
                                    string note      = "Note: Customer selected Ship-To address at PayPal.com";
                                    string ordernote = DB.GetSqlS("select OrderNotes S from Customer where CustomerID=" + ThisCustomer.CustomerID.ToString());
                                    if (!ordernote.Contains(note))
                                    {
                                        ordernote += System.Environment.NewLine + note;
                                        DB.ExecuteSQL("update Customer set OrderNotes=" + DB.SQuote(ordernote) + " where CustomerID=" + ThisCustomer.CustomerID.ToString());
                                    }
                                }

                                if (ExistingAddressID == 0)
                                { // Does not exist
                                    ShippingAddress.CustomerID = CustomerID;
                                    ShippingAddress.FirstName  = FirstName;
                                    ShippingAddress.LastName   = LastName;
                                    ShippingAddress.Address1   = Address1;
                                    ShippingAddress.Address2   = Address2;
                                    ShippingAddress.City       = address_city;
                                    ShippingAddress.State      = address_state;
                                    ShippingAddress.Zip        = address_zip;
                                    ShippingAddress.Country    = address_country;
                                    ShippingAddress.EMail      = payer_email;
                                    ShippingAddress.InsertDB();

                                    ShippingAddress.MakeCustomersPrimaryAddress(AddressTypes.Shipping);
                                }
                                else
                                { // Exists already
                                    ShippingAddress.LoadFromDB(ExistingAddressID);
                                    ShippingAddress.MakeCustomersPrimaryAddress(AddressTypes.Shipping);
                                }
                            }

                            // Reload customer and cart so that we have the addresses right
                            ThisCustomer = new Customer(CustomerID, true);
                            cart         = new ShoppingCart(1, ThisCustomer, CartTypeEnum.ShoppingCart, 0, false);
                            decimal CartTotal = cart.Total(true);
                            decimal NetTotal  = CartTotal - CommonLogic.IIF(cart.Coupon.CouponType == CouponTypeEnum.GiftCard, CommonLogic.IIF(CartTotal < cart.Coupon.DiscountAmount, CartTotal, cart.Coupon.DiscountAmount), 0);
                            NetTotal = Localization.ParseNativeDecimal(Localization.CurrencyStringForGatewayWithoutExchangeRate(NetTotal));
                            decimal PaymentTotal = CommonLogic.FormNativeDecimal("mc_gross");

                            // Cart will be empty if order already processed by paypalok.aspx
                            if (!cart.IsEmpty() && NetTotal > 0.0M)
                            {
                                //Process as AuthOnly first
                                int OrderNumber = AppLogic.GetNextOrderNumber();
                                status = Gateway.MakeOrder(String.Empty, AppLogic.ro_TXModeAuthOnly, cart, OrderNumber, String.Empty, String.Empty, txn_id, String.Empty);

                                if (status == AppLogic.ro_OK)
                                {
                                    if (subscriptionID.Length > 0)
                                    {
                                        String         sql = "update orders set RecurringSubscriptionID = @SubscriptionID where OrderNumber = @OrderNumber";
                                        SqlParameter[] orderNumberParams = { new SqlParameter("@SubscriptionID", SqlDbType.NVarChar, 100)
                                                                             {
                                                                                 Value = subscriptionID
                                                                             },                                  new SqlParameter("@OrderNumber", SqlDbType.Int)
                                                                             {
                                                                                 Value = OrderNumber
                                                                             } };
                                        DB.ExecuteSQL(sql, orderNumberParams);

                                        OrderTransactionCollection ecRecurringOrderTransaction = new OrderTransactionCollection(OrderNumber);
                                        ecRecurringOrderTransaction.AddTransaction("PayPal Standard Checkout Subscription Profile Creation",
                                                                                   string.Empty,
                                                                                   string.Empty,
                                                                                   string.Empty,
                                                                                   subscriptionID,
                                                                                   AppLogic.ro_PMPayPal,
                                                                                   null,
                                                                                   NetTotal);
                                    }

                                    if (TransactionState == AppLogic.ro_TXStateCaptured)
                                    { // Now, if paid for, process as Captured
                                        Gateway.ProcessOrderAsCaptured(OrderNumber);
                                        DB.ExecuteSQL("update orders set AuthorizationPNREF=AuthorizationPNREF+" + DB.SQuote("|CAPTURE=" + txn_id) + " where OrderNumber=" + OrderNumber.ToString());
                                    }
                                    else if (TransactionState == AppLogic.ro_TXStatePending)
                                    {
                                        DB.ExecuteSQL("update orders set TransactionState=" + DB.SQuote(AppLogic.ro_TXStatePending) + " where OrderNumber=" + OrderNumber.ToString());
                                    }
                                }

                                // The incoming payment should match the cart total, if they don't
                                // the customer may have tampered with the cart to cheat, so flag as fraud
                                // but keep new so the admin will have to review the order.
                                if (Math.Abs(NetTotal - PaymentTotal) > 0.05M) // allow 0.05 descrepency to allow minor rounding errors
                                {
                                    Order.MarkOrderAsFraud(OrderNumber, true);
                                    DB.ExecuteSQL("update orders set FraudedOn=getdate(), IsNew=1 where OrderNumber=" + OrderNumber.ToString());
                                }
                                else
                                {
                                    // Finalize the order here since they may never click through to orderconfirmation.aspx
                                    Order  ord = new Order(OrderNumber, ThisCustomer.LocaleSetting);
                                    String PM  = AppLogic.CleanPaymentMethod(ord.PaymentMethod);
                                    if (!ord.AlreadyConfirmed)
                                    {
                                        DB.ExecuteSQL("update Customer set OrderOptions=NULL, OrderNotes=NULL, FinalizationData=NULL where CustomerID=" + CustomerID.ToString());

                                        if (ord.TransactionIsCaptured() && ord.HasGiftRegistryComponents())
                                        {
                                            ord.FinalizeGiftRegistryComponents();
                                        }
                                        AppLogic.SendOrderEMail(ThisCustomer, OrderNumber, false, PM, true, null, null);
                                        DB.ExecuteSQL("Update Orders set AlreadyConfirmed=1 where OrderNumber=" + OrderNumber.ToString());
                                    }
                                }
                            }
                        }
                    }
                }
                else  // we have an existing order
                {
                    if (TransactionState == AppLogic.ro_TXStateVoided)
                    {
                        IPNVoid(ExistingOrderNumber);
                    }
                    else if (TransactionState == AppLogic.ro_TXStateCaptured)
                    {
                        IPNCapture(ExistingOrderNumber, txn_id, CommonLogic.FormNativeDecimal("mc_gross"));
                    }
                    else if (TransactionState == AppLogic.ro_TXStateRefunded)
                    {
                        IPNRefund(ExistingOrderNumber, txn_id, CommonLogic.FormNativeDecimal("mc_gross"));
                    }
                    else if (TransactionState == AppLogic.ro_TXStatePending)
                    { // eChecks could have had the order placed in Captured state with Express Checkout
                        DB.ExecuteSQL("update orders set CapturedOn=NULL, TransactionState=" + DB.SQuote(AppLogic.ro_TXStatePending) + " where OrderNumber=" + ExistingOrderNumber.ToString());
                    }

                    OrderTransactionCollection transactions = new OrderTransactionCollection(ExistingOrderNumber);
                    transactions.AddTransaction(TransactionState, null, null, null, txn_id, AppLogic.ro_PMPayPal + " IPN", null, CommonLogic.FormNativeDecimal("mc_gross"));
                }
            }
        }