/// <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");
 }
Exemplo n.º 2
0
        /// <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();
                    }
                }
            }
        }