public async Task NotifyHttp(string invoiceData, CancellationToken cancellationToken)
        {
            var  job             = NBitcoin.JsonConverters.Serializer.ToObject <ScheduledJob>(invoiceData);
            bool reschedule      = false;
            var  aggregatorEvent = new InvoiceIPNEvent(job.Notification.Data.Id, job.Notification.Event.Code, job.Notification.Event.Name);

            try
            {
                HttpResponseMessage response = await SendNotification(job.Notification, cancellationToken);

                reschedule            = !response.IsSuccessStatusCode;
                aggregatorEvent.Error = reschedule ? $"Unexpected return code: {(int)response.StatusCode}" : null;
                _EventAggregator.Publish <InvoiceIPNEvent>(aggregatorEvent);
            }
            catch (OperationCanceledException) when(cancellationToken.IsCancellationRequested)
            {
                // When the JobClient will be persistent, this will reschedule the job for after reboot
                invoiceData = NBitcoin.JsonConverters.Serializer.ToString(job);
                _JobClient.Schedule((cancellation) => NotifyHttp(invoiceData, cancellation), TimeSpan.FromMinutes(10.0));
                return;
            }
            catch (OperationCanceledException)
            {
                aggregatorEvent.Error = "Timeout";
                _EventAggregator.Publish <InvoiceIPNEvent>(aggregatorEvent);
                reschedule = true;
            }
            catch (Exception ex)
            {
                reschedule = true;

                List <string> messages = new List <string>();
                while (ex != null)
                {
                    messages.Add(ex.Message);
                    ex = ex.InnerException;
                }
                string message = String.Join(',', messages.ToArray());

                aggregatorEvent.Error = $"Unexpected error: {message}";
                _EventAggregator.Publish <InvoiceIPNEvent>(aggregatorEvent);
            }

            job.TryCount++;

            if (job.TryCount < MaxTry && reschedule)
            {
                invoiceData = NBitcoin.JsonConverters.Serializer.ToString(job);
                _JobClient.Schedule((cancellation) => NotifyHttp(invoiceData, cancellation), TimeSpan.FromMinutes(10.0));
            }
        }
        public async Task NotifyHttp(ScheduledJob job, CancellationToken cancellationToken)
        {
            bool reschedule      = false;
            var  aggregatorEvent = new InvoiceIPNEvent(job.Notification.Data.Id, job.Notification.Event.Code, job.Notification.Event.Name, job.Notification.ExtendedNotification);

            try
            {
                using HttpResponseMessage response = await SendNotification(job.Notification, cancellationToken);

                reschedule            = !response.IsSuccessStatusCode;
                aggregatorEvent.Error = reschedule ? $"Unexpected return code: {(int)response.StatusCode}" : null;
                _EventAggregator.Publish <InvoiceIPNEvent>(aggregatorEvent);
            }
            catch (OperationCanceledException) when(cancellationToken.IsCancellationRequested)
            {
                _JobClient.Schedule((cancellation) => NotifyHttp(job, cancellation), TimeSpan.FromMinutes(10.0));
                return;
            }
            catch (OperationCanceledException)
            {
                aggregatorEvent.Error = "Timeout";
                _EventAggregator.Publish <InvoiceIPNEvent>(aggregatorEvent);
                reschedule = true;
            }
            catch (Exception ex)
            {
                reschedule = true;

                List <string> messages = new List <string>();
                while (ex != null)
                {
                    messages.Add(ex.Message);
                    ex = ex.InnerException;
                }
                string message = String.Join(',', messages.ToArray());

                aggregatorEvent.Error = $"Unexpected error: {message}";
                _EventAggregator.Publish <InvoiceIPNEvent>(aggregatorEvent);
            }

            job.TryCount++;

            if (job.TryCount < MaxTry && reschedule)
            {
                _JobClient.Schedule((cancellation) => NotifyHttp(job, cancellation), TimeSpan.FromMinutes(10.0));
            }
        }