Skip to content

Commit 4a55dc3

Browse files
authored
Merge pull request #32 from umbraco/feature/payment-provider-integration
Feedback updates
2 parents ee7a35e + b670240 commit 4a55dc3

File tree

20 files changed

+395
-84
lines changed

20 files changed

+395
-84
lines changed

src/Umbraco.Forms.Integrations.Commerce.EMerchantPay/App_Plugins/UmbracoForms.Integrations/Commerce/eMerchantPay/customer-details-mapper.controller.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
function CustomerDetailsMapperController($scope, notificationsService, emerchantpayService) {
1+
function CustomerDetailsMapperController($scope, notificationsService, emerchantpayService, umbracoFormsIntegrationsCommerceEMerchantPayResource) {
22

33
var vm = this;
44

@@ -31,7 +31,10 @@
3131

3232

3333
function init() {
34-
vm.customerProperties = ["Email", "FirstName", "LastName", "Phone", "Address", "ZipCode", "City", "State", "Country"];
34+
35+
umbracoFormsIntegrationsCommerceEMerchantPayResource.getMappingFields().then(function (response) {
36+
vm.customerProperties = response;
37+
});
3538

3639
vm.fields = [];
3740

src/Umbraco.Forms.Integrations.Commerce.EMerchantPay/App_Plugins/UmbracoForms.Integrations/Commerce/eMerchantPay/emerchantpay.resource.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
$http.get(`${apiEndpoint}/GetCurrencies`),
99
"Failed to get resource");
1010
},
11+
getMappingFields: function () {
12+
return umbRequestHelper.resourcePromise(
13+
$http.get(`${apiEndpoint}/GetMappingFields`),
14+
"Failed to get resource");
15+
}
1116
};
1217
}
1318

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System.Collections.Generic;
2+
3+
namespace Umbraco.Forms.Integrations.Commerce.EMerchantPay.Configuration
4+
{
5+
public interface ISettingsParser
6+
{
7+
IEnumerable<string> AsEnumerable(string propertyName);
8+
9+
Dictionary<string, string> AsDictionary(string propertyName);
10+
}
11+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#if NETCOREAPP
2+
using Microsoft.AspNetCore.Mvc.ModelBinding;
3+
#else
4+
using System.Web.Http.Controllers;
5+
using System.Web.Http.ModelBinding;
6+
#endif
7+
8+
using System;
9+
using System.Linq;
10+
using System.Threading.Tasks;
11+
using Umbraco.Forms.Integrations.Commerce.EMerchantPay.Models.Dtos;
12+
13+
namespace Umbraco.Forms.Integrations.Commerce.EMerchantPay.Configuration
14+
{
15+
public sealed class NotificationModelBinder : IModelBinder
16+
{
17+
#if NETCOREAPP
18+
public Task BindModelAsync(ModelBindingContext bindingContext)
19+
{
20+
if (bindingContext == null)
21+
{
22+
throw new ArgumentNullException(nameof(bindingContext));
23+
}
24+
25+
var transactionId = bindingContext.ValueProvider.GetValue(Constants.NotificationProperty.TransactionId);
26+
27+
var uniqueId = bindingContext.ValueProvider.GetValue(Constants.NotificationProperty.UniqueId);
28+
29+
var status = bindingContext.ValueProvider.GetValue(Constants.NotificationProperty.Status);
30+
31+
var model = new NotificationDto
32+
{
33+
TransactionId = transactionId.FirstValue.ToString(),
34+
UniqueId = uniqueId.FirstValue.ToString(),
35+
Status = status.FirstValue.ToString()
36+
};
37+
38+
bindingContext.Result = ModelBindingResult.Success(model);
39+
40+
return Task.CompletedTask;
41+
}
42+
#else
43+
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
44+
{
45+
var notification = new NotificationDto();
46+
47+
var transactionIdValueResult = bindingContext.ValueProvider
48+
.GetValue(CreateFullPropertyName(bindingContext, Constants.NotificationProperty.TransactionId));
49+
if (transactionIdValueResult != null)
50+
{
51+
notification.TransactionId = transactionIdValueResult.AttemptedValue;
52+
}
53+
54+
var uniqueIdValueResult = bindingContext.ValueProvider.GetValue(CreateFullPropertyName(bindingContext, Constants.NotificationProperty.UniqueId));
55+
if (uniqueIdValueResult != null)
56+
notification.UniqueId= uniqueIdValueResult.AttemptedValue;
57+
58+
var statusValueResult = bindingContext.ValueProvider.GetValue(CreateFullPropertyName(bindingContext, Constants.NotificationProperty.Status));
59+
if (statusValueResult != null)
60+
{
61+
notification.Status = statusValueResult.AttemptedValue;
62+
}
63+
64+
bindingContext.Model = notification;
65+
66+
bindingContext.ValidationNode.ValidateAllProperties = true;
67+
68+
return true;
69+
}
70+
#endif
71+
72+
private string CreateFullPropertyName(ModelBindingContext bindingContext, string propertyName)
73+
{
74+
if (string.IsNullOrEmpty(bindingContext.ModelName))
75+
{
76+
return propertyName;
77+
}
78+
return bindingContext.ModelName + "." + propertyName;
79+
}
80+
81+
}
82+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#if NETCOREAPP
2+
using Microsoft.Extensions.Configuration;
3+
using Microsoft.Extensions.Options;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Linq;
7+
8+
namespace Umbraco.Forms.Integrations.Commerce.EMerchantPay.Configuration
9+
{
10+
public class ObjectParser : ISettingsParser
11+
{
12+
private readonly PaymentProviderSettings _settings;
13+
14+
public ObjectParser(IOptions<PaymentProviderSettings> options)
15+
{
16+
_settings = options.Value;
17+
}
18+
19+
public Dictionary<string, string> AsDictionary(string propertyName)
20+
{
21+
var property = _settings.GetType().GetProperty(propertyName);
22+
23+
if (property == null) throw new ArgumentNullException(nameof(ObjectParser));
24+
25+
var propertyValues = property.GetValue(_settings) as Dictionary<string, string>;
26+
27+
return propertyValues;
28+
}
29+
30+
public IEnumerable<string> AsEnumerable(string propertyName)
31+
{
32+
var property = _settings.GetType().GetProperty(propertyName);
33+
34+
if (property == null) throw new ArgumentNullException(nameof(ObjectParser));
35+
36+
var propertyValues = property.GetValue(_settings);
37+
38+
return propertyValues != null ? propertyValues as IEnumerable<string> : Enumerable.Empty<string>();
39+
}
40+
}
41+
}
42+
#endif

src/Umbraco.Forms.Integrations.Commerce.EMerchantPay/Configuration/PaymentProviderSettings.cs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
using System.Collections.Specialized;
1+
using System.Collections.Generic;
2+
using System.Collections.Specialized;
23

34
namespace Umbraco.Forms.Integrations.Commerce.EMerchantPay.Configuration
45
{
56
public class PaymentProviderSettings
67
{
78
public PaymentProviderSettings()
89
{
9-
1010
}
1111

1212
public PaymentProviderSettings(NameValueCollection appSettings)
@@ -23,6 +23,14 @@ public PaymentProviderSettings(NameValueCollection appSettings)
2323

2424
Usage = appSettings[Constants.Configuration.UsageKey];
2525

26+
#if NETFRAMEWORK
27+
Currencies = appSettings[Constants.Configuration.CurrenciesKey];
28+
29+
TransactionTypes = appSettings[Constants.Configuration.TransactionTypesKey];
30+
31+
MappingFields = appSettings[Constants.Configuration.MappingFieldsKey];
32+
#endif
33+
2634
UmbracoBaseUrl = appSettings[Constants.Configuration.UmbracoBaseUrlKey];
2735
}
2836

@@ -40,6 +48,20 @@ public PaymentProviderSettings(NameValueCollection appSettings)
4048

4149
public string UmbracoBaseUrl { get; set; }
4250

51+
#if NETCOREAPP
52+
public Dictionary<string, string> Currencies { get; set; }
53+
54+
public string[] TransactionTypes { get; set; }
55+
56+
public string[] MappingFields { get; set; }
57+
#else
4358
public string Currencies { get; set; }
59+
60+
public string TransactionTypes { get; set; }
61+
62+
public string MappingFields { get; set; }
63+
#endif
64+
65+
4466
}
4567
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#if NETFRAMEWORK
2+
using System;
3+
using System.Configuration;
4+
using System.Collections.Generic;
5+
6+
using Umbraco.Forms.Integrations.Commerce.EMerchantPay.Configuration;
7+
8+
namespace Umbraco.Forms.Integrations.Commerce.EMerchantPay.Services
9+
{
10+
public class StringParser : ISettingsParser
11+
{
12+
private readonly PaymentProviderSettings _settings;
13+
14+
public StringParser()
15+
{
16+
_settings = new PaymentProviderSettings(ConfigurationManager.AppSettings);
17+
}
18+
19+
public IEnumerable<string> AsEnumerable(string propertyName)
20+
{
21+
var property = _settings.GetType().GetProperty(propertyName);
22+
23+
if (property == null) throw new ArgumentNullException(nameof(StringParser));
24+
25+
return property.GetValue(_settings).ToString().Split(';');
26+
}
27+
28+
public Dictionary<string, string> AsDictionary(string propertyName)
29+
{
30+
var dict = new Dictionary<string, string>();
31+
32+
var property = _settings.GetType().GetProperty(propertyName);
33+
34+
if (property == null) throw new ArgumentNullException(nameof(StringParser));
35+
36+
var propertyValues = property.GetValue(_settings).ToString().Split(';');
37+
38+
foreach(var propertyValue in propertyValues)
39+
{
40+
var value = propertyValue.Split(',');
41+
42+
if(value.Length > 1)
43+
dict.Add(value[0], value[1]);
44+
}
45+
46+
return dict;
47+
}
48+
49+
}
50+
}
51+
#endif

src/Umbraco.Forms.Integrations.Commerce.EMerchantPay/Constants.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ public static class Configuration
2323

2424
public const string CurrenciesKey = "Umbraco.Forms.Integrations.Commerce.eMerchantPay.Currencies";
2525

26+
public const string TransactionTypesKey = "Umbraco.Forms.Integrations.Commerce.eMerchantPay.TransactionTypes";
27+
28+
public const string MappingFieldsKey = "Umbraco.Forms.Integrations.Commerce.eMerchantPay.MappingFields";
29+
2630
public const string UmbracoBaseUrlKey = "Umbraco.Forms.Integrations.Commerce.eMerchantPay.UmbracoBaseUrl";
2731
}
2832

@@ -47,5 +51,14 @@ public static class RootNode
4751

4852
public const string WpfReconcile = "wpf_reconcile";
4953
}
54+
55+
public static class NotificationProperty
56+
{
57+
public const string TransactionId = "wpf_transaction_id";
58+
59+
public const string UniqueId = "wpf_unique_id";
60+
61+
public const string Status = "wpf_status";
62+
}
5063
}
5164
}

src/Umbraco.Forms.Integrations.Commerce.EMerchantPay/Controllers/EmerchantPayController.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,18 @@ public class EmerchantPayController : UmbracoAuthorizedApiController
3030
{
3131
private readonly CurrencyHelper _currencyHelper;
3232

33-
public EmerchantPayController(CurrencyHelper currencyHelper)
33+
private readonly MappingFieldHelper _mappingFieldHelper;
34+
35+
public EmerchantPayController(CurrencyHelper currencyHelper, MappingFieldHelper mappingFieldHelper)
3436
{
3537
_currencyHelper = currencyHelper;
38+
_mappingFieldHelper = mappingFieldHelper;
3639
}
3740

3841
[HttpGet]
3942
public IEnumerable<CurrencyDto> GetCurrencies() => _currencyHelper.GetCurrencies();
43+
44+
[HttpGet]
45+
public IEnumerable<string> GetMappingFields() => _mappingFieldHelper.GetMappings();
4046
}
4147
}

src/Umbraco.Forms.Integrations.Commerce.EMerchantPay/Controllers/PaymentProviderController.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,17 @@ public PaymentProviderController(PaymentService paymentService, IRecordStorage r
4949
}
5050

5151
[HttpPost]
52+
#if NETCOREAPP
53+
public HttpResponseMessage NotifyPayment(string formId, string recordUniqueId, string statusFieldId, [FromForm] NotificationDto notificationDto)
54+
#else
5255
public HttpResponseMessage NotifyPayment(string formId, string recordUniqueId, string statusFieldId, [FromBody] NotificationDto notificationDto)
56+
#endif
5357
{
5458
try
5559
{
5660
// reconcile
5761
var reconcileTask =
58-
Task.Run(async () => await _paymentService.Reconcile(notificationDto.wpf_unique_id));
62+
Task.Run(async () => await _paymentService.Reconcile(notificationDto.UniqueId));
5963

6064
var reconcileResponse = reconcileTask.Result;
6165

@@ -75,7 +79,7 @@ public HttpResponseMessage NotifyPayment(string formId, string recordUniqueId, s
7579
if (reconcileResponse.Status == Constants.ErrorCode.WorkflowError)
7680
return new HttpResponseMessage(HttpStatusCode.BadRequest);
7781

78-
string notificationXml = $"<notification_echo><wpf_unique_id>{notificationDto.wpf_unique_id}</wpf_unique_id></notification_echo>";
82+
string notificationXml = $"<notification_echo><wpf_unique_id>{notificationDto.UniqueId}</wpf_unique_id></notification_echo>";
7983
return new HttpResponseMessage()
8084
{
8185
Content = new StringContent(notificationXml, Encoding.UTF8, "application/xml")

0 commit comments

Comments
 (0)