/// <summary> /// A sample notifications callback from the NotificationHandler /// Will be called each time a new notification is received at the local webhook /// </summary> /// <param name="notification">The notification object that was received</param> private static void NotificationReceived(OrderNotification notification) { Console.WriteLine("\n\nNew " + notification.Status + " Notification Received for order with ID:" + notification.Id + " With description: " + notification.Description + (notification.Warnings == null ? "" : ("Warnings:\n" + string.Join("\n",notification.Warnings))) + "\n\n"); }
/// <summary> /// Runs the notification server /// This method is blocking and will not return until StopReceiveNotifications is called /// </summary> /// <exception cref="NotifierServerFailedToStartException">Thrown when the listener was unable to start due to server network configuration errors</exception> /// <exception cref="NotifierAlreadyRunningException">Thrown when server is already running</exception> public void ReceiveNotifications() { if (!_isStopped) throw new NotifierAlreadyRunningException("Notification handler already running"); if (!_listener.IsListening) { try { _listener.Start(); } catch (Exception e) { string errorMsg = string.Format( "Unable to start the HTTP webhook listener on: {0}. Check firewall configuration and make sure the app is running under admin privleges", _localListeningEndpoint); LoggingServices.Fatal(errorMsg, e); throw new NotifierServerFailedToStartException(errorMsg, e); } } _isStopped = false; while (!_isStopped) { try { //blocking call var context = _listener.GetContext(); // reaches here when a connection was made var request = context.Request; if (!request.HasEntityBody) { LoggingServices.Error("Received HTTP notification with no body - shouldn't happen"); continue; } string responseString; bool acionSucceeded = false; try { var notificationData = HttpUtils.ParsePostRequestToObject<OrderWrapper<Notification>>(request,_authToken); OrderNotification n = new OrderNotification(notificationData); responseString = string.Format( "<HTML><BODY>Merchant Received Notification For Order {0} with status {1} and description {2}</BODY></HTML>", n.Id, n.Status, n.Description); // running callback to call merchant code on the notification Task.Factory.StartNew(() => _notificationReceivedCallback(n)); acionSucceeded = true; } catch (RiskifiedAuthenticationException uae) { LoggingServices.Error("Notification message authentication failed",uae); responseString = "<HTML><BODY>Merchant couldn't authenticate notification message</BODY></HTML>"; } catch(Exception e) { LoggingServices.Error("Unable to parse notification message. Some or all of the post params are missing or invalid",e); responseString = "<HTML><BODY>Merchant couldn't parse notification message</BODY></HTML>"; } // Obtain a response object to write back a ack response to the riskified server HttpListenerResponse response = context.Response; // Construct a simple response. HttpUtils.BuildAndSendResponse(response, _authToken,_shopDomain, responseString,acionSucceeded); } catch (Exception e) { LoggingServices.Error("An error occured will receiving notification. Specific request was skipped", e); // trying to restart listening - maybe connection was cut shortly if (!_listener.IsListening) { RestartHttpListener(); } } } }