/// <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)); } }
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()); } }