public IHttpActionResult PostProcessPayment(webModel.PaymentCallbackParameters callback)
        {
            if (callback != null && callback.Parameters != null && callback.Parameters.Any(param => param.Key.EqualsInvariant("orderid")))
            {
                var orderId = callback.Parameters.First(param => param.Key.EqualsInvariant("orderid")).Value;
                //some payment method require customer number to be passed and returned. First search customer order by number
                var order = _searchService.SearchCustomerOrders(new CustomerOrderSearchCriteria {
                    Number = orderId, ResponseGroup = CustomerOrderResponseGroup.Full.ToString()
                }).Results.FirstOrDefault();

                //if order not found by order number search by order id
                if (order == null)
                {
                    order = _customerOrderService.GetByIds(new[] { orderId }, CustomerOrderResponseGroup.Full.ToString()).FirstOrDefault();
                }

                if (order == null)
                {
                    throw new NullReferenceException("order not found");
                }

                var store      = _storeService.GetById(order.StoreId);
                var parameters = new NameValueCollection();
                foreach (var param in callback.Parameters)
                {
                    parameters.Add(param.Key, param.Value);
                }
                var paymentMethod = store.PaymentMethods.Where(x => x.IsActive).FirstOrDefault(x => x.ValidatePostProcessRequest(parameters).IsSuccess);
                if (paymentMethod != null)
                {
                    var paymentOuterId = paymentMethod.ValidatePostProcessRequest(parameters).OuterId;

                    var payment = order.InPayments.FirstOrDefault(x => string.IsNullOrEmpty(x.OuterId) || x.OuterId == paymentOuterId);
                    if (payment == null)
                    {
                        throw new NullReferenceException("appropriate paymentMethod not found");
                    }

                    var context = new PostProcessPaymentEvaluationContext
                    {
                        Order      = order,
                        Payment    = payment,
                        Store      = store,
                        OuterId    = paymentOuterId,
                        Parameters = parameters
                    };

                    var retVal = paymentMethod.PostProcessPayment(context);
                    if (retVal != null)
                    {
                        _customerOrderService.SaveChanges(new[] { order });
                    }

                    // order Number is required
                    retVal.OrderId = order.Number;
                    return(Ok(retVal));
                }
            }
            return(Ok(new PostProcessPaymentResult {
                ErrorMessage = "cancel payment"
            }));
        }
Example #2
0
        public IHttpActionResult PostProcessPayment(webModel.PaymentCallbackParameters callback)
        {
            var parameters = new NameValueCollection();

            foreach (var param in callback?.Parameters ?? Array.Empty <KeyValuePair>())
            {
                parameters.Add(param.Key, param.Value);
            }
            var orderId = parameters.Get("orderid");

            if (string.IsNullOrEmpty(orderId))
            {
                throw new InvalidOperationException("the 'orderid' parameter must be passed");
            }

            //some payment method require customer number to be passed and returned. First search customer order by number
            var searchCriteria = AbstractTypeFactory <CustomerOrderSearchCriteria> .TryCreateInstance();

            searchCriteria.Number        = orderId;
            searchCriteria.ResponseGroup = CustomerOrderResponseGroup.Full.ToString();
            //if order not found by order number search by order id
            var order = _searchService.SearchCustomerOrders(searchCriteria).Results.FirstOrDefault() ?? _customerOrderService.GetByIds(new[] { orderId }, CustomerOrderResponseGroup.Full.ToString()).FirstOrDefault();

            if (order == null)
            {
                throw new InvalidOperationException($"Cannot find order with ID {orderId}");
            }

            var orderPaymentsCodes = order.InPayments.Select(x => x.GatewayCode).Distinct().ToArray();
            var store             = _storeService.GetById(order.StoreId);
            var paymentMethodCode = parameters.Get("code");
            //Need to use concrete  payment method if it code passed otherwise use all order payment methods
            var paymentMethods = store.PaymentMethods.Where(x => x.IsActive)
                                 .Where(x => orderPaymentsCodes.Contains(x.Code));

            if (!string.IsNullOrEmpty(paymentMethodCode))
            {
                paymentMethods = paymentMethods.Where(x => x.Code.EqualsInvariant(paymentMethodCode));
            }

            foreach (var paymentMethod in paymentMethods)
            {
                //Each payment method must check that these parameters are addressed to it
                var result = paymentMethod.ValidatePostProcessRequest(parameters);
                if (result.IsSuccess)
                {
                    var paymentOuterId = result.OuterId;
                    var payment        = order.InPayments.FirstOrDefault(x => string.IsNullOrEmpty(x.OuterId) || x.OuterId == paymentOuterId);
                    if (payment == null)
                    {
                        throw new InvalidOperationException(@"Cannot find payment");
                    }
                    var context = new PostProcessPaymentEvaluationContext
                    {
                        Order      = order,
                        Payment    = payment,
                        Store      = store,
                        OuterId    = paymentOuterId,
                        Parameters = parameters
                    };
                    var retVal = paymentMethod.PostProcessPayment(context);
                    if (retVal != null)
                    {
                        _customerOrderService.SaveChanges(new[] { order });

                        // order Number is required
                        retVal.OrderId = order.Number;
                    }
                    return(Ok(retVal));
                }
            }
            return(Ok(new PostProcessPaymentResult {
                ErrorMessage = "Payment method not found"
            }));
        }