/// <summary>
        /// Create webhook that receive events for the subscribed event types
        /// </summary>
        /// <returns>Webhook id</returns>
        protected string CreateWebHook()
        {
            var storeScope = GetActiveStoreScopeConfiguration(_storeService, _workContext);
            var payPalDirectPaymentSettings = _settingService.LoadSetting <PayPalDirectPaymentSettings>(storeScope);

            try
            {
                var apiContext = PaypalHelper.GetApiContext(payPalDirectPaymentSettings);
                if (!string.IsNullOrEmpty(payPalDirectPaymentSettings.WebhookId))
                {
                    try
                    {
                        return(Webhook.Get(apiContext, payPalDirectPaymentSettings.WebhookId).id);
                    }
                    catch (PayPal.PayPalException) { }
                }

                var currentStore = storeScope > 0 ? _storeService.GetStoreById(storeScope) : _storeContext.CurrentStore;
                var webhook      = new Webhook
                {
                    event_types = new List <WebhookEventType> {
                        new WebhookEventType {
                            name = "*"
                        }
                    },
                    url = string.Format("{0}Plugins/PaymentPayPalDirect/Webhook", currentStore.SslEnabled ? currentStore.SecureUrl : currentStore.Url)
                }.Create(apiContext);

                return(webhook.id);
            }
            catch (PayPal.PayPalException exc)
            {
                if (exc is PayPal.ConnectionException)
                {
                    var error = JsonFormatter.ConvertFromJson <Error>((exc as PayPal.ConnectionException).Response);
                    if (error != null)
                    {
                        _logger.Error(string.Format("PayPal error: {0} ({1})", error.message, error.name));
                        if (error.details != null)
                        {
                            error.details.ForEach(x => _logger.Error(string.Format("{0} {1}", x.field, x.issue)));
                        }
                    }
                    else
                    {
                        _logger.Error(exc.InnerException != null ? exc.InnerException.Message : exc.Message);
                    }
                }
                else
                {
                    _logger.Error(exc.InnerException != null ? exc.InnerException.Message : exc.Message);
                }

                return(string.Empty);
            }
        }
        public ActionResult WebhookEventsHandler()
        {
            var storeScope = GetActiveStoreScopeConfiguration(_storeService, _workContext);
            var payPalDirectPaymentSettings = _settingService.LoadSetting <PayPalDirectPaymentSettings>(storeScope);

            try
            {
                var requestBody = string.Empty;
                using (var stream = new StreamReader(Request.InputStream))
                {
                    requestBody = stream.ReadToEnd();
                }
                var apiContext = PaypalHelper.GetApiContext(payPalDirectPaymentSettings);

                //validate request
                if (!WebhookEvent.ValidateReceivedEvent(apiContext, Request.Headers, requestBody, payPalDirectPaymentSettings.WebhookId))
                {
                    _logger.Error("PayPal error: webhook event was not validated");
                    return(new HttpStatusCodeResult(HttpStatusCode.OK));
                }

                var webhook = JsonFormatter.ConvertFromJson <WebhookEvent>(requestBody);

                //recurring payment
                if (webhook.resource_type.ToLowerInvariant().Equals("sale"))
                {
                    var sale = JsonFormatter.ConvertFromJson <Sale>(webhook.resource.ToString());
                    if (!string.IsNullOrEmpty(sale.billing_agreement_id))
                    {
                        //get agreement
                        var agreement    = Agreement.Get(apiContext, sale.billing_agreement_id);
                        var initialOrder = _orderService.GetOrderByGuid(new Guid(agreement.description));
                        if (initialOrder != null)
                        {
                            var recurringPayment = _orderService.SearchRecurringPayments(initialOrderId: initialOrder.Id).FirstOrDefault();
                            if (recurringPayment != null)
                            {
                                if (sale.state.ToLowerInvariant().Equals("completed"))
                                {
                                    if (recurringPayment.RecurringPaymentHistory.Count == 0)
                                    {
                                        //first payment
                                        initialOrder.PaymentStatus        = PaymentStatus.Paid;
                                        initialOrder.CaptureTransactionId = sale.id;
                                        _orderService.UpdateOrder(initialOrder);

                                        recurringPayment.RecurringPaymentHistory.Add(new RecurringPaymentHistory
                                        {
                                            RecurringPaymentId = recurringPayment.Id,
                                            OrderId            = initialOrder.Id,
                                            CreatedOnUtc       = DateTime.UtcNow
                                        });
                                        _orderService.UpdateRecurringPayment(recurringPayment);
                                    }
                                    else
                                    {
                                        //next payments
                                        var orders = _orderService.GetOrdersByIds(recurringPayment.RecurringPaymentHistory.Select(order => order.OrderId).ToArray());
                                        if (!orders.Any(order => !string.IsNullOrEmpty(order.CaptureTransactionId) &&
                                                        order.CaptureTransactionId.Equals(sale.id, StringComparison.InvariantCultureIgnoreCase)))
                                        {
                                            var processPaymentResult = new ProcessPaymentResult
                                            {
                                                NewPaymentStatus     = PaymentStatus.Paid,
                                                CaptureTransactionId = sale.id
                                            };
                                            _orderProcessingService.ProcessNextRecurringPayment(recurringPayment, processPaymentResult);
                                        }
                                    }
                                }
                                else
                                {
                                    _logger.Error(string.Format("PayPal error: Sale is {0} for the order #{1}", sale.state, initialOrder.Id));
                                }
                            }
                        }
                    }
                }

                return(new HttpStatusCodeResult(HttpStatusCode.OK));
            }
            catch (PayPal.PayPalException exc)
            {
                if (exc is PayPal.ConnectionException)
                {
                    var error = JsonFormatter.ConvertFromJson <Error>((exc as PayPal.ConnectionException).Response);
                    if (error != null)
                    {
                        _logger.Error(string.Format("PayPal error: {0} ({1})", error.message, error.name));
                        if (error.details != null)
                        {
                            error.details.ForEach(x => _logger.Error(string.Format("{0} {1}", x.field, x.issue)));
                        }
                    }
                    else
                    {
                        _logger.Error(exc.InnerException != null ? exc.InnerException.Message : exc.Message);
                    }
                }
                else
                {
                    _logger.Error(exc.InnerException != null ? exc.InnerException.Message : exc.Message);
                }

                return(new HttpStatusCodeResult(HttpStatusCode.OK));
            }
        }
示例#3
0
        public IActionResult WebhookEventsHandler()
        {
            var storeScope = _storeContext.ActiveStoreScopeConfiguration;
            var payPalDirectPaymentSettings = _settingService.LoadSetting <PayPalDirectPaymentSettings>(storeScope);

            try
            {
                var requestBody = string.Empty;
                using (var stream = new StreamReader(this.Request.Body, Encoding.UTF8))
                {
                    requestBody = stream.ReadToEnd();
                }
                var apiContext = PaypalHelper.GetApiContext(payPalDirectPaymentSettings);

                //validate request
                var headers = new NameValueCollection();
                this.Request.Headers.ToList().ForEach(header => headers.Add(header.Key, header.Value));
                if (!WebhookEvent.ValidateReceivedEvent(apiContext, headers, requestBody, payPalDirectPaymentSettings.WebhookId))
                {
                    _logger.Error("PayPal error: webhook event was not validated");
                    return(Ok());
                }

                var webhook = JsonFormatter.ConvertFromJson <WebhookEvent>(requestBody);

                if (webhook.resource_type.ToLowerInvariant().Equals("sale"))
                {
                    var sale = JsonFormatter.ConvertFromJson <Sale>(webhook.resource.ToString());

                    //recurring payment
                    if (!string.IsNullOrEmpty(sale.billing_agreement_id))
                    {
                        //get agreement
                        var agreement    = Agreement.Get(apiContext, sale.billing_agreement_id);
                        var initialOrder = _orderService.GetOrderByGuid(new Guid(agreement.description));
                        if (initialOrder != null)
                        {
                            var recurringPayment = _orderService.SearchRecurringPayments(initialOrderId: initialOrder.Id).FirstOrDefault();
                            if (recurringPayment != null)
                            {
                                if (sale.state.ToLowerInvariant().Equals("completed"))
                                {
                                    if (recurringPayment.RecurringPaymentHistory.Count == 0)
                                    {
                                        //first payment
                                        initialOrder.PaymentStatus        = PaymentStatus.Paid;
                                        initialOrder.CaptureTransactionId = sale.id;
                                        _orderService.UpdateOrder(initialOrder);

                                        recurringPayment.RecurringPaymentHistory.Add(new RecurringPaymentHistory
                                        {
                                            RecurringPaymentId = recurringPayment.Id,
                                            OrderId            = initialOrder.Id,
                                            CreatedOnUtc       = DateTime.UtcNow
                                        });
                                        _orderService.UpdateRecurringPayment(recurringPayment);
                                    }
                                    else
                                    {
                                        //next payments
                                        var orders = _orderService.GetOrdersByIds(recurringPayment.RecurringPaymentHistory.Select(order => order.OrderId).ToArray());
                                        if (!orders.Any(order => !string.IsNullOrEmpty(order.CaptureTransactionId) &&
                                                        order.CaptureTransactionId.Equals(sale.id, StringComparison.InvariantCultureIgnoreCase)))
                                        {
                                            var processPaymentResult = new ProcessPaymentResult
                                            {
                                                NewPaymentStatus     = PaymentStatus.Paid,
                                                CaptureTransactionId = sale.id,
                                                AvsResult            = sale.processor_response?.avs_code ?? string.Empty,
                                                Cvv2Result           = sale.processor_response?.cvv_code ?? string.Empty
                                            };
                                            _orderProcessingService.ProcessNextRecurringPayment(recurringPayment, processPaymentResult);
                                        }
                                    }
                                }
                                else if (sale.state.ToLowerInvariant().Equals("denied"))
                                {
                                    //payment denied
                                    _orderProcessingService.ProcessNextRecurringPayment(recurringPayment,
                                                                                        new ProcessPaymentResult {
                                        Errors = new[] { webhook.summary }, RecurringPaymentFailed = true
                                    });
                                }
                                else
                                {
                                    _logger.Error(
                                        $"PayPal error: Sale is {sale.state} for the order #{initialOrder.Id}");
                                }
                            }
                        }
                    }
                    else
                    //standard payment
                    {
                        var order = _orderService.GetOrderByGuid(new Guid(sale.invoice_number));
                        if (order != null)
                        {
                            if (sale.state.ToLowerInvariant().Equals("completed"))
                            {
                                if (_orderProcessingService.CanMarkOrderAsPaid(order))
                                {
                                    order.CaptureTransactionId     = sale.id;
                                    order.CaptureTransactionResult = sale.state;
                                    _orderService.UpdateOrder(order);
                                    _orderProcessingService.MarkOrderAsPaid(order);
                                }
                            }
                            if (sale.state.ToLowerInvariant().Equals("denied"))
                            {
                                var reason =
                                    $"Payment is denied. {(sale.fmf_details != null ? $"Based on fraud filter: {sale.fmf_details.name}. {sale.fmf_details.description}" : string.Empty)}";
                                order.OrderNotes.Add(new OrderNote
                                {
                                    Note = reason,
                                    DisplayToCustomer = false,
                                    CreatedOnUtc      = DateTime.UtcNow
                                });
                                _logger.Error($"PayPal error: {reason}");
                            }
                        }
                        else
                        {
                            _logger.Error($"PayPal error: Order with GUID {sale.invoice_number} was not found");
                        }
                    }
                }

                return(Ok());
            }
            catch (PayPal.PayPalException exc)
            {
                if (exc is PayPal.ConnectionException)
                {
                    var error = JsonFormatter.ConvertFromJson <Error>((exc as PayPal.ConnectionException).Response);
                    if (error != null)
                    {
                        _logger.Error($"PayPal error: {error.message} ({error.name})");
                        if (error.details != null)
                        {
                            error.details.ForEach(x => _logger.Error($"{x.field} {x.issue}"));
                        }
                    }
                    else
                    {
                        _logger.Error(exc.InnerException != null ? exc.InnerException.Message : exc.Message);
                    }
                }
                else
                {
                    _logger.Error(exc.InnerException != null ? exc.InnerException.Message : exc.Message);
                }

                return(Ok());
            }
        }