diff --git a/src/Billing/Controllers/BitPayController.cs b/src/Billing/Controllers/BitPayController.cs index 85ae83b02a..0bc156237d 100644 --- a/src/Billing/Controllers/BitPayController.cs +++ b/src/Billing/Controllers/BitPayController.cs @@ -117,11 +117,13 @@ namespace Bit.Billing.Controllers if(isAccountCredit) { + string billingEmail = null; if(tx.OrganizationId.HasValue) { var org = await _organizationRepository.GetByIdAsync(tx.OrganizationId.Value); if(org != null) { + billingEmail = org.BillingEmailAddress(); if(await _paymentService.CreditAccountAsync(org, tx.Amount)) { await _organizationRepository.ReplaceAsync(org); @@ -133,6 +135,7 @@ namespace Bit.Billing.Controllers var user = await _userRepository.GetByIdAsync(tx.UserId.Value); if(user != null) { + billingEmail = user.BillingEmailAddress(); if(await _paymentService.CreditAccountAsync(user, tx.Amount)) { await _userRepository.ReplaceAsync(user); @@ -140,7 +143,10 @@ namespace Bit.Billing.Controllers } } - // TODO: Send email about credit added? + if(!string.IsNullOrWhiteSpace(billingEmail)) + { + await _mailService.SendAddedCreditAsync(billingEmail, tx.Amount); + } } } // Catch foreign key violations because user/org could have been deleted. diff --git a/src/Billing/Controllers/PayPalController.cs b/src/Billing/Controllers/PayPalController.cs index 2a85c31617..369e104433 100644 --- a/src/Billing/Controllers/PayPalController.cs +++ b/src/Billing/Controllers/PayPalController.cs @@ -258,11 +258,13 @@ namespace Bit.Billing.Controllers if(ipnTransaction.IsAccountCredit()) { + string billingEmail = null; if(tx.OrganizationId.HasValue) { var org = await _organizationRepository.GetByIdAsync(tx.OrganizationId.Value); if(org != null) { + billingEmail = org.BillingEmailAddress(); if(await _paymentService.CreditAccountAsync(org, tx.Amount)) { await _organizationRepository.ReplaceAsync(org); @@ -274,6 +276,7 @@ namespace Bit.Billing.Controllers var user = await _userRepository.GetByIdAsync(tx.UserId.Value); if(user != null) { + billingEmail = user.BillingEmailAddress(); if(await _paymentService.CreditAccountAsync(user, tx.Amount)) { await _userRepository.ReplaceAsync(user); @@ -281,7 +284,10 @@ namespace Bit.Billing.Controllers } } - // TODO: Send email about credit added? + if(!string.IsNullOrWhiteSpace(billingEmail)) + { + await _mailService.SendAddedCreditAsync(billingEmail, tx.Amount); + } } } // Catch foreign key violations because user/org could have been deleted. diff --git a/src/Core/MailTemplates/Handlebars/AddedCredit.html.hbs b/src/Core/MailTemplates/Handlebars/AddedCredit.html.hbs new file mode 100644 index 0000000000..d77c61cbb0 --- /dev/null +++ b/src/Core/MailTemplates/Handlebars/AddedCredit.html.hbs @@ -0,0 +1,14 @@ +{{#>FullHtmlLayout}} + + + + + + + +
+ A {{usd Amount}} payment has been processed and credited to your account. This credit is now available to make purchases. +
+ You can view your account's available credit by logging into the web vault at {{{link WebVaultUrl}}}. Once logged in, navigate to the Billing page for your account. +
+{{/FullHtmlLayout}} diff --git a/src/Core/MailTemplates/Handlebars/AddedCredit.text.hbs b/src/Core/MailTemplates/Handlebars/AddedCredit.text.hbs new file mode 100644 index 0000000000..38a605b968 --- /dev/null +++ b/src/Core/MailTemplates/Handlebars/AddedCredit.text.hbs @@ -0,0 +1,5 @@ +{{#>BasicTextLayout}} +A {{usd Amount}} payment has been processed and credited to your account. This credit is now available to make purchases. + +You can view your account's available credit by logging into the web vault at {{{WebVaultUrl}}}. Once logged in, navigate to the Billing page for your account. +{{/BasicTextLayout}} \ No newline at end of file diff --git a/src/Core/Models/Mail/AddedCreditViewModel.cs b/src/Core/Models/Mail/AddedCreditViewModel.cs new file mode 100644 index 0000000000..fe3d995019 --- /dev/null +++ b/src/Core/Models/Mail/AddedCreditViewModel.cs @@ -0,0 +1,7 @@ +namespace Bit.Core.Models.Mail +{ + public class AddedCreditViewModel : BaseMailModel + { + public decimal Amount { get; set; } + } +} diff --git a/src/Core/Services/IMailService.cs b/src/Core/Services/IMailService.cs index 639cb30629..42196a0c72 100644 --- a/src/Core/Services/IMailService.cs +++ b/src/Core/Services/IMailService.cs @@ -23,6 +23,7 @@ namespace Bit.Core.Services Task SendInvoiceUpcomingAsync(string email, decimal amount, DateTime dueDate, List items, bool mentionInvoices); Task SendPaymentFailedAsync(string email, decimal amount, bool mentionInvoices); + Task SendAddedCreditAsync(string email, decimal amount); Task SendNewDeviceLoggedInEmail(string email, string deviceType, DateTime timestamp, string ip); } } diff --git a/src/Core/Services/Implementations/HandlebarsMailService.cs b/src/Core/Services/Implementations/HandlebarsMailService.cs index 52d5a3b275..d9b249d6cc 100644 --- a/src/Core/Services/Implementations/HandlebarsMailService.cs +++ b/src/Core/Services/Implementations/HandlebarsMailService.cs @@ -251,6 +251,20 @@ namespace Bit.Core.Services await _mailDeliveryService.SendEmailAsync(message); } + public async Task SendAddedCreditAsync(string email, decimal amount) + { + var message = CreateDefaultMessage("Account Credit Payment Processed", email); + var model = new AddedCreditViewModel + { + WebVaultUrl = _globalSettings.BaseServiceUri.VaultWithHash, + SiteName = _globalSettings.SiteName, + Amount = amount + }; + await AddMessageContentAsync(message, "AddedCredit", model); + message.MetaData.Add("SendGridCategories", new List { "AddedCredit" }); + await _mailDeliveryService.SendEmailAsync(message); + } + public async Task SendNewDeviceLoggedInEmail(string email, string deviceType, DateTime timestamp, string ip) { var message = CreateDefaultMessage($"New Device Logged In From {deviceType}", email); diff --git a/src/Core/Services/NoopImplementations/NoopMailService.cs b/src/Core/Services/NoopImplementations/NoopMailService.cs index 453adf9b7f..b20379c1de 100644 --- a/src/Core/Services/NoopImplementations/NoopMailService.cs +++ b/src/Core/Services/NoopImplementations/NoopMailService.cs @@ -78,6 +78,11 @@ namespace Bit.Core.Services return Task.FromResult(0); } + public Task SendAddedCreditAsync(string email, decimal amount) + { + return Task.FromResult(0); + } + public Task SendNewDeviceLoggedInEmail(string email, string deviceType, DateTime timestamp, string ip) { return Task.FromResult(0);