Skip to content

Commit d65a25a

Browse files
committed
Refactoring
1 parent 15157d6 commit d65a25a

File tree

7 files changed

+141
-159
lines changed

7 files changed

+141
-159
lines changed

src/VirtoCommerce.OrdersModule.Core/Model/PaymentParameters.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ public class PaymentParameters
66
{
77
public string OrderId { get; set; }
88
public string PaymentMethodCode { get; set; }
9-
public NameValueCollection Parameters { get; set; }
9+
public NameValueCollection Parameters { get; set; } = new();
1010
}
Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
using VirtoCommerce.OrdersModule.Core.Model;
22
using VirtoCommerce.PaymentModule.Model.Requests;
33

4-
namespace VirtoCommerce.OrdersModule.Core.Services
4+
namespace VirtoCommerce.OrdersModule.Core.Services;
5+
6+
public interface IPaymentRequestConverter
57
{
6-
public interface IPaymentRequestConverter
7-
{
8-
PaymentParameters GetPaymentParameters(PaymentCallbackParameters request);
9-
PaymentParameters GetPaymentParameters(string requestBody, string requestQuery);
10-
bool IsFailure(PostProcessPaymentRequestResult result);
11-
object GetResponse(PostProcessPaymentRequestResult result);
12-
}
8+
PaymentParameters GetPaymentParameters(PaymentCallbackParameters request);
9+
PaymentParameters GetPaymentParameters(string requestBody, string requestQuery);
10+
(object, bool) GetResponse(PostProcessPaymentRequestResult result);
1311
}

src/VirtoCommerce.OrdersModule.Data/Services/CustomerOrderPaymentService.cs

Lines changed: 83 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -15,115 +15,115 @@
1515
using VirtoCommerce.StoreModule.Core.Model;
1616
using VirtoCommerce.StoreModule.Core.Services;
1717

18-
namespace VirtoCommerce.OrdersModule.Data.Services
18+
namespace VirtoCommerce.OrdersModule.Data.Services;
19+
20+
public class CustomerOrderPaymentService(
21+
IStoreService storeService,
22+
ICustomerOrderService customerOrderService,
23+
ICustomerOrderSearchService customerOrderSearchService,
24+
IValidator<CustomerOrder> customerOrderValidator,
25+
ISettingsManager settingsManager)
26+
: ICustomerOrderPaymentService
1927
{
20-
public class CustomerOrderPaymentService(
21-
IStoreService storeService,
22-
ICustomerOrderService customerOrderService,
23-
ICustomerOrderSearchService customerOrderSearchService,
24-
IValidator<CustomerOrder> customerOrderValidator,
25-
ISettingsManager settingsManager)
26-
: ICustomerOrderPaymentService
28+
public virtual async Task<PostProcessPaymentRequestResult> PostProcessPaymentAsync(PaymentParameters paymentParameters)
2729
{
28-
public virtual async Task<PostProcessPaymentRequestResult> PostProcessPaymentAsync(PaymentParameters paymentParameters)
30+
ArgumentNullException.ThrowIfNull(paymentParameters);
31+
32+
var customerOrder = await GetCustomerOrder(paymentParameters);
33+
if (customerOrder == null)
34+
{
35+
throw new InvalidOperationException($"Cannot find order with ID {paymentParameters.OrderId}");
36+
}
37+
38+
var store = await storeService.GetByIdAsync(customerOrder.StoreId, nameof(StoreResponseGroup.StoreInfo));
39+
if (store == null)
2940
{
30-
ArgumentNullException.ThrowIfNull(paymentParameters);
41+
throw new InvalidOperationException($"Cannot find store with ID {customerOrder.StoreId}");
42+
}
43+
44+
var inPayments = GetInPayments(customerOrder, paymentParameters);
3145

32-
var customerOrder = await GetCustomerOrder(paymentParameters);
33-
if (customerOrder == null)
46+
foreach (var inPayment in inPayments)
47+
{
48+
// Each payment method must check that these parameters are addressed to it
49+
var paymentMethodValidationResult = inPayment.PaymentMethod.ValidatePostProcessRequest(paymentParameters.Parameters);
50+
if (!paymentMethodValidationResult.IsSuccess)
3451
{
35-
throw new InvalidOperationException($"Cannot find order with ID {paymentParameters.OrderId}");
52+
continue;
3653
}
3754

38-
var store = await storeService.GetByIdAsync(customerOrder.StoreId, StoreResponseGroup.StoreInfo.ToString());
39-
if (store == null)
55+
var paymentMethodRequest = new PostProcessPaymentRequest
56+
{
57+
OrderId = customerOrder.Id,
58+
Order = customerOrder,
59+
PaymentId = inPayment.Id,
60+
Payment = inPayment,
61+
StoreId = customerOrder.StoreId,
62+
Store = store,
63+
OuterId = paymentMethodValidationResult.OuterId,
64+
Parameters = paymentParameters.Parameters,
65+
};
66+
67+
var paymentMethodPostProcessResult = inPayment.PaymentMethod.PostProcessPayment(paymentMethodRequest);
68+
if (paymentMethodPostProcessResult == null)
4069
{
41-
throw new InvalidOperationException($"Cannot find store with ID {customerOrder.StoreId}");
70+
continue;
4271
}
4372

44-
var inPayments = GetInPayments(customerOrder, paymentParameters);
45-
foreach (var inPayment in inPayments)
73+
var customerOrderValidationResult = await ValidateAsync(customerOrder);
74+
if (!customerOrderValidationResult.IsValid)
4675
{
47-
//Each payment method must check that these parameters are addressed to it
48-
var paymentMethodValidationResult = inPayment.PaymentMethod.ValidatePostProcessRequest(paymentParameters.Parameters);
49-
if (!paymentMethodValidationResult.IsSuccess)
76+
return new PostProcessPaymentRequestNotValidResult
5077
{
51-
continue;
52-
}
53-
54-
var paymentMethodRequest = new PostProcessPaymentRequest
55-
{
56-
OrderId = customerOrder.Id,
57-
Order = customerOrder,
58-
PaymentId = inPayment.Id,
59-
Payment = inPayment,
60-
StoreId = customerOrder.StoreId,
61-
Store = store,
62-
OuterId = paymentMethodValidationResult.OuterId,
63-
Parameters = paymentParameters.Parameters
78+
Errors = customerOrderValidationResult.Errors,
79+
ErrorMessage = string.Join(" ", customerOrderValidationResult.Errors.Select(x => x.ErrorMessage)),
6480
};
81+
}
6582

66-
var paymentMethodPostProcessResult = inPayment.PaymentMethod.PostProcessPayment(paymentMethodRequest);
67-
if (paymentMethodPostProcessResult == null)
68-
{
69-
continue;
70-
}
71-
72-
var customerOrderValidationResult = await ValidateAsync(customerOrder);
73-
if (!customerOrderValidationResult.IsValid)
74-
{
75-
return new PostProcessPaymentRequestNotValidResult()
76-
{
77-
Errors = customerOrderValidationResult.Errors,
78-
ErrorMessage = string.Join(" ", customerOrderValidationResult.Errors.Select(x => x.ErrorMessage))
79-
};
80-
}
83+
await customerOrderService.SaveChangesAsync([customerOrder]);
8184

82-
await customerOrderService.SaveChangesAsync(new[] { customerOrder });
85+
// Order number is required
86+
paymentMethodPostProcessResult.OrderId = customerOrder.Number;
8387

84-
// order Number is required
85-
paymentMethodPostProcessResult.OrderId = customerOrder.Number;
88+
return paymentMethodPostProcessResult;
89+
}
8690

87-
return paymentMethodPostProcessResult;
88-
}
91+
return new PostProcessPaymentRequestResult { ErrorMessage = "Payment method not found" };
92+
}
8993

90-
return new PostProcessPaymentRequestResult { ErrorMessage = "Payment method not found" };
94+
protected virtual async Task<CustomerOrder> GetCustomerOrder(PaymentParameters paymentParameters)
95+
{
96+
if (string.IsNullOrEmpty(paymentParameters.OrderId))
97+
{
98+
throw new InvalidOperationException("The 'orderid' parameter must be passed");
9199
}
92100

93-
protected virtual async Task<CustomerOrder> GetCustomerOrder(PaymentParameters paymentParameters)
94-
{
95-
if (string.IsNullOrEmpty(paymentParameters.OrderId))
96-
{
97-
throw new InvalidOperationException("The 'orderid' parameter must be passed");
98-
}
101+
// Some payment method require customer number to be passed and returned. First search customer order by number
102+
var searchCriteria = AbstractTypeFactory<CustomerOrderSearchCriteria>.TryCreateInstance();
103+
searchCriteria.Number = paymentParameters.OrderId;
104+
searchCriteria.ResponseGroup = nameof(CustomerOrderResponseGroup.Full);
99105

100-
//some payment method require customer number to be passed and returned. First search customer order by number
101-
var searchCriteria = AbstractTypeFactory<CustomerOrderSearchCriteria>.TryCreateInstance();
102-
searchCriteria.Number = paymentParameters.OrderId;
103-
searchCriteria.ResponseGroup = CustomerOrderResponseGroup.Full.ToString();
106+
// If order is not found by order number, search by order id
107+
var orders = await customerOrderSearchService.SearchAsync(searchCriteria);
104108

105-
//if order not found by order number search by order id
106-
var orders = await customerOrderSearchService.SearchAsync(searchCriteria);
109+
return orders.Results.FirstOrDefault() ?? await customerOrderService.GetByIdAsync(paymentParameters.OrderId, nameof(CustomerOrderResponseGroup.Full));
110+
}
107111

108-
return orders.Results.FirstOrDefault() ?? await customerOrderService.GetByIdAsync(paymentParameters.OrderId, CustomerOrderResponseGroup.Full.ToString());
109-
}
112+
protected virtual IList<PaymentIn> GetInPayments(CustomerOrder customerOrder, PaymentParameters paymentParameters)
113+
{
114+
// Need to use concrete payment method if its code has been passed, otherwise use all order payment methods
115+
return customerOrder.InPayments
116+
.Where(x => x.PaymentMethod != null && (string.IsNullOrEmpty(paymentParameters.PaymentMethodCode) || x.GatewayCode.EqualsIgnoreCase(paymentParameters.PaymentMethodCode)))
117+
.ToList();
118+
}
110119

111-
protected virtual IList<PaymentIn> GetInPayments(CustomerOrder customerOrder, PaymentParameters paymentParameters)
120+
protected virtual async Task<ValidationResult> ValidateAsync(CustomerOrder customerOrder)
121+
{
122+
if (await settingsManager.GetValueAsync<bool>(ModuleConstants.Settings.General.CustomerOrderValidation))
112123
{
113-
//Need to use concrete payment method if it code passed otherwise use all order payment methods
114-
return customerOrder.InPayments
115-
.Where(x => x.PaymentMethod != null && (string.IsNullOrEmpty(paymentParameters.PaymentMethodCode) || x.GatewayCode.EqualsIgnoreCase(paymentParameters.PaymentMethodCode)))
116-
.ToList();
124+
return await customerOrderValidator.ValidateAsync(customerOrder);
117125
}
118126

119-
protected virtual async Task<ValidationResult> ValidateAsync(CustomerOrder customerOrder)
120-
{
121-
if (await settingsManager.GetValueAsync<bool>(ModuleConstants.Settings.General.CustomerOrderValidation))
122-
{
123-
return await customerOrderValidator.ValidateAsync(customerOrder);
124-
}
125-
126-
return new ValidationResult();
127-
}
127+
return new ValidationResult();
128128
}
129129
}
Lines changed: 29 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,48 @@
1-
using System;
2-
using System.Collections.Specialized;
31
using Newtonsoft.Json;
42
using VirtoCommerce.OrdersModule.Core.Model;
53
using VirtoCommerce.OrdersModule.Core.Services;
64
using VirtoCommerce.OrdersModule.Data.Model;
75
using VirtoCommerce.PaymentModule.Model.Requests;
6+
using VirtoCommerce.Platform.Core.Common;
87

9-
namespace VirtoCommerce.OrdersModule.Data.Services
8+
namespace VirtoCommerce.OrdersModule.Data.Services;
9+
10+
public class PaymentRequestDefaultConverter : IPaymentRequestConverter
1011
{
11-
public class PaymentRequestDefaultConverter : IPaymentRequestConverter
12+
public virtual PaymentParameters GetPaymentParameters(PaymentCallbackParameters request)
1213
{
13-
public virtual PaymentParameters GetPaymentParameters(PaymentCallbackParameters request)
14-
{
15-
var result = new PaymentParameters();
14+
var result = AbstractTypeFactory<PaymentParameters>.TryCreateInstance();
1615

17-
result.Parameters = new NameValueCollection();
16+
foreach (var parameter in request?.Parameters ?? [])
17+
{
18+
result.Parameters.Add(parameter.Key, parameter.Value);
19+
}
1820

19-
foreach (var parameter in request?.Parameters ?? Array.Empty<KeyValuePair>())
20-
{
21-
result.Parameters.Add(parameter.Key, parameter.Value);
22-
}
21+
result.OrderId = result.Parameters.Get("orderid");
22+
result.PaymentMethodCode = result.Parameters.Get("code");
2323

24-
result.OrderId = result.Parameters.Get("orderid");
25-
result.PaymentMethodCode = result.Parameters.Get("code");
24+
return result;
25+
}
2626

27-
return result;
28-
}
27+
public virtual PaymentParameters GetPaymentParameters(string requestBody, string requestQuery)
28+
{
29+
var paymentCallbackParameters = JsonConvert.DeserializeObject<PaymentCallbackParameters>(requestBody);
30+
return GetPaymentParameters(paymentCallbackParameters);
31+
}
2932

30-
public virtual PaymentParameters GetPaymentParameters(string requestBody, string requestQuery)
33+
public virtual (object, bool) GetResponse(PostProcessPaymentRequestResult result)
34+
{
35+
if (result is PostProcessPaymentRequestNotValidResult notValidResult)
3136
{
32-
var paymentCallbackParameters = JsonConvert.DeserializeObject<PaymentCallbackParameters>(requestBody);
33-
return GetPaymentParameters(paymentCallbackParameters);
34-
}
37+
var response = new
38+
{
39+
Message = notValidResult.ErrorMessage,
40+
Errors = notValidResult.Errors,
41+
};
3542

36-
public virtual bool IsFailure(PostProcessPaymentRequestResult result)
37-
{
38-
return result is PostProcessPaymentRequestNotValidResult;
43+
return (response, false);
3944
}
4045

41-
public virtual object GetResponse(PostProcessPaymentRequestResult result)
42-
{
43-
if (IsFailure(result))
44-
{
45-
return new
46-
{
47-
Message = (result as PostProcessPaymentRequestNotValidResult)?.ErrorMessage,
48-
Errors = (result as PostProcessPaymentRequestNotValidResult)?.Errors
49-
};
50-
}
51-
52-
return result;
53-
}
46+
return (result, true);
5447
}
5548
}

src/VirtoCommerce.OrdersModule.Web/Controllers/Api/OrderModuleController.cs

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System;
2+
using System.IO;
23
using System.Linq;
4+
using System.Text;
35
using System.Threading.Tasks;
46
using DinkToPdf;
57
using DinkToPdf.Contracts;
@@ -67,7 +69,7 @@ public class OrderModuleController(
6769
IOptions<OutputJsonSerializerSettings> outputJsonSerializerSettings,
6870
IValidator<CustomerOrder> customerOrderValidator,
6971
ISettingsManager settingsManager,
70-
IPaymentRequestConverter paymentParametersConverter,
72+
IPaymentRequestConverter paymentRequestConverter,
7173
ICustomerOrderPaymentService customerOrderPaymentService)
7274
: Controller
7375
{
@@ -521,18 +523,14 @@ public async Task<ActionResult<DashboardStatisticsResult>> GetDashboardStatistic
521523
[Route("~/api/paymentcallback")]
522524
public async Task<ActionResult<PostProcessPaymentRequestResult>> PostProcessPayment([FromBody] PaymentCallbackParameters callback)
523525
{
524-
var parameters = paymentParametersConverter.GetPaymentParameters(callback);
525-
526+
var parameters = paymentRequestConverter.GetPaymentParameters(callback);
526527
var result = await customerOrderPaymentService.PostProcessPaymentAsync(parameters);
527528

528-
object response = paymentParametersConverter.GetResponse(result);
529+
var (response, succeeded) = paymentRequestConverter.GetResponse(result);
529530

530-
if (paymentParametersConverter.IsFailure(result))
531-
{
532-
return BadRequest(response);
533-
}
534-
535-
return Ok(response);
531+
return succeeded
532+
? Ok(response)
533+
: BadRequest(response);
536534
}
537535

538536
/// <summary>
@@ -542,26 +540,20 @@ public async Task<ActionResult<PostProcessPaymentRequestResult>> PostProcessPaym
542540
[Route("~/api/paymentcallback-raw")]
543541
public async Task<ActionResult<PostProcessPaymentRequestResult>> PostProcessPaymentRaw()
544542
{
545-
var parameters = paymentParametersConverter.GetPaymentParameters(await GetRequestBody(), Request.QueryString.Value);
546-
543+
var parameters = paymentRequestConverter.GetPaymentParameters(await GetRequestBody(), Request.QueryString.Value);
547544
var result = await customerOrderPaymentService.PostProcessPaymentAsync(parameters);
548545

549-
object response = paymentParametersConverter.GetResponse(result);
546+
var (response, succeeded) = paymentRequestConverter.GetResponse(result);
550547

551-
if (paymentParametersConverter.IsFailure(result))
552-
{
553-
return BadRequest(response);
554-
}
555-
556-
return Ok(response);
548+
return succeeded
549+
? Ok(response)
550+
: BadRequest(response);
557551
}
558552

559553
private async Task<string> GetRequestBody()
560554
{
561-
using (var reader = new System.IO.StreamReader(Request.Body, System.Text.Encoding.UTF8, true, 1024, true))
562-
{
563-
return await reader.ReadToEndAsync();
564-
}
555+
using var reader = new StreamReader(Request.Body, Encoding.UTF8, detectEncodingFromByteOrderMarks: true, 1024, leaveOpen: true);
556+
return await reader.ReadToEndAsync();
565557
}
566558

567559
[HttpGet]

src/VirtoCommerce.OrdersModule.Web/VirtoCommerce.OrdersModule.Web.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
<ProjectReference Include="..\VirtoCommerce.OrdersModule.Data\VirtoCommerce.OrdersModule.Data.csproj" />
3535
</ItemGroup>
3636
<ItemGroup>
37-
<Folder Include="Model\" />
3837
<Folder Include="Scripts\blades\addresses\" />
3938
<NotificationTemplates Include="NotificationTemplates\**" />
4039
<Folder Include="Properties\" />

0 commit comments

Comments
 (0)