/// <summary> /// Create a webhook /// </summary> /// <param name="url">Webhook url</param> /// <param name="event">Webhook event</param> /// <returns></returns> public async Task <Webhook> CreateWebhook(string url, WebhookEvent _event) { try { var body = new Dictionary <string, string> { { "url", url }, { "event", _event.Value } }; return(await httpService.PostAsync <Webhook>(URL_WEBHOOKS, body)); } catch (ApiException e) { if (e.ApiError != null && e.ApiError.Errors != null) { throw new ValidationException(e.StatusCode, e.ApiError); } throw e; } }
/// <summary> /// Update a single webhook /// </summary> /// <param name="id">Webhook id</param> /// <param name="url">Webhook url</param> /// <param name="event">Webhook event</param> /// <returns></returns> public async Task <Webhook> UpdateWebhook(Guid id, string url, WebhookEvent _event) { try { var body = new Dictionary <string, string> { { "url", url }, { "event", _event.Value } }; return(await httpService.PatchAsync <Webhook>(URL_WEBHOOKS + "/{id}", body, null, HTTP.Utils.GetSegment(id.ToString()))); } catch (ApiException e) { if (e.ApiError != null && e.ApiError.Errors != null) { throw new ValidationException(e.StatusCode, e.ApiError); } throw e; } }
private async Task ProcessEvent(WebhookEvent evt) { try { using var scope = _scopeFactory.CreateScope(); var context = scope.ServiceProvider.GetRequiredService <PlayerContext>(); // The subscriptions to the current event var subscriptions = await context.Webhooks .Include(w => w.EventTypes) .Where(w => w.EventTypes.Any(et => et.EventType == evt.Type)) .ToListAsync(); var pendingEvents = new List <PendingEventEntity>(); foreach (var subscription in subscriptions) { var pendingEvent = new PendingEventEntity { EventType = evt.Type, SubscriptionId = subscription.Id, Timestamp = evt.Timestamp, Payload = JsonSerializer.Serialize(evt) }; pendingEvents.Add(pendingEvent); } await context.PendingEvents.AddRangeAsync(pendingEvents); await context.SaveChangesAsync(); pendingEvents.ForEach(async x => await AddPendingEvent(x)); } catch (Exception ex) { _logger.LogError(ex, $"Exception processing Event with id = {evt?.Id}"); } }
public IHttpActionResult get() { var test = db.WebHookLogs.Where(a => a.Id == 19935).Select(a => a.body).FirstOrDefault(); WebhookEvent uwebhook = JsonConvert.DeserializeObject <WebhookEvent>(test); switch (uwebhook.entity) { case "invoice": WebhookEventInvoice webhookinvoice = JsonConvert.DeserializeObject <WebhookEventInvoice>(test); UNMSHelper.addorupdateInvoiceFromUNMS(webhookinvoice.extraData.entity); break; case "payment": WebhookEventPayment webhookpayment = JsonConvert.DeserializeObject <WebhookEventPayment>(test); if (webhookpayment.extraData.entity.Note != "from Xero") { UNMSHelper.addorupdatePaymentFromUNMS(webhookpayment.extraData.entity); } break; case "client": WebhookEventClient webhookclient = JsonConvert.DeserializeObject <WebhookEventClient>(test); UNMSHelper.addorupdateClientFromUNMS(webhookclient.extraData.entity); break; case "ticket": WebhookEventTicket webhookticket = JsonConvert.DeserializeObject <WebhookEventTicket>(test); UNMSHelper.editTicketFromUNMS(webhookticket.extraData.entity); break; case "service": WebhookEventService webhookservice = JsonConvert.DeserializeObject <WebhookEventService>(test); UNMSHelper.suspendServiceFromUNMS(webhookservice.extraData.entity); break; } return(Ok()); }
public void WhenWrite_ThenPostsEventToSubscribersAndUpdatesResults() { var config = new SubscriptionRelayConfig(); subscriptionCache.Setup(sc => sc.GetAll(It.IsAny <string>())) .Returns(new List <SubscriptionRelayConfig> { config }); var result = new SubscriptionDeliveryResult(); var whe = new WebhookEvent { EventName = "aneventname" }; serviceClient.Setup(sc => sc.Relay(config, whe)) .Returns(result); sink.Write(whe); subscriptionService.Verify(ss => ss.UpdateResults(It.Is <List <SubscriptionDeliveryResult> >(results => results.Count == 1 && results[0] == result))); }
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()); } }
public SubscriptionDeliveryResult Relay(SubscriptionRelayConfig subscription, WebhookEvent webhookEvent) { Guard.AgainstNull(() => subscription, subscription); Guard.AgainstNull(() => webhookEvent, webhookEvent); var serviceClient = CreateServiceClient(subscription, webhookEvent.EventName, Timeout); var attempts = 0; while (attempts <= Retries) { attempts++; try { using (var response = serviceClient.Post(subscription.Config.Url, webhookEvent.Data)) { return(CreateDeliveryResult(subscription.SubscriptionId, response.StatusCode, response.StatusDescription)); } } catch (WebServiceException ex) { if (HasNoMoreRetries(attempts) || ex.IsAny400()) { logger.Warn(Resources.EventServiceClient_FailedDelivery.Fmt(subscription.Config.Url, attempts), ex); return(CreateDeliveryResult(subscription.SubscriptionId, (HttpStatusCode)ex.StatusCode, ex.StatusDescription)); } } catch (Exception ex) { // Timeout (WebException) or other Exception if (HasNoMoreRetries(attempts)) { var message = Resources.EventServiceClient_FailedDelivery.Fmt(subscription.Config.Url, attempts); logger.Warn(message, ex); return(CreateDeliveryResult(subscription.SubscriptionId, HttpStatusCode.ServiceUnavailable, message)); } } } return(null); }
public void WebhookEventGetAllTest() { var webhookEventList = WebhookEvent.List(TestingUtil.GetApiContext()); Assert.NotNull(webhookEventList); }
public Task <Guid> InsertAndGetIdAsync(WebhookEvent webhookEvent) { _events.Add(webhookEvent); return(Task.FromResult(webhookEvent.Id)); }
/// <summary> /// Phương thức gửi thông báo webhook sang web-client thông qua webhookUri /// </summary> /// <param name="webhookEvent">Dữ liệu Event thay đổi cẩn gửi</param> /// <param name="numError">Số lần gửi lỗi của Event này. Bằng 0 nếu gửi lần đầu</param> /// <returns>Trả về response khi gửi sang web-client</returns> /// Created by bvbao (13/8/2020) /// Modified by bvbao (2/10/2020) private async Task PublishAsync(WebhookEvent webhookEvent, int numError) { bool isSucceed = false; HttpStatusCode?responseStatusCode = null; string responseContent = Resources.webhookSendFail; try { //Gửi request đến web-client và đợi response để xử lý var response = await new SendHttpRequest().SendHttpReq(webhookEvent); isSucceed = response.isSucceed; responseStatusCode = response.statusCode; responseContent = response.content; } catch (TaskCanceledException)//since we run it background and never send cancellation token TaskCanceledException means request timeout { responseStatusCode = HttpStatusCode.RequestTimeout; responseContent = Resources.RequestTimeout; } catch (HttpRequestException e)//something wrong happened on request. we can show them to users. { responseContent = e.Message; } catch (Exception e)// an internal error occurred. do not show it to users. just log it. { responseContent = e.ToString(); } finally { if (!isSucceed) //Gửi không thành công thì lưu trữ và Queue eror để xử lý gửi lại sau { var maxSendError = int.Parse(_configuration["webhook:maxSendError"]); //Nếu gửi lỗi quá nhiều thì đẩy vào database để xử lý gửi sau bằng tay if (numError >= maxSendError) { //Nếu đẩy vào database lỗi thì lại đưa event vào Queue, nếu thành công thì thôi if (SaveEventErrorToDB(webhookEvent) == null) { var queueName = _configuration["rabbitmq:queueError"]; //Khởi tạo WebhookSendAttempt từ dữ liệu địa chỉ thay đổi var attempt = new WebhookSendAttempt() { webhookEvent = webhookEvent, ResponseStatusCode = responseStatusCode, Response = responseContent, NumberSendError = numError + 1 }; //Kết nối đến RabbitMQ using (var channel = _connection.CreateModel()) { channel.QueueDeclare(queueName, true, false, false, null); //Gửi WebhookSendAttempt lên Queue lỗi trên RabbitMQ var body = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(attempt)); channel.BasicPublish("", queueName, null, body); } } } else { var queueName = _configuration["rabbitmq:queueError"]; //Khởi tạo WebhookSendAttempt từ dữ liệu địa chỉ thay đổi var attempt = new WebhookSendAttempt() { webhookEvent = webhookEvent, ResponseStatusCode = responseStatusCode, Response = responseContent, NumberSendError = numError + 1 }; //Kết nối đến RabbitMQ using (var channel = _connection.CreateModel()) { channel.QueueDeclare(queueName, true, false, false, null); //Gửi WebhookSendAttempt lên Queue lỗi trên RabbitMQ var body = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(attempt)); channel.BasicPublish("", queueName, null, body); } } } } }
public ActionResult Webhook() { // The APIContext object can contain an optional override for the trusted certificate. var apiContext = PayPalConfiguration.GetAPIContext(); // Get the received request's headers var requestheaders = HttpContext.Request.Headers; // Get the received request's body var requestBody = string.Empty; using (var reader = new System.IO.StreamReader(HttpContext.Request.InputStream)) { requestBody = reader.ReadToEnd(); } //get event data from the request body dynamic jsonBody = JObject.Parse(requestBody); string webhookId = jsonBody.id; string paypalID = jsonBody.resource.id; decimal Totalamount = (decimal)jsonBody.resource.amount.total; DateTime paypalEventDate = (DateTime)jsonBody.create_time; DateTime paypalTransDate = (DateTime)jsonBody.resource.create_time; var ev = WebhookEvent.Get(apiContext, webhookId); // We have all the information the SDK needs, so perform the validation. // Note: at least on Sandbox environment this returns false. // var isValid = WebhookEvent.ValidateReceivedEvent(apiContext, ToNameValueCollection(requestheaders), requestBody, webhookId); //add record on the Notification table //Note: remove if events are successful. Notification table is used for sms notifications. DB.addTestNotification(1, "1"); //get jobid from CUSTOM object field //int jobId = (int)jsonBody.resource.custom ; // bookingid , //PPtrans.AddPaypalNotif("1", 1, paypalEventDate, paypalTransDate, ev.event_type, Totalamount); //get job id from invoice number //PPtrans.AddPaypalNotif(paypalID, jobId, paypalEventDate, paypalTransDate, ev.event_type, Totalamount); //jobId = (int)jsonBody.resource.invoice_number; // DB.addTestNotification(jobId, paypalID); //get job description JobMain jobOrder = db.JobMains.Find(1); string clientName = jobOrder.Description; EMailHandler mail = new EMailHandler(); string siteRedirect = "https://realwheelsdavao.com/reservation/"; /* Handle transaction request from paypal webhook events * switch (ev.event_type) * { * case "PAYMENT.CAPTURE.COMPLETED": * case "PAYMENT.SALE.COMPLETED": // Handle payment completed * //record payment * AddPaymentRecord(jobId, Totalamount); * * //send mail * mail.SendMail(jobId, "*****@*****.**", "PAYMENT-SUCCESS", clientName, siteRedirect); * //mail.SendMail(jobId, "*****@*****.**", "PAYMENT-SUCCESS", clientName, siteRedirect); * //mail.SendMail(jobId, "*****@*****.**", "PAYMENT-SUCCESS", clientName, siteRedirect); * * //add to log * PPtrans.AddPaypalNotif(paypalID, jobId, paypalEventDate, paypalTransDate, ev.event_type, Totalamount); * break; * case "PAYMENT.SALE.DENIED": * case "PAYMENT.CAPTURE.DENIED": // Handle payment denied * * //send mail * mail.SendMail(jobId, "*****@*****.**", "PAYMENT-DENIED", clientName, siteRedirect); * //mail.SendMail(jobId, "*****@*****.**", "PAYMENT-DENIED", clientName, siteRedirect); * //mail.SendMail(jobId, "*****@*****.**", "PAYMENT-DENIED", clientName, siteRedirect); * * //add to log * PPtrans.AddPaypalNotif(paypalID, jobId, paypalEventDate, paypalTransDate, ev.event_type, Totalamount); * * break; * // Handle other webhooks * default: // Handle payment denied * //send mail * mail.SendMail(jobId, "*****@*****.**", "PAYMENT-PENDING", clientName, siteRedirect); * //mail.SendMail2(jobId, "*****@*****.**", "PAYMENT-PENDING", clientName, siteRedirect, ev.event_type); * //mail.SendMail(jobId, "*****@*****.**", "PAYMENT-PENDING", clientName, siteRedirect); * //mail.SendMail(jobId, "*****@*****.**", "PAYMENT-PENDING", clientName, siteRedirect); * * //add to log * PPtrans.AddPaypalNotif(paypalID, jobId, paypalEventDate, paypalTransDate, ev.event_type, Totalamount); * * break; * } */ //AddPaymentRecord(jobId, Totalamount); //add to log //PPtrans.AddPaypalNotif(paypalID, jobId, paypalEventDate, paypalTransDate, ev.event_type, Totalamount); //send mail //mail.SendMail(1, "*****@*****.**", "PAYMENT-PENDING", clientName, siteRedirect); //mail.SendMail2(jobId, "*****@*****.**", "PAYMENT-PENDING", clientName, siteRedirect, ev.event_type); //mail.SendMail(jobId, "*****@*****.**", "PAYMENT-PENDING", clientName, siteRedirect); //mail.SendMail(jobId, "*****@*****.**", "PAYMENT-PENDING", clientName, siteRedirect); return(new HttpStatusCodeResult(200)); }
/// <summary> /// Gửi request tới bên web-client theo Uri /// </summary> /// <param name="request"></param> /// <returns></returns> /// Created by bvbao (13/8/2020) public async Task <(bool isSucceed, HttpStatusCode statusCode, string content)> SendHttpReq(WebhookEvent webhookEvent) { var request = new HttpRequestMessage(HttpMethod.Post, webhookEvent.WebhookUri);//create webhook request using parameters request.Content = new StringContent(JsonConvert.SerializeObject(webhookEvent.webhookPayload), Encoding.UTF8, "application/json"); using (var client = new HttpClient { Timeout = TimeSpan.FromSeconds(60)//make sure you define timeout }) { var response = await client.SendAsync(request); var isSucceed = response.IsSuccessStatusCode; var statusCode = response.StatusCode; var content = await response.Content.ReadAsStringAsync(); return(isSucceed, statusCode, content); } }
public ActionResult Webhook() { // The APIContext object can contain an optional override for the trusted certificate. var apiContext = PayPalConfiguration.GetAPIContext(); // Get the received request's headers var requestheaders = HttpContext.Request.Headers; // Get the received request's body var requestBody = string.Empty; using (var reader = new System.IO.StreamReader(HttpContext.Request.InputStream)) { requestBody = reader.ReadToEnd(); } dynamic jsonBody = JObject.Parse(requestBody); string webhookId = jsonBody.id; string paypalID = jsonBody.resource.id; decimal Totalamount = (decimal)jsonBody.resource.amount.total; int jobId = (int)jsonBody.resource.invoice_number; // bookingid var ev = WebhookEvent.Get(apiContext, webhookId); // We have all the information the SDK needs, so perform the validation. // Note: at least on Sandbox environment this returns false. // var isValid = WebhookEvent.ValidateReceivedEvent(apiContext, ToNameValueCollection(requestheaders), requestBody, webhookId); // DB.addTestNotification(jobId, paypalID); //get job description JobMain jobOrder = db.JobMains.Find(jobId); string clientName = jobOrder.Description; EMailHandler mail = new EMailHandler(); switch (ev.event_type) { case "PAYMENT.CAPTURE.COMPLETED": case "PAYMENT.SALE.COMPLETED": // Handle payment completed //record payment AddPaymentRecord(jobId, Totalamount); //send mail mail.SendMail(jobId, "*****@*****.**", "PAYMENT-SUCCESS", clientName); mail.SendMail(jobId, "*****@*****.**", "PAYMENT-SUCCESS", clientName); mail.SendMail(jobId, "*****@*****.**", "PAYMENT-SUCCESS", clientName); //add to log DB.addTestNotification(jobId, paypalID); break; case "PAYMENT.SALE.DENIED": case "PAYMENT.CAPTURE.DENIED": // Handle payment denied //send mail mail.SendMail(jobId, "*****@*****.**", "PAYMENT-DENIED", clientName); mail.SendMail(jobId, "*****@*****.**", "PAYMENT-DENIED", clientName); mail.SendMail(jobId, "*****@*****.**", "PAYMENT-DENIED", clientName); //add to log DB.addTestNotification(jobId, paypalID); break; // Handle other webhooks default: // Handle payment denied //send mail mail.SendMail(jobId, "*****@*****.**", "PAYMENT-PENDING", clientName); mail.SendMail(jobId, "*****@*****.**", "PAYMENT-PENDING", clientName); mail.SendMail(jobId, "*****@*****.**", "PAYMENT-PENDING", clientName); //add to log DB.addTestNotification(jobId, paypalID); break; } return(new HttpStatusCodeResult(200)); }
public async Task AddEvent(WebhookEvent e) { await _eventQueue.SendAsync(new WebhookEventWrapper(e)); }
public WebhookEventWrapper(WebhookEvent e) { WebhookEvent = e; }
/// <summary> /// Create room webhook /// </summary> /// <param name="room">The room.</param> /// <param name="url">The URL.</param> /// <param name="webhookEvent">The webhook event.</param> /// <param name="name">The name.</param> /// <param name="pattern">The pattern.</param> /// <returns>Task<IResponse<System.Boolean>>.</returns> public async Task<IResponse<bool>> CreateWebhookAsync(string room, Uri url, WebhookEvent webhookEvent, string name = null, string pattern = null) { var hook = new CreateWebhook { Url = url.AbsoluteUri, Event = webhookEvent, Name = string.Format("HipChatDotNet_{0}", name ?? "Default") }; if (pattern != null && (webhookEvent == WebhookEvent.RoomMessage || webhookEvent == WebhookEvent.RoomNotification)) hook.Pattern = pattern; return await CreateWebhookAsync(room, hook); }
public async Task <IActionResult> Post(WebhookEvent request) { await _app.RunAsync(request.events); return(Ok()); }
/// <summary> /// Create room webhook /// </summary> /// <param name="room">The room.</param> /// <param name="url">The URL.</param> /// <param name="webhookEvent">The webhook event.</param> /// <param name="name">The name.</param> /// <param name="pattern">The pattern.</param> /// <returns>Task<IResponse<System.Boolean>>.</returns> public async Task <IResponse <bool> > CreateWebhookAsync(string room, Uri url, WebhookEvent webhookEvent, string name = null, string pattern = null) { var hook = new CreateWebhook { Url = url.AbsoluteUri, Event = webhookEvent, Name = string.Format("HipChatDotNet_{0}", name ?? "Default") }; if (pattern != null && (webhookEvent == WebhookEvent.RoomMessage || webhookEvent == WebhookEvent.RoomNotification)) { hook.Pattern = pattern; } return(await CreateWebhookAsync(room, hook)); }
public void Write(WebhookEvent webhookEvent) { throw new NotImplementedException(); }
public Guid InsertAndGetId(WebhookEvent webhookEvent) { _events.Add(webhookEvent); return(webhookEvent.Id); }
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 async Task AddEvent(WebhookEvent evt) { await _eventQueue.SendAsync(evt); }