Exemplo n.º 1
0
        public ActionResult Index(string error, string transaction_id, string session_id, string merchant_reference, string trackingNumber)
        {
            if (PageEditing.PageIsInEditMode)
            {
                return(new EmptyResult());
            }

            string redirectUrl = null;

            Logger.Debug($"HttpContext.Request.RawUrl: {HttpContext.Request.RawUrl}.");
            Logger.Debug($"Dintero payment error: {error}; transaction_id: {transaction_id}; session_id: {session_id}; merchant_reference: {merchant_reference}; trackingNumber: {trackingNumber}");

            var cancelUrl = UriUtil.GetUrlFromStartPageReferenceProperty("DinteroPaymentCancelPage");
            var acceptUrl = UriUtil.GetUrlFromStartPageReferenceProperty("DinteroPaymentLandingPage");

            cancelUrl = UriUtil.AddQueryString(cancelUrl, "success", "false");
            var orderNumber = merchant_reference + trackingNumber;

            InitializeResponse();

            Logger.Debug($"Lock {orderNumber}");
            LockHelper.Lock(orderNumber);

            var gateway = ServiceLocator.Current.GetInstance <DinteroPaymentGateway>();

            Logger.Debug($"Dintero payment {orderNumber} start processing");

            try
            {
                ICart currentCart;
                if (string.IsNullOrWhiteSpace(session_id))
                {
                    // redirect_url is called
                    currentCart =
                        _orderRepository.LoadCart <ICart>(PrincipalInfo.CurrentPrincipal.GetContactId(), Cart.DefaultName);

                    // in case it's redirect from Dintero, but for some reason cookies are not set OR it's redirect from checkout(trackingNumber not empty)
                    if (currentCart == null && (!string.IsNullOrWhiteSpace(transaction_id) || !string.IsNullOrEmpty(trackingNumber)))
                    {
                        var predictableOrderId = string.IsNullOrEmpty(trackingNumber) ? merchant_reference : trackingNumber;
                        Logger.Debug($"Trying to get cart by predictable order Id predictableOrderId: {predictableOrderId}");
                        currentCart = OrderHelper.GetCartByPredictableOrderId(predictableOrderId);
                        if (currentCart != null)
                        {
                            Logger.Debug($"Cart has been loaded by predictableOrderId: {predictableOrderId}");
                        }
                    }

                    Logger.Debug($"CurrentPrincipal {PrincipalInfo.CurrentPrincipal.GetContactId()}");

                    if (currentCart == null)
                    {
                        // check if cart was processed by return_url / callback_url
                        var order = OrderHelper.GetOrderByTrackingNumber(merchant_reference);
                        if (order == null)
                        {
                            Logger.Debug(
                                $"Dintero payment {orderNumber} Cart cannot be loaded!!! contactId: {PrincipalInfo.CurrentPrincipal.GetContactId()}.");

                            throw new PaymentException(PaymentException.ErrorType.ProviderError, "",
                                                       "Cart cannot be loaded!!!");
                        }

                        Logger.Debug(
                            $"Dintero payment {orderNumber} redirect to accept Url. Order status - {((IOrderGroup) order).OrderStatus}");
                        return(Redirect(DinteroPaymentGateway.UpdateAcceptUrl(order, acceptUrl,
                                                                              ((IOrderGroup)order).OrderStatus == OrderStatus.OnHold)));
                    }
                    else
                    {
                        Logger.Debug($"CurrentCart.OrderFormId= {currentCart.Forms.First().OrderFormId}");
                        Logger.Debug($"Principal From Cart {currentCart.CustomerId}");
                    }

                    if (!currentCart.Forms.Any() || !currentCart.GetFirstForm().Payments.Any())
                    {
                        Logger.Debug($"Dintero payment {orderNumber} Cart is invalid!");
                        throw new PaymentException(PaymentException.ErrorType.ProviderError, "", "Cart is invalid!");
                    }

                    Logger.Debug($"Dintero payment {orderNumber} retrieved cart for current principal");
                }
                else
                {
                    // if session_id parameter is set it means that it is either Dintero callback was sent (in pair with redirect)
                    // or on_hold transaction was processed
                    // in the first case we need to check whether redirect was processed if yes then skip
                    // in the second we need to release order (check transaction if it is authorised or failed)

                    // check if cart has been already processed by redirect_url
                    currentCart = OrderHelper.GetCartByDinteroSessionId(session_id);
                    if (currentCart == null)
                    {
                        var order = OrderHelper.GetOrderByTrackingNumber(merchant_reference);
                        if (order != null && ((IOrderGroup)order).OrderStatus == OrderStatus.OnHold)
                        {
                            Logger.Debug($"Processing OnHold Order.");
                            var result = gateway.ProcessOnHoldOrder(order.Id, transaction_id);
                            if (result == null)
                            {
                                Logger.Debug("Unable to release OnHold order.");
                            }
                            else
                            {
                                Logger.Debug($"Processing OnHold Order completed: {result.OrderStatus}.");
                            }
                        }
                        else
                        {
                            Logger.Debug($"Dintero payment {orderNumber} cart is already processed");
                        }
                        return(new HttpStatusCodeResult(HttpStatusCode.OK));
                    }

                    Logger.Debug($"CurrentPrincipal {currentCart.CustomerId}");
                    Logger.Debug($"CurrentCart.OrderFormId= {currentCart.Forms.First().OrderFormId}");
                    Logger.Debug($"Dintero payment {orderNumber} cart as retrieved by session Id");
                }

                var formPayments = currentCart.Forms.SelectMany(f => f.Payments).Select(p => p.PaymentId);

                var payment = currentCart.Forms.SelectMany(f => f.Payments).FirstOrDefault(c =>
                                                                                           c.PaymentMethodId.Equals(_requestsHelper.Configuration.PaymentMethodId));

                if (payment == null)
                {
                    Logger.Debug($"Dintero payment {orderNumber} payment is null");

                    throw new PaymentException(PaymentException.ErrorType.ProviderError, "",
                                               $"Payment was not specified ({_requestsHelper.Configuration.PaymentMethodId}). Form payments: {string.Join(";", formPayments)}");
                }

                if (string.IsNullOrWhiteSpace(transaction_id) && string.IsNullOrWhiteSpace(error))
                {
                    var sessionData = _requestsHelper.CreateTransaction(payment, currentCart, trackingNumber);

                    if (sessionData != null)
                    {
                        var cart = _orderRepository.LoadCart <Cart>(currentCart.CustomerId, Cart.DefaultName);
                        cart[DinteroConstants.DinteroSessionMetaField] = sessionData.SessionId;
                        cart.OrderForms[0][DinteroConstants.DinteroSessionMetaField] = sessionData.SessionId;
                        cart.AcceptChanges();

                        Logger.Debug($"Dintero payment {orderNumber} redirect to checkout");

                        return(Redirect(sessionData.CheckoutUrl));
                    }

                    Logger.Debug($"Dintero payment {orderNumber} redirect to cancel");

                    return(Redirect(cancelUrl));
                }

                cancelUrl = UriUtil.AddQueryString(cancelUrl, "paymentMethod", "dintero");

                if (string.IsNullOrWhiteSpace(error) && !string.IsNullOrWhiteSpace(transaction_id) &&
                    !string.IsNullOrWhiteSpace(merchant_reference))
                {
                    payment.TransactionID   = transaction_id;
                    payment.TransactionType = TransactionType.Authorization.ToString();

                    redirectUrl = gateway.ProcessSuccessfulTransaction(currentCart, payment, transaction_id,
                                                                       merchant_reference, acceptUrl, cancelUrl);
                }
                else
                {
                    TempData["Message"] = error;
                    redirectUrl         = gateway.ProcessUnsuccessfulTransaction(cancelUrl, error);
                }

                Logger.Debug($"Dintero payment {orderNumber} call post authorize");

                DinteroPaymentGateway.PostProcessPayment.PostAuthorize(payment, error, transaction_id,
                                                                       merchant_reference);
            }
            catch (Exception e)
            {
                Logger.Error($"Dintero payment {orderNumber} failed {e}");
            }
            finally
            {
                Logger.Debug("Release");
                LockHelper.Release(orderNumber);
            }

            if (string.IsNullOrWhiteSpace(session_id))
            {
                Logger.Debug($"Dintero payment {orderNumber} redirect to {redirectUrl}");
                return(Redirect(redirectUrl));
            }

            return(new HttpStatusCodeResult(HttpStatusCode.OK));
        }