diff --git a/BTCPayServer/HostedServices/Webhooks/IWebhookProvider.cs b/BTCPayServer/HostedServices/Webhooks/IWebhookProvider.cs index d4661687b..b0592d52a 100644 --- a/BTCPayServer/HostedServices/Webhooks/IWebhookProvider.cs +++ b/BTCPayServer/HostedServices/Webhooks/IWebhookProvider.cs @@ -6,6 +6,8 @@ namespace BTCPayServer.HostedServices.Webhooks; public interface IWebhookProvider { + public bool SupportsCustomerEmail { get; } + public Dictionary GetSupportedWebhookTypes(); public WebhookEvent CreateTestEvent(string type, params object[] args); diff --git a/BTCPayServer/HostedServices/Webhooks/InvoiceWebhookProvider.cs b/BTCPayServer/HostedServices/Webhooks/InvoiceWebhookProvider.cs index af7e8f617..5a920fc27 100644 --- a/BTCPayServer/HostedServices/Webhooks/InvoiceWebhookProvider.cs +++ b/BTCPayServer/HostedServices/Webhooks/InvoiceWebhookProvider.cs @@ -14,6 +14,8 @@ public class InvoiceWebhookProvider( ILogger logger) : WebhookProvider(eventAggregator, logger, webhookSender) { + public override bool SupportsCustomerEmail { get; } = true; + public override Dictionary GetSupportedWebhookTypes() { return new Dictionary diff --git a/BTCPayServer/HostedServices/Webhooks/PaymentRequestWebhookProvider.cs b/BTCPayServer/HostedServices/Webhooks/PaymentRequestWebhookProvider.cs index 02b46b501..d80c9f265 100644 --- a/BTCPayServer/HostedServices/Webhooks/PaymentRequestWebhookProvider.cs +++ b/BTCPayServer/HostedServices/Webhooks/PaymentRequestWebhookProvider.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using BTCPayServer.Client.Models; using BTCPayServer.Data; @@ -10,6 +10,8 @@ namespace BTCPayServer.HostedServices.Webhooks; public class PaymentRequestWebhookProvider(EventAggregator eventAggregator, ILogger logger, WebhookSender webhookSender) : WebhookProvider(eventAggregator, logger, webhookSender) { + public override bool SupportsCustomerEmail { get; } = true; + public override Dictionary GetSupportedWebhookTypes() { return new Dictionary diff --git a/BTCPayServer/HostedServices/Webhooks/PayoutWebhookProvider.cs b/BTCPayServer/HostedServices/Webhooks/PayoutWebhookProvider.cs index daed7e0a4..42b71b80a 100644 --- a/BTCPayServer/HostedServices/Webhooks/PayoutWebhookProvider.cs +++ b/BTCPayServer/HostedServices/Webhooks/PayoutWebhookProvider.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using BTCPayServer.Client.Models; using BTCPayServer.Data; @@ -36,6 +36,8 @@ public class PayoutWebhookProvider( return new PayoutWebhookDeliveryRequest(payoutEvent, webhook?.Id, webhookEvent, delivery, webhookBlob, btcPayNetworkJsonSerializerSettings); } + public override bool SupportsCustomerEmail { get; } = false; + public override Dictionary GetSupportedWebhookTypes() { return new Dictionary diff --git a/BTCPayServer/HostedServices/Webhooks/PendingTransactionWebhookProvider.cs b/BTCPayServer/HostedServices/Webhooks/PendingTransactionWebhookProvider.cs index 172d95fa2..4a4a25106 100644 --- a/BTCPayServer/HostedServices/Webhooks/PendingTransactionWebhookProvider.cs +++ b/BTCPayServer/HostedServices/Webhooks/PendingTransactionWebhookProvider.cs @@ -18,6 +18,8 @@ public class PendingTransactionWebhookProvider( public const string PendingTransactionBroadcast = nameof(PendingTransactionBroadcast); public const string PendingTransactionCancelled = nameof(PendingTransactionCancelled); + public override bool SupportsCustomerEmail { get; } = false; + public override Dictionary GetSupportedWebhookTypes() { return new Dictionary diff --git a/BTCPayServer/HostedServices/Webhooks/WebhookProvider.cs b/BTCPayServer/HostedServices/Webhooks/WebhookProvider.cs index 1a923bbbe..79d89b2cc 100644 --- a/BTCPayServer/HostedServices/Webhooks/WebhookProvider.cs +++ b/BTCPayServer/HostedServices/Webhooks/WebhookProvider.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; using BTCPayServer.Client.Models; @@ -10,6 +10,8 @@ namespace BTCPayServer.HostedServices.Webhooks; public abstract class WebhookProvider(EventAggregator eventAggregator, ILogger logger, WebhookSender webhookSender) : EventHostedServiceBase(eventAggregator, logger), IWebhookProvider { + public abstract bool SupportsCustomerEmail { get; } + public abstract Dictionary GetSupportedWebhookTypes(); public abstract WebhookEvent CreateTestEvent(string type, params object[] args); diff --git a/BTCPayServer/HostedServices/Webhooks/WebhookSender.cs b/BTCPayServer/HostedServices/Webhooks/WebhookSender.cs index 229f28a2c..1e8e824e1 100644 --- a/BTCPayServer/HostedServices/Webhooks/WebhookSender.cs +++ b/BTCPayServer/HostedServices/Webhooks/WebhookSender.cs @@ -268,6 +268,14 @@ public class WebhookSender( .SelectMany(provider => provider.GetSupportedWebhookTypes()).ToDictionary(pair => pair.Key, pair => pair.Value); } + public Dictionary GetWebhookTypesSupportedByCustomerEmail() + { + return serviceProvider.GetServices() + .SelectMany(provider => provider.GetSupportedWebhookTypes() + .Select(pair => new { pair.Key, Value = provider.SupportsCustomerEmail })) + .ToDictionary(x => x.Key, x => x.Value); + } + public class WebhookDeliveryRequest( string webhookId, WebhookEvent webhookEvent, diff --git a/BTCPayServer/Views/UIStores/StoreEmailRulesManage.cshtml b/BTCPayServer/Views/UIStores/StoreEmailRulesManage.cshtml index 2a04c5aa5..38da5879a 100644 --- a/BTCPayServer/Views/UIStores/StoreEmailRulesManage.cshtml +++ b/BTCPayServer/Views/UIStores/StoreEmailRulesManage.cshtml @@ -33,8 +33,8 @@

@ViewData["Title"]

- - Cancel + + Cancel
@@ -55,8 +55,8 @@
Who to send the email to. For multiple emails, separate with a comma.
-
- +
+
@@ -229,11 +229,27 @@ } } + function toggleCustomerEmailVisibility() { + const customerEmailContainer = document.querySelector('.customer-email-container'); + const customerEmailCheckbox = document.querySelector('.customer-email-checkbox'); + const selectedTrigger = triggerSelect.value; + const supportsCustomerEmailDict = @Safe.Json(WebhookSender.GetWebhookTypesSupportedByCustomerEmail()); + + if (supportsCustomerEmailDict[selectedTrigger]) { + customerEmailContainer.style.display = 'block'; + } else { + customerEmailContainer.style.display = 'none'; + customerEmailCheckbox.checked = false; + } + } + triggerSelect.addEventListener('change', applyTemplate); + triggerSelect.addEventListener('change', toggleCustomerEmailVisibility); // Apply template on page load if a trigger is selected if (triggerSelect.value) { applyTemplate(); + toggleCustomerEmailVisibility(); } });