Skip to content

Commit 53815cd

Browse files
author
mariannk
committed
Merge branch 'develop' of https://github.com/nopSolutions/nopCommerce into develop
2 parents ea8cce2 + 6bc82bb commit 53815cd

File tree

30 files changed

+391
-30
lines changed

30 files changed

+391
-30
lines changed

src/Libraries/Nop.Core/Domain/Messages/MessageTemplateSystemNames.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,16 @@ public static partial class MessageTemplateSystemNames
106106
/// </summary>
107107
public const string RecurringPaymentCancelledStoreOwnerNotification = "RecurringPaymentCancelled.StoreOwnerNotification";
108108

109+
/// <summary>
110+
/// Represents system name of notification customer about cancelled recurring order
111+
/// </summary>
112+
public const string RecurringPaymentCancelledCustomerNotification = "RecurringPaymentCancelled.CustomerNotification";
113+
114+
/// <summary>
115+
/// Represents system name of notification customer about failed payment for the recurring payments
116+
/// </summary>
117+
public const string RecurringPaymentFailedCustomerNotification = "RecurringPaymentFailed.CustomerNotification";
118+
109119
#endregion
110120

111121
#region Newsletter

src/Libraries/Nop.Core/Domain/Orders/RecurringPayment.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ public partial class RecurringPayment : BaseEntity
3737
/// </summary>
3838
public bool IsActive { get; set; }
3939

40+
/// <summary>
41+
/// Gets or sets a value indicating whether the last payment failed
42+
/// </summary>
43+
public bool LastPaymentFailed { get; set; }
44+
4045
/// <summary>
4146
/// Gets or sets a value indicating whether the entity has been deleted
4247
/// </summary>

src/Libraries/Nop.Core/Domain/Payments/PaymentSettings.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,10 @@ public PaymentSettings()
3434
/// Gets or sets a value indicating whether we should skip 'payment info' page for redirection payment methods
3535
/// </summary>
3636
public bool SkipPaymentInfoStepForRedirectionPaymentMethods { get; set; }
37+
38+
/// <summary>
39+
/// Gets or sets a value indicating whether to cancel the recurring payment after failed last payment
40+
/// </summary>
41+
public bool CancelRecurringPaymentsAfterFailedPayment { get; set; }
3742
}
3843
}

src/Libraries/Nop.Services/Installation/CodeFirstInstallationService.cs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5508,7 +5508,23 @@ protected virtual void InstallMessageTemplates()
55085508
{
55095509
Name = MessageTemplateSystemNames.RecurringPaymentCancelledStoreOwnerNotification,
55105510
Subject = "%Store.Name%. Recurring payment cancelled",
5511-
Body = string.Format("<p>{0}<a href=\"%Store.URL%\">%Store.Name%</a>{0}<br />{0}<br />{0}%Customer.FullName% (%Customer.Email%) has just cancelled a recurring payment ID=%RecurringPayment.ID%.{0}</p>{0}", Environment.NewLine),
5511+
Body = string.Format("<p>{0}<a href=\"%Store.URL%\">%Store.Name%</a>{0}<br />{0}<br />{0}%if (%RecurringPayment.CancelAfterFailedPayment%) The last payment for the recurring payment ID=%RecurringPayment.ID% failed, so it was cancelled. endif% %if (!%RecurringPayment.CancelAfterFailedPayment%) %Customer.FullName% (%Customer.Email%) has just cancelled a recurring payment ID=%RecurringPayment.ID%. endif%{0}</p>{0}", Environment.NewLine),
5512+
IsActive = true,
5513+
EmailAccountId = eaGeneral.Id,
5514+
},
5515+
new MessageTemplate
5516+
{
5517+
Name = MessageTemplateSystemNames.RecurringPaymentCancelledCustomerNotification,
5518+
Subject = "%Store.Name%. Recurring payment cancelled",
5519+
Body = string.Format("<p>{0}<a href=\"%Store.URL%\">%Store.Name%</a>{0}<br />{0}<br />{0}Hello %Customer.FullName%,{0}<br />{0}%if (%RecurringPayment.CancelAfterFailedPayment%) It appears your credit card didn't go through for this recurring payment (<a href=\"%Order.OrderURLForCustomer%\" target=\"_blank\">%Order.OrderURLForCustomer%</a>){0}<br />{0}So your subscription has been canceled. endif% %if (!%RecurringPayment.CancelAfterFailedPayment%) The recurring payment ID=%RecurringPayment.ID% was cancelled. endif%{0}</p>{0}", Environment.NewLine),
5520+
IsActive = true,
5521+
EmailAccountId = eaGeneral.Id,
5522+
},
5523+
new MessageTemplate
5524+
{
5525+
Name = MessageTemplateSystemNames.RecurringPaymentFailedCustomerNotification,
5526+
Subject = "%Store.Name%. Last recurring payment failed",
5527+
Body = string.Format("<p>{0}<a href=\"%Store.URL%\">%Store.Name%</a>{0}<br />{0}<br />{0}Hello %Customer.FullName%,{0}<br />{0}It appears your credit card didn't go through for this recurring payment (<a href=\"%Order.OrderURLForCustomer%\" target=\"_blank\">%Order.OrderURLForCustomer%</a>){0}<br /> %if (%RecurringPayment.RecurringPaymentType% == \"Manual\") {0}You can recharge balance and manually retry payment or cancel it on the order history page. endif% %if (%RecurringPayment.RecurringPaymentType% == \"Automatic\") {0}You can recharge balance and wait, we will try to make the payment again, or you can cancel it on the order history page. endif%{0}</p>{0}", Environment.NewLine),
55125528
IsActive = true,
55135529
EmailAccountId = eaGeneral.Id,
55145530
},
@@ -6195,7 +6211,8 @@ protected virtual void InstallSettings()
61956211
AllowRePostingPayments = true,
61966212
BypassPaymentMethodSelectionIfOnlyOne = true,
61976213
ShowPaymentMethodDescriptions = true,
6198-
SkipPaymentInfoStepForRedirectionPaymentMethods = false
6214+
SkipPaymentInfoStepForRedirectionPaymentMethods = false,
6215+
CancelRecurringPaymentsAfterFailedPayment = false
61996216
});
62006217

62016218
settingService.SaveSetting(new TaxSettings

src/Libraries/Nop.Services/Messages/IWorkflowMessageService.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,23 @@ int SendOrderCompletedCustomerNotification(Order order, int languageId,
183183
/// <param name="languageId">Message language identifier</param>
184184
/// <returns>Queued email identifier</returns>
185185
int SendRecurringPaymentCancelledStoreOwnerNotification(RecurringPayment recurringPayment, int languageId);
186-
186+
187+
/// <summary>
188+
/// Sends a "Recurring payment cancelled" notification to a customer
189+
/// </summary>
190+
/// <param name="recurringPayment">Recurring payment</param>
191+
/// <param name="languageId">Message language identifier</param>
192+
/// <returns>Queued email identifier</returns>
193+
int SendRecurringPaymentCancelledCustomerNotification(RecurringPayment recurringPayment, int languageId);
194+
195+
/// <summary>
196+
/// Sends a "Recurring payment failed" notification to a customer
197+
/// </summary>
198+
/// <param name="recurringPayment">Recurring payment</param>
199+
/// <param name="languageId">Message language identifier</param>
200+
/// <returns>Queued email identifier</returns>
201+
int SendRecurringPaymentFailedCustomerNotification(RecurringPayment recurringPayment, int languageId);
202+
187203
#endregion
188204

189205
#region Newsletter workflow

src/Libraries/Nop.Services/Messages/MessageTemplateExtensions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ public static IEnumerable<string> GetTokenGroups(this MessageTemplate messageTem
4747
return new[] { TokenGroupNames.StoreTokens, TokenGroupNames.OrderNoteTokens, TokenGroupNames.OrderTokens, TokenGroupNames.CustomerTokens };
4848

4949
case MessageTemplateSystemNames.RecurringPaymentCancelledStoreOwnerNotification:
50+
case MessageTemplateSystemNames.RecurringPaymentCancelledCustomerNotification:
51+
case MessageTemplateSystemNames.RecurringPaymentFailedCustomerNotification:
5052
return new[] { TokenGroupNames.StoreTokens, TokenGroupNames.OrderTokens, TokenGroupNames.CustomerTokens, TokenGroupNames.RecurringPaymentTokens };
5153

5254
case MessageTemplateSystemNames.NewsletterSubscriptionActivationMessage:

src/Libraries/Nop.Services/Messages/MessageTokenProvider.cs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
using Nop.Core.Domain.Messages;
1515
using Nop.Core.Domain.News;
1616
using Nop.Core.Domain.Orders;
17+
using Nop.Core.Domain.Payments;
1718
using Nop.Core.Domain.Shipping;
1819
using Nop.Core.Domain.Stores;
1920
using Nop.Core.Domain.Tax;
@@ -62,6 +63,7 @@ public partial class MessageTokenProvider : IMessageTokenProvider
6263
private readonly TaxSettings _taxSettings;
6364
private readonly CurrencySettings _currencySettings;
6465
private readonly ShippingSettings _shippingSettings;
66+
private readonly PaymentSettings _paymentSettings;
6567

6668
private readonly IEventPublisher _eventPublisher;
6769
private readonly StoreInformationSettings _storeInformationSettings;
@@ -89,6 +91,7 @@ public MessageTokenProvider(ILanguageService languageService,
8991
TaxSettings taxSettings,
9092
CurrencySettings currencySettings,
9193
ShippingSettings shippingSettings,
94+
PaymentSettings paymentSettings,
9295
IEventPublisher eventPublisher,
9396
StoreInformationSettings storeInformationSettings)
9497
{
@@ -112,6 +115,7 @@ public MessageTokenProvider(ILanguageService languageService,
112115
this._taxSettings = taxSettings;
113116
this._currencySettings = currencySettings;
114117
this._shippingSettings = shippingSettings;
118+
this._paymentSettings = paymentSettings;
115119
this._eventPublisher = eventPublisher;
116120
this._storeInformationSettings = storeInformationSettings;
117121
}
@@ -234,7 +238,9 @@ protected Dictionary<string, IEnumerable<string>> AllowedTokens
234238
//recurring payment tokens
235239
_allowedTokens.Add(TokenGroupNames.RecurringPaymentTokens, new[]
236240
{
237-
"%RecurringPayment.ID%"
241+
"%RecurringPayment.ID%",
242+
"%RecurringPayment.CancelAfterFailedPayment%",
243+
"%RecurringPayment.RecurringPaymentType%"
238244
});
239245

240246
//newsletter subscription tokens
@@ -983,6 +989,10 @@ public virtual void AddOrderNoteTokens(IList<Token> tokens, OrderNote orderNote)
983989
public virtual void AddRecurringPaymentTokens(IList<Token> tokens, RecurringPayment recurringPayment)
984990
{
985991
tokens.Add(new Token("RecurringPayment.ID", recurringPayment.Id));
992+
tokens.Add(new Token("RecurringPayment.CancelAfterFailedPayment",
993+
recurringPayment.LastPaymentFailed && _paymentSettings.CancelRecurringPaymentsAfterFailedPayment));
994+
if (recurringPayment.InitialOrder != null)
995+
tokens.Add(new Token("RecurringPayment.RecurringPaymentType", _paymentService.GetRecurringPaymentType(recurringPayment.InitialOrder.PaymentMethodSystemName).ToString()));
986996

987997
//event notification
988998
_eventPublisher.EntityTokensAdded(recurringPayment, tokens);

src/Libraries/Nop.Services/Messages/WorkflowMessageService.cs

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -898,6 +898,82 @@ public virtual int SendRecurringPaymentCancelledStoreOwnerNotification(Recurring
898898
return SendNotification(messageTemplate, emailAccount, languageId, tokens, toEmail, toName);
899899
}
900900

901+
/// <summary>
902+
/// Sends a "Recurring payment cancelled" notification to a customer
903+
/// </summary>
904+
/// <param name="recurringPayment">Recurring payment</param>
905+
/// <param name="languageId">Message language identifier</param>
906+
/// <returns>Queued email identifier</returns>
907+
public virtual int SendRecurringPaymentCancelledCustomerNotification(RecurringPayment recurringPayment, int languageId)
908+
{
909+
if (recurringPayment == null)
910+
throw new ArgumentNullException("recurringPayment");
911+
912+
var store = _storeService.GetStoreById(recurringPayment.InitialOrder.StoreId) ?? _storeContext.CurrentStore;
913+
languageId = EnsureLanguageIsActive(languageId, store.Id);
914+
915+
var messageTemplate = GetActiveMessageTemplate(MessageTemplateSystemNames.RecurringPaymentCancelledCustomerNotification, store.Id);
916+
if (messageTemplate == null)
917+
return 0;
918+
919+
//email account
920+
var emailAccount = GetEmailAccountOfMessageTemplate(messageTemplate, languageId);
921+
922+
//tokens
923+
var tokens = new List<Token>();
924+
_messageTokenProvider.AddStoreTokens(tokens, store, emailAccount);
925+
_messageTokenProvider.AddOrderTokens(tokens, recurringPayment.InitialOrder, languageId);
926+
_messageTokenProvider.AddCustomerTokens(tokens, recurringPayment.InitialOrder.Customer);
927+
_messageTokenProvider.AddRecurringPaymentTokens(tokens, recurringPayment);
928+
929+
//event notification
930+
_eventPublisher.MessageTokensAdded(messageTemplate, tokens);
931+
932+
var toEmail = recurringPayment.InitialOrder.BillingAddress.Email;
933+
var toName = string.Format("{0} {1}",
934+
recurringPayment.InitialOrder.BillingAddress.FirstName, recurringPayment.InitialOrder.BillingAddress.LastName);
935+
936+
return SendNotification(messageTemplate, emailAccount, languageId, tokens, toEmail, toName);
937+
}
938+
939+
/// <summary>
940+
/// Sends a "Recurring payment failed" notification to a customer
941+
/// </summary>
942+
/// <param name="recurringPayment">Recurring payment</param>
943+
/// <param name="languageId">Message language identifier</param>
944+
/// <returns>Queued email identifier</returns>
945+
public virtual int SendRecurringPaymentFailedCustomerNotification(RecurringPayment recurringPayment, int languageId)
946+
{
947+
if (recurringPayment == null)
948+
throw new ArgumentNullException("recurringPayment");
949+
950+
var store = _storeService.GetStoreById(recurringPayment.InitialOrder.StoreId) ?? _storeContext.CurrentStore;
951+
languageId = EnsureLanguageIsActive(languageId, store.Id);
952+
953+
var messageTemplate = GetActiveMessageTemplate(MessageTemplateSystemNames.RecurringPaymentFailedCustomerNotification, store.Id);
954+
if (messageTemplate == null)
955+
return 0;
956+
957+
//email account
958+
var emailAccount = GetEmailAccountOfMessageTemplate(messageTemplate, languageId);
959+
960+
//tokens
961+
var tokens = new List<Token>();
962+
_messageTokenProvider.AddStoreTokens(tokens, store, emailAccount);
963+
_messageTokenProvider.AddOrderTokens(tokens, recurringPayment.InitialOrder, languageId);
964+
_messageTokenProvider.AddCustomerTokens(tokens, recurringPayment.InitialOrder.Customer);
965+
_messageTokenProvider.AddRecurringPaymentTokens(tokens, recurringPayment);
966+
967+
//event notification
968+
_eventPublisher.MessageTokensAdded(messageTemplate, tokens);
969+
970+
var toEmail = recurringPayment.InitialOrder.BillingAddress.Email;
971+
var toName = string.Format("{0} {1}",
972+
recurringPayment.InitialOrder.BillingAddress.FirstName, recurringPayment.InitialOrder.BillingAddress.LastName);
973+
974+
return SendNotification(messageTemplate, emailAccount, languageId, tokens, toEmail, toName);
975+
}
976+
901977
#endregion
902978

903979
#region Newsletter workflow

src/Libraries/Nop.Services/Orders/IOrderProcessingService.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ public partial interface IOrderProcessingService
4343
/// </summary>
4444
/// <param name="recurringPayment">Recurring payment</param>
4545
/// <param name="paymentResult">Process payment result (info about last payment for automatic recurring payments)</param>
46-
void ProcessNextRecurringPayment(RecurringPayment recurringPayment, ProcessPaymentResult paymentResult = null);
46+
/// <returns>Collection of errors</returns>
47+
IEnumerable<string> ProcessNextRecurringPayment(RecurringPayment recurringPayment, ProcessPaymentResult paymentResult = null);
4748

4849
/// <summary>
4950
/// Cancels a recurring payment
@@ -59,8 +60,14 @@ public partial interface IOrderProcessingService
5960
/// <returns>value indicating whether a customer can cancel recurring payment</returns>
6061
bool CanCancelRecurringPayment(Customer customerToValidate, RecurringPayment recurringPayment);
6162

63+
/// <summary>
64+
/// Gets a value indicating whether a customer can retry last failed recurring payment
65+
/// </summary>
66+
/// <param name="customer">Customer</param>
67+
/// <param name="recurringPayment">Recurring Payment</param>
68+
/// <returns>True if a customer can retry payment; otherwise false</returns>
69+
bool CanRetryLastRecurringPayment(Customer customer, RecurringPayment recurringPayment);
6270

63-
6471

6572

6673
/// <summary>

0 commit comments

Comments
 (0)