/// <summary>
        /// Inserts a recurring payment history entry
        /// </summary>
        /// <param name="recurringPaymentHistory">Recurring payment history entry</param>
        public virtual void InsertRecurringPaymentHistory(RecurringPaymentHistory recurringPaymentHistory)
        {
            if (recurringPaymentHistory == null)
            {
                throw new ArgumentNullException(nameof(recurringPaymentHistory));
            }

            _recurringPaymentHistoryRepository.Insert(recurringPaymentHistory);

            //event notification
            _eventPublisher.EntityInserted(recurringPaymentHistory);
        }
        public void Can_save_and_load_recurringPaymentHistory()
        {
            var rph = new RecurringPaymentHistory()
            {
                CreatedOnUtc     = new DateTime(2010, 01, 03),
                RecurringPayment = new RecurringPayment()
                {
                    StartDateUtc = new DateTime(2010, 01, 01),
                    CreatedOnUtc = new DateTime(2010, 01, 02),
                    InitialOrder = GetTestOrder(),
                },
            };

            var fromDb = SaveAndLoadEntity(rph);

            fromDb.ShouldNotBeNull();
            fromDb.CreatedOnUtc.ShouldEqual(new DateTime(2010, 01, 03));

            fromDb.RecurringPayment.ShouldNotBeNull();
            fromDb.RecurringPayment.StartDateUtc.ShouldEqual(new DateTime(2010, 01, 01));
        }
        protected virtual void PrepareRecurringPaymentHistoryModel(RecurringPaymentModel.RecurringPaymentHistoryModel model,
                                                                   RecurringPaymentHistory history)
        {
            if (model == null)
            {
                throw new ArgumentNullException("model");
            }

            if (history == null)
            {
                throw new ArgumentNullException("history");
            }

            var order = _orderService.GetOrderById(history.OrderId);

            model.Id                 = history.Id;
            model.OrderId            = history.OrderId;
            model.RecurringPaymentId = history.RecurringPaymentId;
            model.OrderStatus        = order.OrderStatus.GetLocalizedEnum(_localizationService, _workContext);
            model.PaymentStatus      = order.PaymentStatus.GetLocalizedEnum(_localizationService, _workContext);
            model.ShippingStatus     = order.ShippingStatus.GetLocalizedEnum(_localizationService, _workContext);
            model.CreatedOn          = _dateTimeHelper.ConvertToUserTime(history.CreatedOnUtc, DateTimeKind.Utc);
        }
        public ActionResult IPNHandler()
        {
            byte[] param      = Request.BinaryRead(Request.ContentLength);
            var    strRequest = Encoding.UTF8.GetString(param);

            if (!PaymentService.IsPaymentMethodActive(SystemName, Services.StoreContext.CurrentStore.Id))
            {
                Logger.Warn(new SmartException(strRequest), T("Plugins.Payments.PayPal.NoModuleLoading", "IPNHandler"));
                return(Content(string.Empty));
            }

            var sb = new StringBuilder();
            Dictionary <string, string> values;
            var settings = Services.Settings.LoadSetting <TSetting>();

            if (VerifyIPN(settings, strRequest, out values))
            {
                #region values

                decimal total = decimal.Zero;
                try
                {
                    total = decimal.Parse(values["mc_gross"], new CultureInfo("en-US"));
                }
                catch { }

                string payer_status = string.Empty;
                values.TryGetValue("payer_status", out payer_status);
                string payment_status = string.Empty;
                values.TryGetValue("payment_status", out payment_status);
                string pending_reason = string.Empty;
                values.TryGetValue("pending_reason", out pending_reason);
                string mc_currency = string.Empty;
                values.TryGetValue("mc_currency", out mc_currency);
                string txn_id = string.Empty;
                values.TryGetValue("txn_id", out txn_id);
                string txn_type = string.Empty;
                values.TryGetValue("txn_type", out txn_type);
                string rp_invoice_id = string.Empty;
                values.TryGetValue("rp_invoice_id", out rp_invoice_id);
                string payment_type = string.Empty;
                values.TryGetValue("payment_type", out payment_type);
                string payer_id = string.Empty;
                values.TryGetValue("payer_id", out payer_id);
                string receiver_id = string.Empty;
                values.TryGetValue("receiver_id", out receiver_id);
                string invoice = string.Empty;
                values.TryGetValue("invoice", out invoice);
                string payment_fee = string.Empty;
                values.TryGetValue("payment_fee", out payment_fee);

                #endregion

                sb.AppendLine("PayPal IPN:");
                foreach (KeyValuePair <string, string> kvp in values.Where(x => x.Value.HasValue()))
                {
                    sb.AppendLine(kvp.Key + ": " + kvp.Value);
                }

                switch (txn_type)
                {
                case "recurring_payment_profile_created":
                    //do nothing here
                    break;

                case "recurring_payment":
                    #region Recurring payment
                {
                    Guid orderNumberGuid = Guid.Empty;
                    try
                    {
                        orderNumberGuid = new Guid(rp_invoice_id);
                    }
                    catch { }

                    var initialOrder = OrderService.GetOrderByGuid(orderNumberGuid);
                    if (initialOrder != null)
                    {
                        var newPaymentStatus  = GetPaymentStatus(payment_status, pending_reason, total, initialOrder.OrderTotal);
                        var recurringPayments = OrderService.SearchRecurringPayments(0, 0, initialOrder.Id, null);

                        foreach (var rp in recurringPayments)
                        {
                            switch (newPaymentStatus)
                            {
                            case PaymentStatus.Authorized:
                            case PaymentStatus.Paid:
                            {
                                var recurringPaymentHistory = rp.RecurringPaymentHistory;
                                if (recurringPaymentHistory.Count == 0)
                                {
                                    //first payment
                                    var rph = new RecurringPaymentHistory
                                    {
                                        RecurringPaymentId = rp.Id,
                                        OrderId            = initialOrder.Id,
                                        CreatedOnUtc       = DateTime.UtcNow
                                    };
                                    rp.RecurringPaymentHistory.Add(rph);
                                    OrderService.UpdateRecurringPayment(rp);
                                }
                                else
                                {
                                    //next payments
                                    OrderProcessingService.ProcessNextRecurringPayment(rp);
                                }
                            }
                            break;
                            }
                        }

                        Logger.Info(new SmartException(sb.ToString()), T("Plugins.Payments.PayPal.IpnRecurringPaymentInfo"));
                    }
                    else
                    {
                        if (rp_invoice_id.IsEmpty())
                        {
                            Logger.Warn(new SmartException(sb.ToString()), T("Plugins.Payments.PayPal.IpnIrregular", "rp_invoice_id"));
                        }
                        else
                        {
                            Logger.Error(new SmartException(sb.ToString()), T("Plugins.Payments.PayPal.IpnOrderNotFound"));
                        }
                    }
                }
                    #endregion
                    break;

                default:
                    #region Standard payment
                {
                    var orderNumber     = "";
                    var orderNumberGuid = Guid.Empty;
                    values.TryGetValue("custom", out orderNumber);

                    try
                    {
                        orderNumberGuid = new Guid(orderNumber);
                    }
                    catch { }

                    var order = OrderService.GetOrderByGuid(orderNumberGuid);
                    if (order != null)
                    {
                        order.HasNewPaymentNotification = true;

                        OrderService.AddOrderNote(order, sb.ToString());

                        if (settings.IpnChangesPaymentStatus)
                        {
                            var newPaymentStatus = GetPaymentStatus(payment_status, pending_reason, total, order.OrderTotal);

                            switch (newPaymentStatus)
                            {
                            case PaymentStatus.Pending:
                                break;

                            case PaymentStatus.Authorized:
                                if (OrderProcessingService.CanMarkOrderAsAuthorized(order))
                                {
                                    OrderProcessingService.MarkAsAuthorized(order);
                                }
                                break;

                            case PaymentStatus.Paid:
                                if (OrderProcessingService.CanMarkOrderAsPaid(order))
                                {
                                    OrderProcessingService.MarkOrderAsPaid(order);
                                }
                                break;

                            case PaymentStatus.Refunded:
                                if (OrderProcessingService.CanRefundOffline(order))
                                {
                                    OrderProcessingService.RefundOffline(order);
                                }
                                break;

                            case PaymentStatus.PartiallyRefunded:
                                if (OrderProcessingService.CanPartiallyRefundOffline(order, Math.Abs(total)))
                                {
                                    OrderProcessingService.PartiallyRefundOffline(order, Math.Abs(total));
                                }
                                break;

                            case PaymentStatus.Voided:
                                if (OrderProcessingService.CanVoidOffline(order))
                                {
                                    OrderProcessingService.VoidOffline(order);
                                }
                                break;

                            default:
                                break;
                            }
                        }
                    }
                    else
                    {
                        if (orderNumber.IsEmpty())
                        {
                            Logger.Warn(new SmartException(sb.ToString()), T("Plugins.Payments.PayPal.IpnIrregular", "custom"));
                        }
                        else
                        {
                            Logger.Error(new SmartException(sb.ToString()), T("Plugins.Payments.PayPal.IpnOrderNotFound"));
                        }
                    }
                }
                    #endregion
                    break;
                }
            }
            else
            {
                Logger.Error(new SmartException(strRequest), T("Plugins.Payments.PayPal.IpnFailed"));
            }

            //nothing should be rendered to visitor
            return(Content(""));
        }
Ejemplo n.º 5
0
 /// <summary>
 /// Inserts a recurring payment history entry
 /// </summary>
 /// <param name="recurringPaymentHistory">Recurring payment history entry</param>
 /// <returns>A task that represents the asynchronous operation</returns>
 public virtual async Task InsertRecurringPaymentHistoryAsync(RecurringPaymentHistory recurringPaymentHistory)
 {
     await _recurringPaymentHistoryRepository.InsertAsync(recurringPaymentHistory);
 }
Ejemplo n.º 6
0
        public ActionResult IPNHandler()
        {
            Debug.WriteLine("PayPal Direct IPN: {0}".FormatWith(Request.ContentLength));

            byte[] param      = Request.BinaryRead(Request.ContentLength);
            string strRequest = Encoding.ASCII.GetString(param);
            Dictionary <string, string> values;

            var provider  = _paymentService.LoadPaymentMethodBySystemName("Payments.PayPalDirect", true);
            var processor = provider != null ? provider.Value as PayPalDirectProvider : null;

            if (processor == null)
            {
                throw new SmartException(_helper.GetResource("NoModuleLoading"));
            }

            if (processor.VerifyIPN(strRequest, out values))
            {
                #region values
                decimal total = decimal.Zero;
                try
                {
                    total = decimal.Parse(values["mc_gross"], new CultureInfo("en-US"));
                }
                catch { }

                string payer_status = string.Empty;
                values.TryGetValue("payer_status", out payer_status);
                string payment_status = string.Empty;
                values.TryGetValue("payment_status", out payment_status);
                string pending_reason = string.Empty;
                values.TryGetValue("pending_reason", out pending_reason);
                string mc_currency = string.Empty;
                values.TryGetValue("mc_currency", out mc_currency);
                string txn_id = string.Empty;
                values.TryGetValue("txn_id", out txn_id);
                string txn_type = string.Empty;
                values.TryGetValue("txn_type", out txn_type);
                string rp_invoice_id = string.Empty;
                values.TryGetValue("rp_invoice_id", out rp_invoice_id);
                string payment_type = string.Empty;
                values.TryGetValue("payment_type", out payment_type);
                string payer_id = string.Empty;
                values.TryGetValue("payer_id", out payer_id);
                string receiver_id = string.Empty;
                values.TryGetValue("receiver_id", out receiver_id);
                string invoice = string.Empty;
                values.TryGetValue("invoice", out invoice);
                string payment_fee = string.Empty;
                values.TryGetValue("payment_fee", out payment_fee);

                #endregion

                var sb = new StringBuilder();
                sb.AppendLine("PayPal IPN:");
                foreach (KeyValuePair <string, string> kvp in values)
                {
                    sb.AppendLine(kvp.Key + ": " + kvp.Value);
                }

                var newPaymentStatus = PayPalHelper.GetPaymentStatus(payment_status, pending_reason);
                sb.AppendLine("{0}: {1}".FormatWith(_helper.GetResource("NewPaymentStatus"), newPaymentStatus));

                switch (txn_type)
                {
                case "recurring_payment_profile_created":
                    //do nothing here
                    break;

                case "recurring_payment":
                    #region Recurring payment
                {
                    Guid orderNumberGuid = Guid.Empty;
                    try
                    {
                        orderNumberGuid = new Guid(rp_invoice_id);
                    }
                    catch
                    {
                    }

                    var initialOrder = _orderService.GetOrderByGuid(orderNumberGuid);
                    if (initialOrder != null)
                    {
                        var recurringPayments = _orderService.SearchRecurringPayments(0, 0, initialOrder.Id, null);
                        foreach (var rp in recurringPayments)
                        {
                            switch (newPaymentStatus)
                            {
                            case PaymentStatus.Authorized:
                            case PaymentStatus.Paid:
                            {
                                var recurringPaymentHistory = rp.RecurringPaymentHistory;
                                if (recurringPaymentHistory.Count == 0)
                                {
                                    //first payment
                                    var rph = new RecurringPaymentHistory()
                                    {
                                        RecurringPaymentId = rp.Id,
                                        OrderId            = initialOrder.Id,
                                        CreatedOnUtc       = DateTime.UtcNow
                                    };
                                    rp.RecurringPaymentHistory.Add(rph);
                                    _orderService.UpdateRecurringPayment(rp);
                                }
                                else
                                {
                                    //next payments
                                    _orderProcessingService.ProcessNextRecurringPayment(rp);
                                }
                            }
                            break;
                            }
                        }

                        //this.OrderService.InsertOrderNote(newOrder.OrderId, sb.ToString(), DateTime.UtcNow);
                        Logger.Information(_helper.GetResource("IpnLogInfo"), new SmartException(sb.ToString()));
                    }
                    else
                    {
                        Logger.Error(_helper.GetResource("IpnOrderNotFound"), new SmartException(sb.ToString()));
                    }
                }
                    #endregion
                    break;

                default:
                    #region Standard payment
                {
                    string orderNumber = string.Empty;
                    values.TryGetValue("custom", out orderNumber);
                    Guid orderNumberGuid = Guid.Empty;
                    try
                    {
                        orderNumberGuid = new Guid(orderNumber);
                    }
                    catch
                    {
                    }

                    var order = _orderService.GetOrderByGuid(orderNumberGuid);
                    if (order != null)
                    {
                        //order note
                        order.HasNewPaymentNotification = true;

                        order.OrderNotes.Add(new OrderNote
                            {
                                Note = sb.ToString(),
                                DisplayToCustomer = false,
                                CreatedOnUtc      = DateTime.UtcNow
                            });
                        _orderService.UpdateOrder(order);

                        switch (newPaymentStatus)
                        {
                        case PaymentStatus.Pending:
                        {
                        }
                        break;

                        case PaymentStatus.Authorized:
                        {
                            if (_orderProcessingService.CanMarkOrderAsAuthorized(order))
                            {
                                _orderProcessingService.MarkAsAuthorized(order);
                            }
                        }
                        break;

                        case PaymentStatus.Paid:
                        {
                            if (_orderProcessingService.CanMarkOrderAsPaid(order))
                            {
                                _orderProcessingService.MarkOrderAsPaid(order);
                            }
                        }
                        break;

                        case PaymentStatus.Refunded:
                        {
                            if (_orderProcessingService.CanRefundOffline(order))
                            {
                                _orderProcessingService.RefundOffline(order);
                            }
                        }
                        break;

                        case PaymentStatus.Voided:
                        {
                            if (_orderProcessingService.CanVoidOffline(order))
                            {
                                _orderProcessingService.VoidOffline(order);
                            }
                        }
                        break;

                        default:
                            break;
                        }
                    }
                    else
                    {
                        Logger.Error(_helper.GetResource("IpnOrderNotFound"), new SmartException(sb.ToString()));
                    }
                }
                    #endregion
                    break;
                }
            }
            else
            {
                Logger.Error(_helper.GetResource("IpnFailed"), new SmartException(strRequest));
            }

            //nothing should be rendered to visitor
            return(Content(""));
        }
        /// <summary>
        /// Places an order
        /// </summary>
        /// <param name="processPaymentRequest">Process payment request</param>
        /// <returns>Place order result</returns>
        public override PlaceOrderResult PlaceOrder(ProcessPaymentRequest processPaymentRequest)
        {
            //think about moving functionality of processing recurring orders (after the initial order was placed) to ProcessNextRecurringPayment() method
            if (processPaymentRequest == null)
                throw new ArgumentNullException("processPaymentRequest");

            var result = new PlaceOrderResult();
            try
            {
                if (processPaymentRequest.OrderGuid == Guid.Empty)
                    processPaymentRequest.OrderGuid = Guid.NewGuid();

                //prepare order details
                var details = PreparePlaceOrderDetails(processPaymentRequest);

                #region Payment workflow


                //process payment
                ProcessPaymentResult processPaymentResult = null;
                //skip payment workflow if order total equals zero
                var skipPaymentWorkflow = details.OrderTotal == decimal.Zero;
                if (!skipPaymentWorkflow)
                {
                    var paymentMethod = _paymentService.LoadPaymentMethodBySystemName(processPaymentRequest.PaymentMethodSystemName);
                    if (paymentMethod == null)
                        throw new NopException("Payment method couldn't be loaded");

                    //ensure that payment method is active
                    if (!paymentMethod.IsPaymentMethodActive(_paymentSettings))
                        throw new NopException("Payment method is not active");

                    if (!processPaymentRequest.IsRecurringPayment)
                    {
                        if (details.IsRecurringShoppingCart)
                        {
                            //recurring cart
                            var recurringPaymentType = _paymentService.GetRecurringPaymentType(processPaymentRequest.PaymentMethodSystemName);
                            switch (recurringPaymentType)
                            {
                                case RecurringPaymentType.NotSupported:
                                    throw new NopException("Recurring payments are not supported by selected payment method");
                                case RecurringPaymentType.Manual:
                                case RecurringPaymentType.Automatic:
                                    processPaymentResult = _paymentService.ProcessRecurringPayment(processPaymentRequest);
                                    break;
                                default:
                                    throw new NopException("Not supported recurring payment type");
                            }
                        }
                        else
                        {
                            //standard cart
                            processPaymentResult = _paymentService.ProcessPayment(processPaymentRequest);
                        }
                    }
                    else
                    {
                        if (details.IsRecurringShoppingCart)
                        {
                            //Old credit card info
                            processPaymentRequest.CreditCardType = details.InitialOrder.AllowStoringCreditCardNumber ? _encryptionService.DecryptText(details.InitialOrder.CardType) : "";
                            processPaymentRequest.CreditCardName = details.InitialOrder.AllowStoringCreditCardNumber ? _encryptionService.DecryptText(details.InitialOrder.CardName) : "";
                            processPaymentRequest.CreditCardNumber = details.InitialOrder.AllowStoringCreditCardNumber ? _encryptionService.DecryptText(details.InitialOrder.CardNumber) : "";
                            processPaymentRequest.CreditCardCvv2 = details.InitialOrder.AllowStoringCreditCardNumber ? _encryptionService.DecryptText(details.InitialOrder.CardCvv2) : "";
                            try
                            {
                                processPaymentRequest.CreditCardExpireMonth = details.InitialOrder.AllowStoringCreditCardNumber ? Convert.ToInt32(_encryptionService.DecryptText(details.InitialOrder.CardExpirationMonth)) : 0;
                                processPaymentRequest.CreditCardExpireYear = details.InitialOrder.AllowStoringCreditCardNumber ? Convert.ToInt32(_encryptionService.DecryptText(details.InitialOrder.CardExpirationYear)) : 0;
                            }
                            catch { }

                            var recurringPaymentType = _paymentService.GetRecurringPaymentType(processPaymentRequest.PaymentMethodSystemName);
                            switch (recurringPaymentType)
                            {
                                case RecurringPaymentType.NotSupported:
                                    throw new NopException("Recurring payments are not supported by selected payment method");
                                case RecurringPaymentType.Manual:
                                    processPaymentResult = _paymentService.ProcessRecurringPayment(processPaymentRequest);
                                    break;
                                case RecurringPaymentType.Automatic:
                                    //payment is processed on payment gateway site
                                    processPaymentResult = new ProcessPaymentResult();
                                    break;
                                default:
                                    throw new NopException("Not supported recurring payment type");
                            }
                        }
                        else
                        {
                            throw new NopException("No recurring products");
                        }
                    }
                }
                else
                {
                    //payment is not required
                    if (processPaymentResult == null)
                        processPaymentResult = new ProcessPaymentResult();
                    processPaymentResult.NewPaymentStatus = PaymentStatus.Paid;
                }

                if (processPaymentResult == null)
                    throw new NopException("processPaymentResult is not available");

                #endregion

                if (processPaymentResult.Success)
                {
                    #region Save order details

                    var order = new Order
                    {
                        StoreId = processPaymentRequest.StoreId,
                        OrderGuid = processPaymentRequest.OrderGuid,
                        CustomerId = details.Customer.Id,
                        CustomerLanguageId = details.CustomerLanguage.Id,
                        CustomerTaxDisplayType = details.CustomerTaxDisplayType,
                        CustomerIp = _webHelper.GetCurrentIpAddress(),
                        OrderSubtotalInclTax = details.OrderSubTotalInclTax,
                        OrderSubtotalExclTax = details.OrderSubTotalExclTax,
                        OrderSubTotalDiscountInclTax = details.OrderSubTotalDiscountInclTax,
                        OrderSubTotalDiscountExclTax = details.OrderSubTotalDiscountExclTax,
                        OrderShippingInclTax = details.OrderShippingTotalInclTax,
                        OrderShippingExclTax = details.OrderShippingTotalExclTax,
                        PaymentMethodAdditionalFeeInclTax = details.PaymentAdditionalFeeInclTax,
                        PaymentMethodAdditionalFeeExclTax = details.PaymentAdditionalFeeExclTax,
                        TaxRates = details.TaxRates,
                        OrderTax = details.OrderTaxTotal,
                        OrderTotal = details.OrderTotal,
                        RefundedAmount = decimal.Zero,
                        OrderDiscount = details.OrderDiscountAmount,
                        CheckoutAttributeDescription = details.CheckoutAttributeDescription,
                        CheckoutAttributesXml = details.CheckoutAttributesXml,
                        CustomerCurrencyCode = details.CustomerCurrencyCode,
                        CurrencyRate = details.CustomerCurrencyRate,
                        AffiliateId = details.AffiliateId,
                        OrderStatus = OrderStatus.Pending,
                        AllowStoringCreditCardNumber = processPaymentResult.AllowStoringCreditCardNumber,
                        CardType = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardType) : string.Empty,
                        CardName = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardName) : string.Empty,
                        CardNumber = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardNumber) : string.Empty,
                        MaskedCreditCardNumber = _encryptionService.EncryptText(_paymentService.GetMaskedCreditCardNumber(processPaymentRequest.CreditCardNumber)),
                        CardCvv2 = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardCvv2) : string.Empty,
                        CardExpirationMonth = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardExpireMonth.ToString()) : string.Empty,
                        CardExpirationYear = processPaymentResult.AllowStoringCreditCardNumber ? _encryptionService.EncryptText(processPaymentRequest.CreditCardExpireYear.ToString()) : string.Empty,
                        PaymentMethodSystemName = processPaymentRequest.PaymentMethodSystemName,
                        AuthorizationTransactionId = processPaymentResult.AuthorizationTransactionId,
                        AuthorizationTransactionCode = processPaymentResult.AuthorizationTransactionCode,
                        AuthorizationTransactionResult = processPaymentResult.AuthorizationTransactionResult,
                        CaptureTransactionId = processPaymentResult.CaptureTransactionId,
                        CaptureTransactionResult = processPaymentResult.CaptureTransactionResult,
                        SubscriptionTransactionId = processPaymentResult.SubscriptionTransactionId,
                        PaymentStatus = processPaymentResult.NewPaymentStatus,
                        PaidDateUtc = null,
                        BillingAddress = details.BillingAddress,
                        ShippingAddress = details.ShippingAddress,
                        ShippingStatus = details.ShippingStatus,
                        ShippingMethod = details.ShippingMethodName,
                        PickUpInStore = details.PickUpInStore,
                        ShippingRateComputationMethodSystemName = details.ShippingRateComputationMethodSystemName,
                        CustomValuesXml = processPaymentRequest.SerializeCustomValues(),
                        VatNumber = details.VatNumber,
                        CreatedOnUtc = DateTime.UtcNow
                    };
                    _orderService.InsertOrder(order);

                    #region Promo

                    _promoService.SendConfirmedBasket(order);

                    BasketResponse basketResponse = _promoUtilities.GetBasketResponse();

                    if (basketResponse == null)
                    {
                        throw new NopException(string.Format("Failed to create PromoOrder for order: {0}", order.Id));
                    }
                    else
                    {

                        PromoOrder promoOrder = new PromoOrder()
                        {
                            RequestXml = _workContext.CurrentCustomer.GetAttribute<string>(PromoCustomerAttributeNames.PromoBasketRequest, _genericAttributeService, _storeContext.CurrentStore.Id),
                            ResponseXml = basketResponse.ToXml(),
                            OrderId = order.Id,
                            DeliveryOriginalPrice = basketResponse.DeliveryOriginalPrice
                        };

                        _promoOrderService.InsertPromoOrder(promoOrder);

                        basketResponse.Items.ForEach(bi =>
                        {
                            PromoOrderItem promoOrderItem = new PromoOrderItem()
                            {
                                LineAmount = bi.LineAmount,
                                OrderId = order.Id,
                                PromoOrderId = promoOrder.Id,
                                IsDelivery = bi.IsDelivery,
                                ProductCode = bi.ProductCode,
                                VariantCode = bi.VariantCode,
                                LinePromotionDiscount = bi.LinePromotionDiscount,
                                Barcode = bi.Barcode,
                                Generated = bi.Generated,
                                ManualDiscount = bi.ManualDiscount,
                                OriginalAmount = bi.OriginalAmount,
                                OriginalPrice = bi.OriginalPrice,
                                OriginalQuantity = bi.OriginalQuantity,
                                Price = bi.Price,
                                ProductDescription = bi.ProductDescription,
                                Quantity = bi.Quantity,
                                SplitFromLineId = bi.SplitFromLineId,
                                TotalDiscount = bi.TotalDiscount,
                                TotalIssuedPoints = bi.TotalIssuedPoints
                            };

                            promoOrder.PromoOrderItems.Add(promoOrderItem);
                            _promoOrderService.UpdatePromoOrder(promoOrder);

                            bi.AppliedPromotions.ForEach(ap =>
                            {
                                string promotionTypeDisplay = string.Empty;
                                string promotionType = string.Empty;
                                string promotionName = string.Empty;
                                string promotionDisplayText = string.Empty;
                                var appliedPromo = (from sap in basketResponse.Summary.AppliedPromotions where sap.PromotionId == ap.PromotionId select sap).FirstOrDefault();
                                if (appliedPromo != null)
                                {
                                    promotionName = appliedPromo.PromotionName;
                                    promotionType = appliedPromo.PromotionType;
                                    promotionTypeDisplay = appliedPromo.PromotionTypeDisplay;
                                    promotionDisplayText = appliedPromo.DisplayText;
                                }

                                PromoOrderItemPromotion promoOrderItemPromotion = new PromoOrderItemPromotion()
                                {
                                    BasketLevel = ap.BasketLevelPromotion,
                                    DeliveryLevel = ap.DeliveryLevelPromotion,
                                    DiscountAmount = ap.DiscountAmount,
                                    ForLineId = ap.AssociatedLine,
                                    Instance = ap.InstanceId,
                                    PointsIssued = ap.PointsIssued,
                                    PromotionId = ap.PromotionId,
                                    DisplayText = promotionDisplayText,
                                    PromotionTypeDisplay = promotionTypeDisplay,
                                    PromotionName = promotionName,
                                    PromotionType = promotionType,
                                    ExternalIdentifier = ap.ExternalIdentifier,
                                    ReportingGroupCode = ap.ReportingGroupCode
                                };
                                promoOrderItem.PromoOrderItemPromotions.Add(promoOrderItemPromotion);
                                _promoOrderService.UpdatePromoOrder(promoOrder);
                            });
                        });

                        basketResponse.Coupons.ForEach(c =>
                            {
                                PromoOrderCoupon promoOrderCoupon = new PromoOrderCoupon()
                                {
                                    CouponCode = c.CouponCode,
                                    Issued = c.Issued,
                                    OrderId = order.Id,
                                    PromoOrderId = promoOrder.Id,
                                    CouponName = c.CouponName,
                                    IssuedConfirmed = c.IssuedConfirmed,
                                    DisplayText = c.DisplayText
                                };
                                promoOrder.PromoOrderCoupons.Add(promoOrderCoupon);
                                _promoOrderService.UpdatePromoOrder(promoOrder);
                            });
                    }

                    #region clean up

                    Customer customer = _workContext.CurrentCustomer;

                    // basket guid
                    _genericAttributeService.SaveAttribute<string>(customer, PromoCustomerAttributeNames.PromoBasketUniqueReference, null, _storeContext.CurrentStore.Id);

                    // basket response
                    _genericAttributeService.SaveAttribute<string>(customer, PromoCustomerAttributeNames.PromoBasketResponse, null, _storeContext.CurrentStore.Id);

                    // basket request
                    _genericAttributeService.SaveAttribute<string>(customer, PromoCustomerAttributeNames.PromoBasketRequest, null, _storeContext.CurrentStore.Id);

                    // coupon code
                    _genericAttributeService.SaveAttribute<string>(customer, SystemCustomerAttributeNames.DiscountCouponCode, null);

                    #endregion

                    #endregion

                    result.PlacedOrder = order;

                    if (!processPaymentRequest.IsRecurringPayment)
                    {
                        //move shopping cart items to order items
                        foreach (var sc in details.Cart)
                        {
                            var basketResponseItems = basketResponse.FindBasketResponseItems(sc);

                            if (basketResponseItems == null)
                            {
                                // TODO: handle this error
                            }
                            else
                            {
                                //prices
                                decimal taxRate;
                                decimal discountAmount = basketResponseItems.Sum(i => i.LinePromotionDiscount);
                                decimal scUnitPrice = _priceCalculationService.GetUnitPrice(sc);
                                decimal scSubTotal = basketResponseItems.Sum(i => i.LineAmount);
                                decimal scUnitPriceInclTax = _taxService.GetProductPrice(sc.Product, scUnitPrice, true, details.Customer, out taxRate);
                                decimal scUnitPriceExclTax = _taxService.GetProductPrice(sc.Product, scUnitPrice, false, details.Customer, out taxRate);
                                decimal scSubTotalInclTax = _taxService.GetProductPrice(sc.Product, scSubTotal, true, details.Customer, out taxRate);
                                decimal scSubTotalExclTax = _taxService.GetProductPrice(sc.Product, scSubTotal, false, details.Customer, out taxRate);

                                decimal discountAmountInclTax = _taxService.GetProductPrice(sc.Product, discountAmount, true, details.Customer, out taxRate);
                                decimal discountAmountExclTax = _taxService.GetProductPrice(sc.Product, discountAmount, false, details.Customer, out taxRate);

                                //attributes
                                string attributeDescription = _productAttributeFormatter.FormatAttributes(sc.Product, sc.AttributesXml, details.Customer);

                                var itemWeight = _shippingService.GetShoppingCartItemWeight(sc);

                                //save order item
                                var orderItem = new OrderItem
                                {
                                    OrderItemGuid = Guid.NewGuid(),
                                    Order = order,
                                    ProductId = sc.ProductId,
                                    UnitPriceInclTax = scUnitPriceInclTax,
                                    UnitPriceExclTax = scUnitPriceExclTax,
                                    PriceInclTax = scSubTotalInclTax,
                                    PriceExclTax = scSubTotalExclTax,
                                    OriginalProductCost = _priceCalculationService.GetProductCost(sc.Product, sc.AttributesXml),
                                    AttributeDescription = attributeDescription,
                                    AttributesXml = sc.AttributesXml,
                                    Quantity = sc.Quantity,
                                    DiscountAmountInclTax = discountAmountInclTax,
                                    DiscountAmountExclTax = discountAmountExclTax,
                                    DownloadCount = 0,
                                    IsDownloadActivated = false,
                                    LicenseDownloadId = 0,
                                    ItemWeight = itemWeight,
                                    RentalStartDateUtc = sc.RentalStartDateUtc,
                                    RentalEndDateUtc = sc.RentalEndDateUtc
                                };
                                order.OrderItems.Add(orderItem);
                                _orderService.UpdateOrder(order);

                                //gift cards
                                if (sc.Product.IsGiftCard)
                                {
                                    string giftCardRecipientName, giftCardRecipientEmail,
                                        giftCardSenderName, giftCardSenderEmail, giftCardMessage;
                                    _productAttributeParser.GetGiftCardAttribute(sc.AttributesXml,
                                        out giftCardRecipientName, out giftCardRecipientEmail,
                                        out giftCardSenderName, out giftCardSenderEmail, out giftCardMessage);

                                    for (int i = 0; i < sc.Quantity; i++)
                                    {
                                        var gc = new GiftCard
                                        {
                                            GiftCardType = sc.Product.GiftCardType,
                                            PurchasedWithOrderItem = orderItem,
                                            Amount = scUnitPriceExclTax,
                                            IsGiftCardActivated = false,
                                            GiftCardCouponCode = _giftCardService.GenerateGiftCardCode(),
                                            RecipientName = giftCardRecipientName,
                                            RecipientEmail = giftCardRecipientEmail,
                                            SenderName = giftCardSenderName,
                                            SenderEmail = giftCardSenderEmail,
                                            Message = giftCardMessage,
                                            IsRecipientNotified = false,
                                            CreatedOnUtc = DateTime.UtcNow
                                        };
                                        _giftCardService.InsertGiftCard(gc);
                                    }
                                }

                                //inventory
                                _productService.AdjustInventory(sc.Product, -sc.Quantity, sc.AttributesXml);
                            }
                        }

                        //clear shopping cart
                        details.Cart.ToList().ForEach(sci => _shoppingCartService.DeleteShoppingCartItem(sci, false));
                    }
                    else
                    {
                        //recurring payment
                        var initialOrderItems = details.InitialOrder.OrderItems;
                        foreach (var orderItem in initialOrderItems)
                        {
                            //save item
                            var newOrderItem = new OrderItem
                            {
                                OrderItemGuid = Guid.NewGuid(),
                                Order = order,
                                ProductId = orderItem.ProductId,
                                UnitPriceInclTax = orderItem.UnitPriceInclTax,
                                UnitPriceExclTax = orderItem.UnitPriceExclTax,
                                PriceInclTax = orderItem.PriceInclTax,
                                PriceExclTax = orderItem.PriceExclTax,
                                OriginalProductCost = orderItem.OriginalProductCost,
                                AttributeDescription = orderItem.AttributeDescription,
                                AttributesXml = orderItem.AttributesXml,
                                Quantity = orderItem.Quantity,
                                DiscountAmountInclTax = orderItem.DiscountAmountInclTax,
                                DiscountAmountExclTax = orderItem.DiscountAmountExclTax,
                                DownloadCount = 0,
                                IsDownloadActivated = false,
                                LicenseDownloadId = 0,
                                ItemWeight = orderItem.ItemWeight,
                                RentalStartDateUtc = orderItem.RentalStartDateUtc,
                                RentalEndDateUtc = orderItem.RentalEndDateUtc
                            };
                            order.OrderItems.Add(newOrderItem);
                            _orderService.UpdateOrder(order);

                            //gift cards
                            if (orderItem.Product.IsGiftCard)
                            {
                                string giftCardRecipientName, giftCardRecipientEmail,
                                    giftCardSenderName, giftCardSenderEmail, giftCardMessage;
                                _productAttributeParser.GetGiftCardAttribute(orderItem.AttributesXml,
                                    out giftCardRecipientName, out giftCardRecipientEmail,
                                    out giftCardSenderName, out giftCardSenderEmail, out giftCardMessage);

                                for (int i = 0; i < orderItem.Quantity; i++)
                                {
                                    var gc = new GiftCard
                                    {
                                        GiftCardType = orderItem.Product.GiftCardType,
                                        PurchasedWithOrderItem = newOrderItem,
                                        Amount = orderItem.UnitPriceExclTax,
                                        IsGiftCardActivated = false,
                                        GiftCardCouponCode = _giftCardService.GenerateGiftCardCode(),
                                        RecipientName = giftCardRecipientName,
                                        RecipientEmail = giftCardRecipientEmail,
                                        SenderName = giftCardSenderName,
                                        SenderEmail = giftCardSenderEmail,
                                        Message = giftCardMessage,
                                        IsRecipientNotified = false,
                                        CreatedOnUtc = DateTime.UtcNow
                                    };
                                    _giftCardService.InsertGiftCard(gc);
                                }
                            }

                            //inventory
                            _productService.AdjustInventory(orderItem.Product, -orderItem.Quantity, orderItem.AttributesXml);
                        }
                    }

                    //discount usage history
                    // TODO: replace with Promo discount usage history?

                    //gift card usage history
                    if (!processPaymentRequest.IsRecurringPayment)
                        if (details.AppliedGiftCards != null)
                            foreach (var agc in details.AppliedGiftCards)
                            {
                                decimal amountUsed = agc.AmountCanBeUsed;
                                var gcuh = new GiftCardUsageHistory
                                {
                                    GiftCard = agc.GiftCard,
                                    UsedWithOrder = order,
                                    UsedValue = amountUsed,
                                    CreatedOnUtc = DateTime.UtcNow
                                };
                                agc.GiftCard.GiftCardUsageHistory.Add(gcuh);
                                _giftCardService.UpdateGiftCard(agc.GiftCard);
                            }

                    //reward points history
                    if (details.RedeemedRewardPointsAmount > decimal.Zero)
                    {
                        details.Customer.AddRewardPointsHistoryEntry(-details.RedeemedRewardPoints,
                            string.Format(_localizationService.GetResource("RewardPoints.Message.RedeemedForOrder", order.CustomerLanguageId), order.Id),
                            order,
                            details.RedeemedRewardPointsAmount);
                        _customerService.UpdateCustomer(details.Customer);
                    }

                    //recurring orders
                    if (!processPaymentRequest.IsRecurringPayment && details.IsRecurringShoppingCart)
                    {
                        //create recurring payment (the first payment)
                        var rp = new RecurringPayment
                        {
                            CycleLength = processPaymentRequest.RecurringCycleLength,
                            CyclePeriod = processPaymentRequest.RecurringCyclePeriod,
                            TotalCycles = processPaymentRequest.RecurringTotalCycles,
                            StartDateUtc = DateTime.UtcNow,
                            IsActive = true,
                            CreatedOnUtc = DateTime.UtcNow,
                            InitialOrder = order,
                        };
                        _orderService.InsertRecurringPayment(rp);


                        var recurringPaymentType = _paymentService.GetRecurringPaymentType(processPaymentRequest.PaymentMethodSystemName);
                        switch (recurringPaymentType)
                        {
                            case RecurringPaymentType.NotSupported:
                                {
                                    //not supported
                                }
                                break;
                            case RecurringPaymentType.Manual:
                                {
                                    //first payment
                                    var rph = new RecurringPaymentHistory
                                    {
                                        RecurringPayment = rp,
                                        CreatedOnUtc = DateTime.UtcNow,
                                        OrderId = order.Id,
                                    };
                                    rp.RecurringPaymentHistory.Add(rph);
                                    _orderService.UpdateRecurringPayment(rp);
                                }
                                break;
                            case RecurringPaymentType.Automatic:
                                {
                                    //will be created later (process is automated)
                                }
                                break;
                            default:
                                break;
                        }
                    }

                    #endregion

                    #region Notifications & notes

                    //notes, messages
                    if (_workContext.OriginalCustomerIfImpersonated != null)
                    {
                        //this order is placed by a store administrator impersonating a customer
                        order.OrderNotes.Add(new OrderNote
                        {
                            Note = string.Format("Order placed by a store owner ('{0}'. ID = {1}) impersonating the customer.",
                                _workContext.OriginalCustomerIfImpersonated.Email, _workContext.OriginalCustomerIfImpersonated.Id),
                            DisplayToCustomer = false,
                            CreatedOnUtc = DateTime.UtcNow
                        });
                        _orderService.UpdateOrder(order);
                    }
                    else
                    {
                        order.OrderNotes.Add(new OrderNote
                        {
                            Note = "Order placed",
                            DisplayToCustomer = false,
                            CreatedOnUtc = DateTime.UtcNow
                        });
                        _orderService.UpdateOrder(order);
                    }

                    //send email notifications
                    int orderPlacedStoreOwnerNotificationQueuedEmailId = _workflowMessageService.SendOrderPlacedStoreOwnerNotification(order, _localizationSettings.DefaultAdminLanguageId);
                    if (orderPlacedStoreOwnerNotificationQueuedEmailId > 0)
                    {
                        order.OrderNotes.Add(new OrderNote
                        {
                            Note = string.Format("\"Order placed\" email (to store owner) has been queued. Queued email identifier: {0}.", orderPlacedStoreOwnerNotificationQueuedEmailId),
                            DisplayToCustomer = false,
                            CreatedOnUtc = DateTime.UtcNow
                        });
                        _orderService.UpdateOrder(order);
                    }

                    var orderPlacedAttachmentFilePath = _orderSettings.AttachPdfInvoiceToOrderPlacedEmail ?
                        _pdfService.PrintOrderToPdf(order, order.CustomerLanguageId) : null;
                    var orderPlacedAttachmentFileName = _orderSettings.AttachPdfInvoiceToOrderPlacedEmail ?
                        "order.pdf" : null;
                    int orderPlacedCustomerNotificationQueuedEmailId = _workflowMessageService
                        .SendOrderPlacedCustomerNotification(order, order.CustomerLanguageId, orderPlacedAttachmentFilePath, orderPlacedAttachmentFileName);
                    if (orderPlacedCustomerNotificationQueuedEmailId > 0)
                    {
                        order.OrderNotes.Add(new OrderNote
                        {
                            Note = string.Format("\"Order placed\" email (to customer) has been queued. Queued email identifier: {0}.", orderPlacedCustomerNotificationQueuedEmailId),
                            DisplayToCustomer = false,
                            CreatedOnUtc = DateTime.UtcNow
                        });
                        _orderService.UpdateOrder(order);
                    }

                    var vendors = GetVendorsInOrder(order);
                    foreach (var vendor in vendors)
                    {
                        int orderPlacedVendorNotificationQueuedEmailId = _workflowMessageService.SendOrderPlacedVendorNotification(order, vendor, order.CustomerLanguageId);
                        if (orderPlacedVendorNotificationQueuedEmailId > 0)
                        {
                            order.OrderNotes.Add(new OrderNote
                            {
                                Note = string.Format("\"Order placed\" email (to vendor) has been queued. Queued email identifier: {0}.", orderPlacedVendorNotificationQueuedEmailId),
                                DisplayToCustomer = false,
                                CreatedOnUtc = DateTime.UtcNow
                            });
                            _orderService.UpdateOrder(order);
                        }
                    }

                    //check order status
                    CheckOrderStatus(order);

                    //reset checkout data
                    if (!processPaymentRequest.IsRecurringPayment)
                        _customerService.ResetCheckoutData(details.Customer, processPaymentRequest.StoreId, clearCouponCodes: true, clearCheckoutAttributes: true);

                    if (!processPaymentRequest.IsRecurringPayment)
                    {
                        _customerActivityService.InsertActivity(
                            "PublicStore.PlaceOrder",
                            _localizationService.GetResource("ActivityLog.PublicStore.PlaceOrder"),
                            order.Id);
                    }

                    //raise event       
                    _eventPublisher.Publish(new OrderPlacedEvent(order));

                    if (order.PaymentStatus == PaymentStatus.Paid)
                    {
                        ProcessOrderPaid(order);
                    }
                    #endregion
                }
                else
                {
                    foreach (var paymentError in processPaymentResult.Errors)
                        result.AddError(string.Format(_localizationService.GetResource("Checkout.PaymentError"), paymentError));
                }
            }
            catch (Exception exc)
            {
                _logger.Error(exc.Message, exc);
                result.AddError(exc.Message);
            }

            #region Process errors

            string error = "";
            for (int i = 0; i < result.Errors.Count; i++)
            {
                error += string.Format("Error {0}: {1}", i + 1, result.Errors[i]);
                if (i != result.Errors.Count - 1)
                    error += ". ";
            }
            if (!String.IsNullOrEmpty(error))
            {
                //log it
                string logError = string.Format("Error while placing order. {0}", error);
                _logger.Error(logError);
            }

            #endregion

            return result;
        }
Ejemplo n.º 8
0
        public void HandleIPN(string ipnData)
        {
            Dictionary <string, string> values;

            if (VerifyIPN(ipnData, out values))
            {
                #region values
                decimal total = decimal.Zero;
                try
                {
                    total = decimal.Parse(values["mc_gross"], new CultureInfo("en-US"));
                }
                catch { }

                string payer_status = string.Empty;
                values.TryGetValue("payer_status", out payer_status);
                string payment_status = string.Empty;
                values.TryGetValue("payment_status", out payment_status);
                string pending_reason = string.Empty;
                values.TryGetValue("pending_reason", out pending_reason);
                string mc_currency = string.Empty;
                values.TryGetValue("mc_currency", out mc_currency);
                string txn_id = string.Empty;
                values.TryGetValue("txn_id", out txn_id);
                string txn_type = string.Empty;
                values.TryGetValue("txn_type", out txn_type);
                string rp_invoice_id = string.Empty;
                values.TryGetValue("rp_invoice_id", out rp_invoice_id);
                string payment_type = string.Empty;
                values.TryGetValue("payment_type", out payment_type);
                string payer_id = string.Empty;
                values.TryGetValue("payer_id", out payer_id);
                string receiver_id = string.Empty;
                values.TryGetValue("receiver_id", out receiver_id);
                string invoice = string.Empty;
                values.TryGetValue("invoice", out invoice);
                string payment_fee = string.Empty;
                values.TryGetValue("payment_fee", out payment_fee);

                #endregion

                var sb = new StringBuilder();
                sb.AppendLine("Paypal IPN:");
                foreach (KeyValuePair <string, string> kvp in values)
                {
                    sb.AppendLine(kvp.Key + ": " + kvp.Value);
                }

                var newPaymentStatus = GetPaymentStatus(payment_status, pending_reason);
                sb.AppendLine("New payment status: " + newPaymentStatus);

                switch (txn_type)
                {
                case "recurring_payment_profile_created":
                    //do nothing here
                    break;

                case "recurring_payment":
                    #region Recurring payment
                {
                    Guid orderNumberGuid = Guid.Empty;
                    try
                    {
                        orderNumberGuid = new Guid(rp_invoice_id);
                    }
                    catch
                    {
                    }

                    var initialOrder = _orderService.GetOrderByGuid(orderNumberGuid);
                    if (initialOrder != null)
                    {
                        var recurringPayments = _orderService.SearchRecurringPayments(0, 0, initialOrder.Id, null, 0, int.MaxValue);
                        foreach (var rp in recurringPayments)
                        {
                            switch (newPaymentStatus)
                            {
                            case PaymentStatus.Authorized:
                            case PaymentStatus.Paid:
                            {
                                var recurringPaymentHistory = rp.RecurringPaymentHistory;
                                if (recurringPaymentHistory.Count == 0)
                                {
                                    //first payment
                                    var rph = new RecurringPaymentHistory()
                                    {
                                        RecurringPaymentId = rp.Id,
                                        OrderId            = initialOrder.Id,
                                        CreatedOnUtc       = DateTime.UtcNow
                                    };
                                    rp.RecurringPaymentHistory.Add(rph);
                                    _orderService.UpdateRecurringPayment(rp);
                                }
                                else
                                {
                                    //next payments
                                    _orderProcessingService.ProcessNextRecurringPayment(rp);
                                }
                            }
                            break;
                            }
                        }

                        //this.OrderService.InsertOrderNote(newOrder.OrderId, sb.ToString(), DateTime.UtcNow);
                        _logger.Information("PayPal IPN. Recurring info", new NopException(sb.ToString()));
                    }
                    else
                    {
                        _logger.Error("PayPal IPN. Order is not found", new NopException(sb.ToString()));
                    }
                }
                    #endregion
                    break;

                default:
                    #region Standard payment
                {
                    string orderNumber = string.Empty;
                    values.TryGetValue("custom", out orderNumber);
                    Guid orderNumberGuid = Guid.Empty;
                    try
                    {
                        orderNumberGuid = new Guid(orderNumber);
                    }
                    catch
                    {
                    }

                    var order = _orderService.GetOrderByGuid(orderNumberGuid);
                    if (order != null)
                    {
                        //order note
                        order.OrderNotes.Add(new OrderNote()
                            {
                                Note = sb.ToString(),
                                DisplayToCustomer = false,
                                CreatedOnUtc      = DateTime.UtcNow
                            });
                        _orderService.UpdateOrder(order);

                        switch (newPaymentStatus)
                        {
                        case PaymentStatus.Pending:
                        {
                        }
                        break;

                        case PaymentStatus.Authorized:
                        {
                            if (_orderProcessingService.CanMarkOrderAsAuthorized(order))
                            {
                                _orderProcessingService.MarkAsAuthorized(order);
                            }
                        }
                        break;

                        case PaymentStatus.Paid:
                        {
                            if (_orderProcessingService.CanMarkOrderAsPaid(order))
                            {
                                _orderProcessingService.MarkOrderAsPaid(order);
                            }
                        }
                        break;

                        case PaymentStatus.Refunded:
                        {
                            if (_orderProcessingService.CanRefundOffline(order))
                            {
                                _orderProcessingService.RefundOffline(order);
                            }
                        }
                        break;

                        case PaymentStatus.Voided:
                        {
                            if (_orderProcessingService.CanVoidOffline(order))
                            {
                                _orderProcessingService.VoidOffline(order);
                            }
                        }
                        break;

                        default:
                            break;
                        }
                    }
                    else
                    {
                        _logger.Error("PayPal IPN. Order is not found", new NopException(sb.ToString()));
                    }
                }
                    #endregion
                    break;
                }
            }
            else
            {
                _logger.Error("PayPal IPN failed.", new NopException(ipnData));
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Process recurring payment
        /// </summary>
        /// <param name="transactionId">AuthorizeNet transaction ID</param>
        public void ProcessRecurringPayment(string transactionId)
        {
            PrepareAuthorizeNet();
            var request = new getTransactionDetailsRequest {
                transId = transactionId
            };

            // instantiate the controller that will call the service
            var controller = new getTransactionDetailsController(request);

            controller.Execute();

            // get the response from the service (errors contained if any)
            var response = controller.GetApiResponse();

            if (response != null && response.messages.resultCode == messageTypeEnum.Ok)
            {
                var transaction = response.transaction;
                if (transaction == null)
                {
                    _logger.Error(String.Format("Authorize.NET: Transaction data is missing (transactionId: {0})", transactionId));
                    return;
                }

                if (transaction.transactionStatus == "refundTransaction")
                {
                    return;
                }

                var orderDescriptions = transaction.order.description.Split('#');

                if (orderDescriptions.Length < 2)
                {
                    _logger.Error(String.Format("Authorize.NET: Missing order GUID (transactionId: {0})", transactionId));
                    return;
                }

                var order = _orderService.GetOrderByGuid(new Guid(orderDescriptions[1]));

                if (order == null)
                {
                    _logger.Error(String.Format("Authorize.NET: Order cannot be loaded (order GUID: {0})", orderDescriptions[1]));
                    return;
                }

                var recurringPayments = _orderService.SearchRecurringPayments(initialOrderId: order.Id);
                foreach (var rp in recurringPayments)
                {
                    var recurringPaymentHistory = rp.RecurringPaymentHistory;
                    var orders = _orderService.GetOrdersByIds(recurringPaymentHistory.Select(rph => rph.OrderId).ToArray()).ToList();

                    var transactionsIds = new List <string>();
                    transactionsIds.AddRange(orders.Select(o => o.AuthorizationTransactionId).Where(tId => !string.IsNullOrEmpty(tId)));
                    transactionsIds.AddRange(orders.Select(o => o.CaptureTransactionId).Where(tId => !string.IsNullOrEmpty(tId)));

                    //skip the re-processing of transactions
                    if (transactionsIds.Contains(transactionId))
                    {
                        continue;
                    }

                    var newPaymentStatus = transaction.transactionType == "authOnlyTransaction" ? PaymentStatus.Authorized : PaymentStatus.Paid;

                    if (recurringPaymentHistory.Count == 0)
                    {
                        //first payment
                        var rph = new RecurringPaymentHistory
                        {
                            RecurringPaymentId = rp.Id,
                            OrderId            = order.Id,
                            CreatedOnUtc       = DateTime.UtcNow
                        };
                        rp.RecurringPaymentHistory.Add(rph);

                        if (newPaymentStatus == PaymentStatus.Authorized)
                        {
                            rp.InitialOrder.AuthorizationTransactionId = transactionId;
                        }
                        else
                        {
                            rp.InitialOrder.CaptureTransactionId = transactionId;
                        }

                        _orderService.UpdateRecurringPayment(rp);
                    }
                    else
                    {
                        //next payments
                        var processPaymentResult = new ProcessPaymentResult();
                        processPaymentResult.NewPaymentStatus = newPaymentStatus;

                        if (newPaymentStatus == PaymentStatus.Authorized)
                        {
                            processPaymentResult.AuthorizationTransactionId = transactionId;
                        }
                        else
                        {
                            processPaymentResult.CaptureTransactionId = transactionId;
                        }

                        _orderProcessingService.ProcessNextRecurringPayment(rp, processPaymentResult);
                    }
                }
            }
            else if (response != null)
            {
                _logger.Error(String.Format("Authorize.Net Error: {0} - {1} (transactionId: {2})", response.messages.message[0].code, response.messages.message[0].text, transactionId));
            }
            else
            {
                _logger.Error(String.Format("Authorize.NET unknown error (transactionId: {0})", transactionId));
            }
        }
        /// <summary>
        /// Process recurring payment
        /// </summary>
        /// <param name="transactionId">AuthorizeNet transaction ID</param>
        public void ProcessRecurringPayment(string transactionId)
        {
            PrepareAuthorizeNet();
            var request = new getTransactionDetailsRequest {
                transId = transactionId
            };

            // instantiate the controller that will call the service
            var controller = new getTransactionDetailsController(request);

            controller.Execute();

            // get the response from the service (errors contained if any)
            var response = controller.GetApiResponse();

            if (response != null && response.messages.resultCode == messageTypeEnum.Ok)
            {
                var transaction = response.transaction;
                if (transaction == null)
                {
                    _logger.Error(String.Format("Authorize.NET: Transaction data is missing (transactionId: {0})", transactionId));
                    return;
                }

                if (transaction.transactionStatus != "settledSuccessfully")
                {
                    return;
                }

                var orderDescriptions = transaction.order.description.Split('#');

                if (orderDescriptions.Length < 2)
                {
                    _logger.Error(String.Format("Authorize.NET: Missing order GUID (transactionId: {0})", transactionId));
                    return;
                }

                var order = _orderService.GetOrderByGuid(new Guid(orderDescriptions[1]));

                if (order == null)
                {
                    _logger.Error(String.Format("Authorize.NET: Order cannot be loaded (order GUID: {0})", orderDescriptions[1]));
                    return;
                }

                var recurringPayments = _orderService.SearchRecurringPayments(initialOrderId: order.Id);
                foreach (var rp in recurringPayments)
                {
                    var recurringPaymentHistory = rp.RecurringPaymentHistory;
                    if (recurringPaymentHistory.Count == 0)
                    {
                        //first payment
                        var rph = new RecurringPaymentHistory {
                            RecurringPaymentId = rp.Id,
                            OrderId            = order.Id,
                            CreatedOnUtc       = DateTime.UtcNow
                        };
                        rp.RecurringPaymentHistory.Add(rph);
                        _orderService.UpdateRecurringPayment(rp);
                    }
                    else
                    {
                        //next payments
                        _orderProcessingService.ProcessNextRecurringPayment(rp);
                    }
                }
            }
            else if (response != null)
            {
                _logger.Error(String.Format("Authorize.Net Error: {0} - {1} (transactionId: {2})", response.messages.message[0].code, response.messages.message[0].text, transactionId));
            }
            else
            {
                _logger.Error(String.Format("Authorize.NET unknown error (transactionId: {0})", transactionId));
            }
        }
        private void PrepareRecurringPaymentHistoryModel(RecurringPaymentModel.RecurringPaymentHistoryModel model, RecurringPaymentHistory history)
        {
            Guard.NotNull(model, nameof(model));
            Guard.NotNull(history, nameof(history));

            var order = _orderService.GetOrderById(history.OrderId);

            model.Id                 = history.Id;
            model.OrderId            = history.OrderId;
            model.RecurringPaymentId = history.RecurringPaymentId;
            model.OrderStatus        = order.OrderStatus.GetLocalizedEnum(_localizationService, _workContext);
            model.PaymentStatus      = order.PaymentStatus.GetLocalizedEnum(_localizationService, _workContext);
            model.ShippingStatus     = order.ShippingStatus.GetLocalizedEnum(_localizationService, _workContext);
            model.CreatedOn          = _dateTimeHelper.ConvertToUserTime(history.CreatedOnUtc, DateTimeKind.Utc);
        }
        public void HandleIPN(string ipnData)
        {
            if (VerifyIPN(ipnData, out var values))
            {
                values.TryGetValue("payer_status", out _);
                values.TryGetValue("payment_status", out var paymentStatus);
                values.TryGetValue("pending_reason", out var pendingReason);
                values.TryGetValue("mc_currency", out _);
                values.TryGetValue("txn_id", out _);
                values.TryGetValue("txn_type", out var txnType);
                values.TryGetValue("rp_invoice_id", out var rpInvoiceId);
                values.TryGetValue("payment_type", out _);
                values.TryGetValue("payer_id", out _);
                values.TryGetValue("receiver_id", out _);
                values.TryGetValue("invoice", out _);
                values.TryGetValue("payment_fee", out _);

                var sb = new StringBuilder();
                sb.AppendLine("Paypal IPN:");
                foreach (var kvp in values)
                {
                    sb.AppendLine(kvp.Key + ": " + kvp.Value);
                }

                var newPaymentStatus = GetPaymentStatus(paymentStatus, pendingReason);
                sb.AppendLine("New payment status: " + newPaymentStatus);

                switch (txnType)
                {
                case "recurring_payment_profile_created":
                    //do nothing here
                    break;

                case "recurring_payment":
                {
                    var orderNumberGuid = Guid.Empty;
                    try
                    {
                        orderNumberGuid = new Guid(rpInvoiceId);
                    }
                    catch
                    {
                        // ignored
                    }

                    var initialOrder = _orderService.GetOrderByGuid(orderNumberGuid);
                    if (initialOrder != null)
                    {
                        var recurringPayments = _orderService.SearchRecurringPayments(0, 0, initialOrder.Id);
                        foreach (var rp in recurringPayments)
                        {
                            switch (newPaymentStatus)
                            {
                            case PaymentStatus.Authorized:
                            case PaymentStatus.Paid:
                            {
                                var recurringPaymentHistory = rp.RecurringPaymentHistory;
                                if (recurringPaymentHistory.Count == 0)
                                {
                                    //first payment
                                    var rph = new RecurringPaymentHistory
                                    {
                                        RecurringPaymentId = rp.Id,
                                        OrderId            = initialOrder.Id,
                                        CreatedOnUtc       = DateTime.UtcNow
                                    };
                                    rp.RecurringPaymentHistory.Add(rph);
                                    _orderService.UpdateRecurringPayment(rp);
                                }
                                else
                                {
                                    //next payments
                                    _orderProcessingService.ProcessNextRecurringPayment(rp);
                                }
                            }

                            break;
                            }
                        }

                        //this.OrderService.InsertOrderNote(newOrder.OrderId, sb.ToString(), DateTime.UtcNow);
                        _logger.Information("PayPal IPN. Recurring info", new NopException(sb.ToString()));
                    }
                    else
                    {
                        _logger.Error("PayPal IPN. Order is not found", new NopException(sb.ToString()));
                    }
                }

                break;

                default:
                {
                    values.TryGetValue("custom", out var orderNumber);
                    var orderNumberGuid = Guid.Empty;
                    try
                    {
                        orderNumberGuid = new Guid(orderNumber);
                    }
                    catch
                    {
                        // ignored
                    }

                    var order = _orderService.GetOrderByGuid(orderNumberGuid);
                    if (order != null)
                    {
                        //order note
                        order.OrderNotes.Add(new OrderNote
                            {
                                Note = sb.ToString(),
                                DisplayToCustomer = false,
                                CreatedOnUtc      = DateTime.UtcNow
                            });
                        _orderService.UpdateOrder(order);

                        switch (newPaymentStatus)
                        {
                        case PaymentStatus.Pending:
                            break;

                        case PaymentStatus.Authorized:
                            if (_orderProcessingService.CanMarkOrderAsAuthorized(order))
                            {
                                _orderProcessingService.MarkAsAuthorized(order);
                            }
                            break;

                        case PaymentStatus.Paid:
                            if (_orderProcessingService.CanMarkOrderAsPaid(order))
                            {
                                _orderProcessingService.MarkOrderAsPaid(order);
                            }
                            break;

                        case PaymentStatus.Refunded:
                            if (_orderProcessingService.CanRefundOffline(order))
                            {
                                _orderProcessingService.RefundOffline(order);
                            }
                            break;

                        case PaymentStatus.Voided:
                            if (_orderProcessingService.CanVoidOffline(order))
                            {
                                _orderProcessingService.VoidOffline(order);
                            }
                            break;

                        default:
                            break;
                        }
                    }
                    else
                    {
                        _logger.Error("PayPal IPN. Order is not found", new NopException(sb.ToString()));
                    }
                }

                break;
                }
            }
            else
            {
                _logger.Error("PayPal IPN failed.", new NopException(ipnData));
            }
        }
Ejemplo n.º 13
0
        public ActionResult IPNHandler()
        {
            byte[] param      = Request.BinaryRead(Request.ContentLength);
            string strRequest = Encoding.ASCII.GetString(param);
            Dictionary <string, string> values;

            var processor = _paymentService.LoadPaymentMethodBySystemName("Payments.PayPalStandard") as PayPalStandardPaymentProcessor;

            if (processor == null ||
                !processor.IsPaymentMethodActive(_paymentSettings) || !processor.PluginDescriptor.Installed)
            {
                throw new NopException("PayPal Standard module cannot be loaded");
            }

            if (processor.VerifyIpn(strRequest, out values))
            {
                #region values
                decimal mc_gross = decimal.Zero;
                try
                {
                    mc_gross = decimal.Parse(values["mc_gross"], new CultureInfo("en-US"));
                }
                catch { }

                string payer_status = string.Empty;
                values.TryGetValue("payer_status", out payer_status);
                string payment_status = string.Empty;
                values.TryGetValue("payment_status", out payment_status);
                string pending_reason = string.Empty;
                values.TryGetValue("pending_reason", out pending_reason);
                string mc_currency = string.Empty;
                values.TryGetValue("mc_currency", out mc_currency);
                string txn_id = string.Empty;
                values.TryGetValue("txn_id", out txn_id);
                string txn_type = string.Empty;
                values.TryGetValue("txn_type", out txn_type);
                string rp_invoice_id = string.Empty;
                values.TryGetValue("rp_invoice_id", out rp_invoice_id);
                string payment_type = string.Empty;
                values.TryGetValue("payment_type", out payment_type);
                string payer_id = string.Empty;
                values.TryGetValue("payer_id", out payer_id);
                string receiver_id = string.Empty;
                values.TryGetValue("receiver_id", out receiver_id);
                string invoice = string.Empty;
                values.TryGetValue("invoice", out invoice);
                string payment_fee = string.Empty;
                values.TryGetValue("payment_fee", out payment_fee);

                #endregion

                var sb = new StringBuilder();
                sb.AppendLine("Paypal IPN:");
                foreach (KeyValuePair <string, string> kvp in values)
                {
                    sb.AppendLine(kvp.Key + ": " + kvp.Value);
                }

                var newPaymentStatus = PaypalHelper.GetPaymentStatus(payment_status, pending_reason);
                sb.AppendLine("New payment status: " + newPaymentStatus);

                switch (txn_type)
                {
                case "recurring_payment_profile_created":
                    //do nothing here
                    break;

                    #region Recurring payment
                case "recurring_payment":
                {
                    Guid orderNumberGuid = Guid.Empty;
                    try
                    {
                        orderNumberGuid = new Guid(rp_invoice_id);
                    }
                    catch
                    {
                    }

                    var initialOrder = _orderService.GetOrderByGuid(orderNumberGuid);
                    if (initialOrder != null)
                    {
                        var recurringPayments = _orderService.SearchRecurringPayments(initialOrderId: initialOrder.Id);
                        foreach (var rp in recurringPayments)
                        {
                            switch (newPaymentStatus)
                            {
                            case PaymentStatus.Authorized:
                            case PaymentStatus.Paid:
                            {
                                var recurringPaymentHistory = rp.RecurringPaymentHistory;
                                if (!recurringPaymentHistory.Any())
                                {
                                    //first payment
                                    var rph = new RecurringPaymentHistory
                                    {
                                        RecurringPaymentId = rp.Id,
                                        OrderId            = initialOrder.Id,
                                        CreatedOnUtc       = DateTime.UtcNow
                                    };
                                    rp.RecurringPaymentHistory.Add(rph);
                                    _orderService.UpdateRecurringPayment(rp);
                                }
                                else
                                {
                                    //next payments
                                    var processPaymentResult = new ProcessPaymentResult();
                                    processPaymentResult.NewPaymentStatus = newPaymentStatus;
                                    if (newPaymentStatus == PaymentStatus.Authorized)
                                    {
                                        processPaymentResult.AuthorizationTransactionId = txn_id;
                                    }
                                    else
                                    {
                                        processPaymentResult.CaptureTransactionId = txn_id;
                                    }

                                    _orderProcessingService.ProcessNextRecurringPayment(rp, processPaymentResult);
                                }
                            }
                            break;

                            case PaymentStatus.Voided:
                                //failed payment
                                var failedPaymentResult = new ProcessPaymentResult
                                {
                                    Errors = new[] { string.Format("PayPal IPN. Recurring payment is {0} .", payment_status) },
                                    RecurringPaymentFailed = true
                                };
                                _orderProcessingService.ProcessNextRecurringPayment(rp, failedPaymentResult);
                                break;
                            }
                        }

                        //this.OrderService.InsertOrderNote(newOrder.OrderId, sb.ToString(), DateTime.UtcNow);
                        _logger.Information("PayPal IPN. Recurring info", new NopException(sb.ToString()));
                    }
                    else
                    {
                        _logger.Error("PayPal IPN. Order is not found", new NopException(sb.ToString()));
                    }
                }
                break;

                case "recurring_payment_failed":
                    var orderGuid = Guid.Empty;
                    if (Guid.TryParse(rp_invoice_id, out orderGuid))
                    {
                        var initialOrder = _orderService.GetOrderByGuid(orderGuid);
                        if (initialOrder != null)
                        {
                            var recurringPayment = _orderService.SearchRecurringPayments(initialOrderId: initialOrder.Id).FirstOrDefault();
                            //failed payment
                            if (recurringPayment != null)
                            {
                                _orderProcessingService.ProcessNextRecurringPayment(recurringPayment, new ProcessPaymentResult {
                                    Errors = new[] { txn_type }, RecurringPaymentFailed = true
                                });
                            }
                        }
                    }
                    break;

                    #endregion
                default:
                    #region Standard payment
                {
                    string orderNumber = string.Empty;
                    values.TryGetValue("custom", out orderNumber);
                    Guid orderNumberGuid = Guid.Empty;
                    try
                    {
                        orderNumberGuid = new Guid(orderNumber);
                    }
                    catch
                    {
                    }

                    var order = _orderService.GetOrderByGuid(orderNumberGuid);
                    if (order != null)
                    {
                        //order note
                        order.OrderNotes.Add(new OrderNote
                            {
                                Note = sb.ToString(),
                                DisplayToCustomer = false,
                                CreatedOnUtc      = DateTime.UtcNow
                            });
                        _orderService.UpdateOrder(order);

                        switch (newPaymentStatus)
                        {
                        case PaymentStatus.Pending:
                        {
                        }
                        break;

                        case PaymentStatus.Authorized:
                        {
                            //validate order total
                            if (Math.Round(mc_gross, 2).Equals(Math.Round(order.OrderTotal, 2)))
                            {
                                //valid
                                if (_orderProcessingService.CanMarkOrderAsAuthorized(order))
                                {
                                    _orderProcessingService.MarkAsAuthorized(order);
                                }
                            }
                            else
                            {
                                //not valid
                                string errorStr = string.Format("PayPal IPN. Returned order total {0} doesn't equal order total {1}. Order# {2}.", mc_gross, order.OrderTotal, order.Id);
                                //log
                                _logger.Error(errorStr);
                                //order note
                                order.OrderNotes.Add(new OrderNote
                                        {
                                            Note = errorStr,
                                            DisplayToCustomer = false,
                                            CreatedOnUtc      = DateTime.UtcNow
                                        });
                                _orderService.UpdateOrder(order);
                            }
                        }
                        break;

                        case PaymentStatus.Paid:
                        {
                            //validate order total
                            if (Math.Round(mc_gross, 2).Equals(Math.Round(order.OrderTotal, 2)))
                            {
                                //valid
                                if (_orderProcessingService.CanMarkOrderAsPaid(order))
                                {
                                    order.AuthorizationTransactionId = txn_id;
                                    _orderService.UpdateOrder(order);

                                    _orderProcessingService.MarkOrderAsPaid(order);
                                }
                            }
                            else
                            {
                                //not valid
                                string errorStr = string.Format("PayPal IPN. Returned order total {0} doesn't equal order total {1}. Order# {2}.", mc_gross, order.OrderTotal, order.Id);
                                //log
                                _logger.Error(errorStr);
                                //order note
                                order.OrderNotes.Add(new OrderNote
                                        {
                                            Note = errorStr,
                                            DisplayToCustomer = false,
                                            CreatedOnUtc      = DateTime.UtcNow
                                        });
                                _orderService.UpdateOrder(order);
                            }
                        }
                        break;

                        case PaymentStatus.Refunded:
                        {
                            var totalToRefund = Math.Abs(mc_gross);
                            if (totalToRefund > 0 && Math.Round(totalToRefund, 2).Equals(Math.Round(order.OrderTotal, 2)))
                            {
                                //refund
                                if (_orderProcessingService.CanRefundOffline(order))
                                {
                                    _orderProcessingService.RefundOffline(order);
                                }
                            }
                            else
                            {
                                //partial refund
                                if (_orderProcessingService.CanPartiallyRefundOffline(order, totalToRefund))
                                {
                                    _orderProcessingService.PartiallyRefundOffline(order, totalToRefund);
                                }
                            }
                        }
                        break;

                        case PaymentStatus.Voided:
                        {
                            if (_orderProcessingService.CanVoidOffline(order))
                            {
                                _orderProcessingService.VoidOffline(order);
                            }
                        }
                        break;

                        default:
                            break;
                        }
                    }
                    else
                    {
                        _logger.Error("PayPal IPN. Order is not found", new NopException(sb.ToString()));
                    }
                }
                    #endregion
                    break;
                }
            }
            else
            {
                _logger.Error("PayPal IPN failed.", new NopException(strRequest));
            }

            //nothing should be rendered to visitor
            return(Content(""));
        }
Ejemplo n.º 14
0
 /// <summary>
 /// Inserts a recurring payment history entry
 /// </summary>
 /// <param name="recurringPaymentHistory">Recurring payment history entry</param>
 public virtual void InsertRecurringPaymentHistory(RecurringPaymentHistory recurringPaymentHistory)
 {
     _recurringPaymentHistoryRepository.Insert(recurringPaymentHistory);
 }
        /// <summary>
        /// Process recurring payment
        /// </summary>
        /// <param name="transactionId">AuthorizeNet transaction ID</param>
        public void ProcessRecurringPayment(string transactionId)
        {
            var transactionDetails = GetTransactionDetails(transactionId);

            if (transactionDetails.TransactionStatus == "refundTransaction")
            {
                return;
            }

            var orderDescriptions = transactionDetails.OrderDescriptions;

            if (orderDescriptions.Length < 2)
            {
                _logger.Error($"Authorize.NET: Missing order GUID (transactionId: {transactionId})");
                return;
            }

            if (orderDescriptions[0].Contains("Full order"))
            {
                return;
            }

            var order = _orderService.GetOrderByGuid(new Guid(orderDescriptions[1]));

            if (order == null)
            {
                _logger.Error($"Authorize.NET: Order cannot be loaded (order GUID: {orderDescriptions[1]})");
                return;
            }

            var recurringPayments = _orderService.SearchRecurringPayments(initialOrderId: order.Id);

            foreach (var rp in recurringPayments)
            {
                if (transactionDetails.IsOk)
                {
                    var recurringPaymentHistory = rp.RecurringPaymentHistory;
                    var orders = _orderService.GetOrdersByIds(recurringPaymentHistory.Select(rph => rph.OrderId).ToArray()).ToList();

                    var transactionsIds = new List <string>();
                    transactionsIds.AddRange(orders.Select(o => o.AuthorizationTransactionId).Where(tId => !string.IsNullOrEmpty(tId)));
                    transactionsIds.AddRange(orders.Select(o => o.CaptureTransactionId).Where(tId => !string.IsNullOrEmpty(tId)));

                    //skip the re-processing of transactions
                    if (transactionsIds.Contains(transactionId))
                    {
                        continue;
                    }

                    var newPaymentStatus = transactionDetails.TransactionType == "authOnlyTransaction" ? PaymentStatus.Authorized : PaymentStatus.Paid;

                    if (recurringPaymentHistory.Count == 0)
                    {
                        //first payment
                        var rph = new RecurringPaymentHistory
                        {
                            RecurringPaymentId = rp.Id,
                            OrderId            = order.Id,
                            CreatedOnUtc       = DateTime.UtcNow
                        };
                        rp.RecurringPaymentHistory.Add(rph);

                        if (newPaymentStatus == PaymentStatus.Authorized)
                        {
                            rp.InitialOrder.AuthorizationTransactionId = transactionId;
                        }
                        else
                        {
                            rp.InitialOrder.CaptureTransactionId = transactionId;
                        }

                        _orderService.UpdateRecurringPayment(rp);
                    }
                    else
                    {
                        //next payments
                        var processPaymentResult = new ProcessPaymentResult
                        {
                            NewPaymentStatus = newPaymentStatus
                        };

                        if (newPaymentStatus == PaymentStatus.Authorized)
                        {
                            processPaymentResult.AuthorizationTransactionId = transactionId;
                        }
                        else
                        {
                            processPaymentResult.CaptureTransactionId = transactionId;
                        }

                        _orderProcessingService.ProcessNextRecurringPayment(rp, processPaymentResult);
                    }
                }
                else
                {
                    var processPaymentResult = new ProcessPaymentResult();
                    processPaymentResult.AuthorizationTransactionId = processPaymentResult.CaptureTransactionId = transactionId;
                    processPaymentResult.RecurringPaymentFailed     = true;
                    processPaymentResult.Errors.Add(
                        $"Authorize.Net Error: {transactionDetails.Message?.code} - {transactionDetails.Message?.text} (transactionId: {transactionId})");
                    _orderProcessingService.ProcessNextRecurringPayment(rp, processPaymentResult);
                }
            }
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            CommonHelper.SetResponseNoCache(Response);

            if (!Page.IsPostBack)
            {
                byte[] param      = Request.BinaryRead(Request.ContentLength);
                string strRequest = Encoding.ASCII.GetString(param);
                Dictionary <string, string> values;

                PayPalStandardPaymentProcessor processor = new PayPalStandardPaymentProcessor();
                if (processor.VerifyIPN(strRequest, out values))
                {
                    #region values
                    decimal total = decimal.Zero;
                    try
                    {
                        total = decimal.Parse(values["mc_gross"], new CultureInfo("en-US"));
                    }
                    catch { }

                    string payer_status = string.Empty;
                    values.TryGetValue("payer_status", out payer_status);
                    string payment_status = string.Empty;
                    values.TryGetValue("payment_status", out payment_status);
                    string pending_reason = string.Empty;
                    values.TryGetValue("pending_reason", out pending_reason);
                    string mc_currency = string.Empty;
                    values.TryGetValue("mc_currency", out mc_currency);
                    string txn_id = string.Empty;
                    values.TryGetValue("txn_id", out txn_id);
                    string txn_type = string.Empty;
                    values.TryGetValue("txn_type", out txn_type);
                    string rp_invoice_id = string.Empty;
                    values.TryGetValue("rp_invoice_id", out rp_invoice_id);
                    string payment_type = string.Empty;
                    values.TryGetValue("payment_type", out payment_type);
                    string payer_id = string.Empty;
                    values.TryGetValue("payer_id", out payer_id);
                    string receiver_id = string.Empty;
                    values.TryGetValue("receiver_id", out receiver_id);
                    string invoice = string.Empty;
                    values.TryGetValue("invoice", out invoice);
                    string payment_fee = string.Empty;
                    values.TryGetValue("payment_fee", out payment_fee);

                    #endregion

                    StringBuilder sb = new StringBuilder();
                    sb.AppendLine("Paypal IPN:");
                    foreach (KeyValuePair <string, string> kvp in values)
                    {
                        sb.AppendLine(kvp.Key + ": " + kvp.Value);
                    }

                    PaymentStatusEnum newPaymentStatus = PaypalHelper.GetPaymentStatus(payment_status, pending_reason);
                    sb.AppendLine("New payment status: " + newPaymentStatus.GetPaymentStatusName());

                    switch (txn_type)
                    {
                    case "recurring_payment_profile_created":
                        //do nothing here
                        break;

                    case "recurring_payment":
                        #region Recurring payment
                    {
                        Guid orderNumberGuid = Guid.Empty;
                        try
                        {
                            orderNumberGuid = new Guid(rp_invoice_id);
                        }
                        catch
                        {
                        }

                        Order initialOrder = this.OrderService.GetOrderByGuid(orderNumberGuid);
                        if (initialOrder != null)
                        {
                            var recurringPayments = this.OrderService.SearchRecurringPayments(0, initialOrder.OrderId, null);
                            foreach (var rp in recurringPayments)
                            {
                                switch (newPaymentStatus)
                                {
                                case PaymentStatusEnum.Authorized:
                                case PaymentStatusEnum.Paid:
                                {
                                    var recurringPaymentHistory = rp.RecurringPaymentHistory;
                                    if (recurringPaymentHistory.Count == 0)
                                    {
                                        //first payment
                                        var rph = new RecurringPaymentHistory()
                                        {
                                            RecurringPaymentId = rp.RecurringPaymentId,
                                            OrderId            = initialOrder.OrderId,
                                            CreatedOn          = DateTime.UtcNow
                                        };
                                        this.OrderService.InsertRecurringPaymentHistory(rph);
                                    }
                                    else
                                    {
                                        //next payments
                                        this.OrderService.ProcessNextRecurringPayment(rp.RecurringPaymentId);
                                        //UNDONE change new order status according to newPaymentStatus
                                        //UNDONE refund/void is not supported
                                    }
                                }
                                break;
                                }
                            }

                            //this.OrderService.InsertOrderNote(newOrder.OrderId, sb.ToString(), DateTime.UtcNow);
                            this.LogService.InsertLog(LogTypeEnum.Unknown, "PayPal IPN. Recurring info", new NopException(sb.ToString()));
                        }
                        else
                        {
                            this.LogService.InsertLog(LogTypeEnum.OrderError, "PayPal IPN. Order is not found", new NopException(sb.ToString()));
                        }
                    }
                        #endregion
                        break;

                    default:
                        #region Standard payment
                    {
                        string orderNumber = string.Empty;
                        values.TryGetValue("custom", out orderNumber);
                        Guid orderNumberGuid = Guid.Empty;
                        try
                        {
                            orderNumberGuid = new Guid(orderNumber);
                        }
                        catch
                        {
                        }

                        Order order = this.OrderService.GetOrderByGuid(orderNumberGuid);
                        if (order != null)
                        {
                            this.OrderService.InsertOrderNote(order.OrderId, sb.ToString(), false, DateTime.UtcNow);
                            switch (newPaymentStatus)
                            {
                            case PaymentStatusEnum.Pending:
                            {
                            }
                            break;

                            case PaymentStatusEnum.Authorized:
                            {
                                if (this.OrderService.CanMarkOrderAsAuthorized(order))
                                {
                                    this.OrderService.MarkAsAuthorized(order.OrderId);
                                }
                            }
                            break;

                            case PaymentStatusEnum.Paid:
                            {
                                if (this.OrderService.CanMarkOrderAsPaid(order))
                                {
                                    this.OrderService.MarkOrderAsPaid(order.OrderId);
                                }
                            }
                            break;

                            case PaymentStatusEnum.Refunded:
                            {
                                if (this.OrderService.CanRefundOffline(order))
                                {
                                    this.OrderService.RefundOffline(order.OrderId);
                                }
                            }
                            break;

                            case PaymentStatusEnum.Voided:
                            {
                                if (this.OrderService.CanVoidOffline(order))
                                {
                                    this.OrderService.VoidOffline(order.OrderId);
                                }
                            }
                            break;

                            default:
                                break;
                            }
                        }
                        else
                        {
                            this.LogService.InsertLog(LogTypeEnum.OrderError, "PayPal IPN. Order is not found", new NopException(sb.ToString()));
                        }
                    }
                        #endregion
                        break;
                    }
                }
                else
                {
                    this.LogService.InsertLog(LogTypeEnum.OrderError, "PayPal IPN failed.", strRequest);
                }
            }
        }
        protected virtual void ProcessRecurringPayment(string invoiceId, PaymentStatus newPaymentStatus, string transactionId, string ipnInfo)
        {
            Guid orderNumberGuid;

            try
            {
                orderNumberGuid = new Guid(invoiceId);
            }
            catch
            {
                orderNumberGuid = Guid.Empty;
            }

            var order = _orderService.GetOrderByGuid(orderNumberGuid);

            if (order == null)
            {
                _logger.Error("PayPal IPN. Order is not found", new NopException(ipnInfo));
                return;
            }

            var recurringPayments = _orderService.SearchRecurringPayments(initialOrderId: order.Id);

            foreach (var rp in recurringPayments)
            {
                switch (newPaymentStatus)
                {
                case PaymentStatus.Authorized:
                case PaymentStatus.Paid:
                {
                    var recurringPaymentHistory = rp.RecurringPaymentHistory;
                    if (!recurringPaymentHistory.Any())
                    {
                        //first payment
                        var rph = new RecurringPaymentHistory
                        {
                            RecurringPaymentId = rp.Id,
                            OrderId            = order.Id,
                            CreatedOnUtc       = DateTime.UtcNow
                        };
                        rp.RecurringPaymentHistory.Add(rph);
                        _orderService.UpdateRecurringPayment(rp);
                    }
                    else
                    {
                        //next payments
                        var processPaymentResult = new ProcessPaymentResult
                        {
                            NewPaymentStatus = newPaymentStatus
                        };
                        if (newPaymentStatus == PaymentStatus.Authorized)
                        {
                            processPaymentResult.AuthorizationTransactionId = transactionId;
                        }
                        else
                        {
                            processPaymentResult.CaptureTransactionId = transactionId;
                        }

                        _orderProcessingService.ProcessNextRecurringPayment(rp,
                                                                            processPaymentResult);
                    }
                }

                break;

                case PaymentStatus.Voided:
                    //failed payment
                    var failedPaymentResult = new ProcessPaymentResult
                    {
                        Errors = new[] { $"PayPal IPN. Recurring payment is {nameof(PaymentStatus.Voided).ToLower()} ." },
                        RecurringPaymentFailed = true
                    };
                    _orderProcessingService.ProcessNextRecurringPayment(rp, failedPaymentResult);
                    break;
                }
            }

            //OrderService.InsertOrderNote(newOrder.OrderId, sb.ToString(), DateTime.UtcNow);
            _logger.Information("PayPal IPN. Recurring info", new NopException(ipnInfo));
        }
        public IActionResult IPNHandler(IFormCollection form)
        {
            //byte[] parameters;
            //using (var stream = new MemoryStream())
            //{
            //    this.Request.Body.CopyTo(stream);
            //    parameters = stream.ToArray();
            //}
            //var strRequest = Encoding.ASCII.GetString(parameters);

            var processor = _paymentService.LoadPaymentMethodBySystemName("Payments.MOLPay") as MOLPayPaymentProcessor;

            if (processor == null ||
                !processor.IsPaymentMethodActive(_paymentSettings) || !processor.PluginDescriptor.Installed)
            {
                throw new NopException("MOLPay module cannot be loaded");
            }

            //if (processor.VerifyIpn(strRequest, out Dictionary<string, string> values))
            //{
            #region values
            var mc_gross = decimal.Zero;
            try
            {
                mc_gross = decimal.Parse(form["mc_gross"], new CultureInfo("en-US"));
            }
            catch { }

            //values.TryGetValue("payer_status", out string payer_status);
            //values.TryGetValue("payment_status", out string payment_status);
            //values.TryGetValue("pending_reason", out string pending_reason);
            //values.TryGetValue("mc_currency", out string mc_currency);
            //values.TryGetValue("txn_id", out string txn_id);
            //values.TryGetValue("txn_type", out string txn_type);
            //values.TryGetValue("rp_invoice_id", out string rp_invoice_id);
            //values.TryGetValue("payment_type", out string payment_type);
            //values.TryGetValue("payer_id", out string payer_id);
            //values.TryGetValue("receiver_id", out string receiver_id);
            //values.TryGetValue("invoice", out string _);
            //values.TryGetValue("payment_fee", out string payment_fee);

            #endregion

            var    skey          = form["skey"];
            var    tranID        = form["tranID"];
            var    domain        = form["domain"];
            var    status        = form["status"];
            var    amount        = form["amount"];
            var    currency      = form["currency"];
            var    paydate       = form["paydate"];
            int    orderid       = Int32.Parse(form["orderid"]);
            var    appcode       = form["appcode"];
            var    error_code    = form["error_code"];
            var    error_desc    = form["error_desc"];
            string txn_type      = form["txn_type"];
            var    rp_invoice_id = form["rp_invoice_id"];
            var    txn_id        = form["txn_id"];
            var    channel       = form["channel"];

            var sb = new StringBuilder();
            sb.AppendLine("MOLPay IPN:");
            foreach (var kvp in form)
            {
                sb.AppendLine(kvp.Key + ": " + kvp.Value);
            }

            var captured = _molPayPaymentSettings.CapturedMode;
            var failed   = _molPayPaymentSettings.FailedMode;
            var pending  = _molPayPaymentSettings.PendingMode;
            var result   = pending;
            switch (status)
            {
            case "00":
                result = captured;
                break;

            case "11":
                result = failed;
                break;

            case "22":
                result = pending;
                break;

            default:
                break;
            }

            //var newPaymentStatus = MOLPayHelper.GetPaymentStatus(payment_status);
            var newPaymentStatus = result;
            sb.AppendLine("New payment status: " + newPaymentStatus);

            switch (txn_type)
            {
            case "recurring_payment_profile_created":
                //do nothing here
                break;

                #region Recurring payment
            case "recurring_payment":
            {
                var orderNumberGuid = Guid.Empty;
                try
                {
                    orderNumberGuid = new Guid(rp_invoice_id);
                }
                catch
                {
                }

                var initialOrder = _orderService.GetOrderByGuid(orderNumberGuid);
                if (initialOrder != null)
                {
                    var recurringPayments = _orderService.SearchRecurringPayments(initialOrderId: initialOrder.Id);
                    foreach (var rp in recurringPayments)
                    {
                        switch (newPaymentStatus)
                        {
                        case PaymentStatus.Authorized:
                        case PaymentStatus.Paid:
                        {
                            var recurringPaymentHistory = rp.RecurringPaymentHistory;
                            if (!recurringPaymentHistory.Any())
                            {
                                //first payment
                                var rph = new RecurringPaymentHistory
                                {
                                    RecurringPaymentId = rp.Id,
                                    OrderId            = initialOrder.Id,
                                    CreatedOnUtc       = DateTime.UtcNow
                                };
                                rp.RecurringPaymentHistory.Add(rph);
                                _orderService.UpdateRecurringPayment(rp);
                            }
                            else
                            {
                                //next payments
                                var processPaymentResult = new ProcessPaymentResult
                                {
                                    NewPaymentStatus = newPaymentStatus
                                };
                                if (newPaymentStatus == PaymentStatus.Authorized)
                                {
                                    processPaymentResult.AuthorizationTransactionId = txn_id;
                                }
                                else
                                {
                                    processPaymentResult.CaptureTransactionId = txn_id;
                                }

                                _orderProcessingService.ProcessNextRecurringPayment(rp, processPaymentResult);
                            }
                        }
                        break;

                        case PaymentStatus.Voided:
                            //failed payment
                            var failedPaymentResult = new ProcessPaymentResult
                            {
                                Errors = new[] { $"MOLPay IPN. Recurring payment is {newPaymentStatus} ." },
                                RecurringPaymentFailed = true
                            };
                            _orderProcessingService.ProcessNextRecurringPayment(rp, failedPaymentResult);
                            break;
                        }
                    }

                    //this.OrderService.InsertOrderNote(newOrder.OrderId, sb.ToString(), DateTime.UtcNow);
                    _logger.Information("MOLPay IPN. Recurring info", new NopException(sb.ToString()));
                }
                else
                {
                    _logger.Error("MOLPay IPN. Order is not found", new NopException(sb.ToString()));
                }
            }
            break;

            case "recurring_payment_failed":
                if (Guid.TryParse(rp_invoice_id, out Guid orderGuid))
                {
                    var initialOrder = _orderService.GetOrderByGuid(orderGuid);
                    if (initialOrder != null)
                    {
                        var recurringPayment = _orderService.SearchRecurringPayments(initialOrderId: initialOrder.Id).FirstOrDefault();
                        //failed payment
                        if (recurringPayment != null)
                        {
                            _orderProcessingService.ProcessNextRecurringPayment(recurringPayment, new ProcessPaymentResult {
                                Errors = new[] { txn_type }, RecurringPaymentFailed = true
                            });
                        }
                    }
                }
                break;

                #endregion
            default:
                #region Standard payment
            {
                //values.TryGetValue("custom", out string orderNumber);
                var orderNumber     = form["custom"];
                var orderNumberGuid = Guid.Empty;
                try
                {
                    orderNumberGuid = new Guid(orderNumber);
                }
                catch
                {
                }

                var order = _orderService.GetOrderByGuid(orderNumberGuid);
                if (order != null)
                {
                    //order note
                    order.OrderNotes.Add(new OrderNote
                        {
                            Note = sb.ToString(),
                            DisplayToCustomer = false,
                            CreatedOnUtc      = DateTime.UtcNow
                        });
                    _orderService.UpdateOrder(order);

                    switch (newPaymentStatus)
                    {
                    case PaymentStatus.Pending:
                    {
                    }
                    break;

                    case PaymentStatus.Authorized:
                    {
                        //validate order total
                        if (Math.Round(mc_gross, 2).Equals(Math.Round(order.OrderTotal, 2)))
                        {
                            //valid
                            if (_orderProcessingService.CanMarkOrderAsAuthorized(order))
                            {
                                _orderProcessingService.MarkAsAuthorized(order);
                            }
                        }
                        else
                        {
                            //not valid
                            var errorStr =
                                $"MOLPay IPN. Returned order total {mc_gross} doesn't equal order total {order.OrderTotal}. Order# {order.Id}.";
                            //log
                            _logger.Error(errorStr);
                            //order note
                            order.OrderNotes.Add(new OrderNote
                                    {
                                        Note = errorStr,
                                        DisplayToCustomer = false,
                                        CreatedOnUtc      = DateTime.UtcNow
                                    });
                            _orderService.UpdateOrder(order);
                        }
                    }
                    break;

                    case PaymentStatus.Paid:
                    {
                        //validate order total
                        if (Math.Round(mc_gross, 2).Equals(Math.Round(order.OrderTotal, 2)))
                        {
                            //valid
                            if (_orderProcessingService.CanMarkOrderAsPaid(order))
                            {
                                order.AuthorizationTransactionId = txn_id;
                                _orderService.UpdateOrder(order);

                                _orderProcessingService.MarkOrderAsPaid(order);
                            }
                        }
                        else
                        {
                            //not valid
                            var errorStr =
                                $"MOLPay IPN. Returned order total {mc_gross} doesn't equal order total {order.OrderTotal}. Order# {order.Id}.";
                            //log
                            _logger.Error(errorStr);
                            //order note
                            order.OrderNotes.Add(new OrderNote
                                    {
                                        Note = errorStr,
                                        DisplayToCustomer = false,
                                        CreatedOnUtc      = DateTime.UtcNow
                                    });
                            _orderService.UpdateOrder(order);
                        }
                    }
                    break;

                    case PaymentStatus.Refunded:
                    {
                        var totalToRefund = Math.Abs(mc_gross);
                        if (totalToRefund > 0 && Math.Round(totalToRefund, 2).Equals(Math.Round(order.OrderTotal, 2)))
                        {
                            //refund
                            if (_orderProcessingService.CanRefundOffline(order))
                            {
                                _orderProcessingService.RefundOffline(order);
                            }
                        }
                        else
                        {
                            //partial refund
                            if (_orderProcessingService.CanPartiallyRefundOffline(order, totalToRefund))
                            {
                                _orderProcessingService.PartiallyRefundOffline(order, totalToRefund);
                            }
                        }
                    }
                    break;

                    case PaymentStatus.Voided:
                    {
                        if (_orderProcessingService.CanVoidOffline(order))
                        {
                            _orderProcessingService.VoidOffline(order);
                        }
                    }
                    break;

                    default:
                        break;
                    }
                }
                else
                {
                    _logger.Error("MOLPay IPN. Order is not found", new NopException(sb.ToString()));
                }
            }
                #endregion
                break;
            }
            //}
            //else
            //{
            //    _logger.Error("MOLPay IPN failed.", new NopException(strRequest));
            //}

            //nothing should be rendered to visitor
            return(Content(""));
        }
Ejemplo n.º 19
0
        public ActionResult IPNHandler()
        {
            byte[] param      = Request.BinaryRead(Request.ContentLength);
            string strRequest = Encoding.ASCII.GetString(param);
            Dictionary <string, string> values;

            var processor = _paymentService.LoadPaymentMethodBySystemName("Payments.PayPalStandard") as PayPalStandardPaymentProcessor;

            if (processor == null ||
                !processor.IsPaymentMethodActive(_paymentSettings) || !processor.PluginDescriptor.Installed)
            {
                throw new NopException("PayPal Standard module cannot be loaded");
            }

            if (processor.VerifyIpn(strRequest, out values))
            {
                #region values
                decimal total = decimal.Zero;
                try
                {
                    total = decimal.Parse(values["mc_gross"], new CultureInfo("en-US"));
                }
                catch { }

                string payer_status = string.Empty;
                values.TryGetValue("payer_status", out payer_status);
                string payment_status = string.Empty;
                values.TryGetValue("payment_status", out payment_status);
                string pending_reason = string.Empty;
                values.TryGetValue("pending_reason", out pending_reason);
                string mc_currency = string.Empty;
                values.TryGetValue("mc_currency", out mc_currency);
                string txn_id = string.Empty;
                values.TryGetValue("txn_id", out txn_id);
                string txn_type = string.Empty;
                values.TryGetValue("txn_type", out txn_type);
                string rp_invoice_id = string.Empty;
                values.TryGetValue("rp_invoice_id", out rp_invoice_id);
                string payment_type = string.Empty;
                values.TryGetValue("payment_type", out payment_type);
                string payer_id = string.Empty;
                values.TryGetValue("payer_id", out payer_id);
                string receiver_id = string.Empty;
                values.TryGetValue("receiver_id", out receiver_id);
                string invoice = string.Empty;
                values.TryGetValue("invoice", out invoice);
                string payment_fee = string.Empty;
                values.TryGetValue("payment_fee", out payment_fee);

                #endregion

                var sb = new StringBuilder();
                sb.AppendLine("Paypal IPN:");
                foreach (KeyValuePair <string, string> kvp in values)
                {
                    sb.AppendLine(kvp.Key + ": " + kvp.Value);
                }

                var newPaymentStatus = PaypalHelper.GetPaymentStatus(payment_status, pending_reason);
                sb.AppendLine("New payment status: " + newPaymentStatus);

                switch (txn_type)
                {
                case "recurring_payment_profile_created":
                    //do nothing here
                    break;

                case "recurring_payment":
                    #region Recurring payment
                {
                    Guid orderNumberGuid = Guid.Empty;
                    try
                    {
                        orderNumberGuid = new Guid(rp_invoice_id);
                    }
                    catch
                    {
                    }

                    var initialOrder = _orderService.GetOrderByGuid(orderNumberGuid);
                    if (initialOrder != null)
                    {
                        var recurringPayments = _orderService.SearchRecurringPayments(0, 0, initialOrder.Id, null, 0, int.MaxValue);
                        foreach (var rp in recurringPayments)
                        {
                            switch (newPaymentStatus)
                            {
                            case PaymentStatus.Authorized:
                            case PaymentStatus.Paid:
                            {
                                var recurringPaymentHistory = rp.RecurringPaymentHistory;
                                if (recurringPaymentHistory.Count == 0)
                                {
                                    //first payment
                                    var rph = new RecurringPaymentHistory
                                    {
                                        RecurringPaymentId = rp.Id,
                                        OrderId            = initialOrder.Id,
                                        CreatedOnUtc       = DateTime.UtcNow
                                    };
                                    rp.RecurringPaymentHistory.Add(rph);
                                    _orderService.UpdateRecurringPayment(rp);
                                }
                                else
                                {
                                    //next payments
                                    _orderProcessingService.ProcessNextRecurringPayment(rp);
                                }
                            }
                            break;
                            }
                        }

                        //this.OrderService.InsertOrderNote(newOrder.OrderId, sb.ToString(), DateTime.UtcNow);
                        _logger.Information("PayPal IPN. Recurring info", new NopException(sb.ToString()));
                    }
                    else
                    {
                        _logger.Error("PayPal IPN. Order is not found", new NopException(sb.ToString()));
                    }
                }
                    #endregion
                    break;

                default:
                    #region Standard payment
                {
                    string orderNumber = string.Empty;
                    values.TryGetValue("custom", out orderNumber);
                    Guid orderNumberGuid = Guid.Empty;
                    try
                    {
                        orderNumberGuid = new Guid(orderNumber);
                    }
                    catch
                    {
                    }

                    var order = _orderService.GetOrderByGuid(orderNumberGuid);
                    if (order != null)
                    {
                        //order note
                        order.OrderNotes.Add(new OrderNote
                            {
                                Note = sb.ToString(),
                                DisplayToCustomer = false,
                                CreatedOnUtc      = DateTime.UtcNow
                            });
                        _orderService.UpdateOrder(order);

                        switch (newPaymentStatus)
                        {
                        case PaymentStatus.Pending:
                        {
                        }
                        break;

                        case PaymentStatus.Authorized:
                        {
                            if (_orderProcessingService.CanMarkOrderAsAuthorized(order))
                            {
                                _orderProcessingService.MarkAsAuthorized(order);
                            }
                        }
                        break;

                        case PaymentStatus.Paid:
                        {
                            if (_orderProcessingService.CanMarkOrderAsPaid(order))
                            {
                                order.AuthorizationTransactionId = txn_id;
                                _orderService.UpdateOrder(order);

                                _orderProcessingService.MarkOrderAsPaid(order);
                            }
                        }
                        break;


                        default:
                            break;
                        }
                    }
                    else
                    {
                        _logger.Error("PayPal IPN. Order is not found", new NopException(sb.ToString()));
                    }
                }
                    #endregion
                    break;
                }
            }
            else
            {
                _logger.Error("PayPal IPN failed.", new NopException(strRequest));
            }

            //nothing should be rendered to visitor
            return(Content(""));
        }
        /// <summary>
        /// Process next recurring psayment
        /// </summary>
        /// <param name="recurringPayment">Recurring payment</param>
        public virtual async Task ProcessNextRecurringPayment(RecurringPayment recurringPayment)
        {
            if (recurringPayment == null)
            {
                throw new ArgumentNullException("recurringPayment");
            }
            try
            {
                if (!recurringPayment.IsActive)
                {
                    throw new GrandException("Recurring payment is not active");
                }

                var initialOrder = recurringPayment.InitialOrder;
                if (initialOrder == null)
                {
                    throw new GrandException("Initial order could not be loaded");
                }

                var customer = await _customerService.GetCustomerById(initialOrder.CustomerId);

                if (customer == null)
                {
                    throw new GrandException("Customer could not be loaded");
                }

                var nextPaymentDate = recurringPayment.NextPaymentDate;
                if (!nextPaymentDate.HasValue)
                {
                    throw new GrandException("Next payment date could not be calculated");
                }

                //payment info
                var paymentInfo = new ProcessPaymentRequest {
                    StoreId              = initialOrder.StoreId,
                    CustomerId           = customer.Id,
                    OrderGuid            = Guid.NewGuid(),
                    IsRecurringPayment   = true,
                    InitialOrderId       = initialOrder.Id,
                    RecurringCycleLength = recurringPayment.CycleLength,
                    RecurringCyclePeriod = recurringPayment.CyclePeriod,
                    RecurringTotalCycles = recurringPayment.TotalCycles,
                };

                //place a new order
                var orderConfirmationService = _serviceProvider.GetRequiredService <IOrderConfirmationService>();
                var result = await orderConfirmationService.PlaceOrder(paymentInfo);

                if (result.Success)
                {
                    if (result.PlacedOrder == null)
                    {
                        throw new GrandException("Placed order could not be loaded");
                    }

                    var rph = new RecurringPaymentHistory {
                        RecurringPaymentId = recurringPayment.Id,
                        CreatedOnUtc       = DateTime.UtcNow,
                        OrderId            = result.PlacedOrder.Id,
                    };
                    recurringPayment.RecurringPaymentHistory.Add(rph);
                    await _orderService.UpdateRecurringPayment(recurringPayment);
                }
                else
                {
                    string error = "";
                    for (int i = 0; i < result.Errors.Count; i++)
                    {
                        error += string.Format("Error {0}: {1}", i, result.Errors[i]);
                        if (i != result.Errors.Count - 1)
                        {
                            error += ". ";
                        }
                    }
                    throw new GrandException(error);
                }
            }
            catch (Exception exc)
            {
                _logger.Error(string.Format("Error while processing recurring order. {0}", exc.Message), exc);
                throw;
            }
        }