Skip to content

Commit 81f42a1

Browse files
authored
v13.1.0: Migrate from Newtonsoft.Json to System.Text.Json (#5)
1 parent 2fd14aa commit 81f42a1

17 files changed

+264
-34
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,3 +472,5 @@ $RECYCLE.BIN/
472472
## Umbraco Commerce specific
473473
##
474474
/local_pack.bat
475+
**/packages.lock.json
476+

Umbraco.Commerce.PaymentProviders.Buckaroo.sln

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ VisualStudioVersion = 17.7.34024.191
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Umbraco.Commerce.PaymentProviders.Buckaroo", "src\Umbraco.Commerce.PaymentProviders.Buckaroo\Umbraco.Commerce.PaymentProviders.Buckaroo.csproj", "{9F79EF0C-CA7C-4A1A-AD82-E335EBA5BEB8}"
77
EndProject
8+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Umbraco.Commerce.PaymentProviders.Buckaroo.UnitTests", "tests\Umbraco.Commerce.PaymentProviders.Buckaroo.UnitTests\Umbraco.Commerce.PaymentProviders.Buckaroo.UnitTests.csproj", "{72D33F40-9F9F-4471-A969-C35FC1C9BA4B}"
9+
EndProject
810
Global
911
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1012
Debug|Any CPU = Debug|Any CPU
@@ -15,6 +17,10 @@ Global
1517
{9F79EF0C-CA7C-4A1A-AD82-E335EBA5BEB8}.Debug|Any CPU.Build.0 = Debug|Any CPU
1618
{9F79EF0C-CA7C-4A1A-AD82-E335EBA5BEB8}.Release|Any CPU.ActiveCfg = Release|Any CPU
1719
{9F79EF0C-CA7C-4A1A-AD82-E335EBA5BEB8}.Release|Any CPU.Build.0 = Release|Any CPU
20+
{72D33F40-9F9F-4471-A969-C35FC1C9BA4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
21+
{72D33F40-9F9F-4471-A969-C35FC1C9BA4B}.Debug|Any CPU.Build.0 = Debug|Any CPU
22+
{72D33F40-9F9F-4471-A969-C35FC1C9BA4B}.Release|Any CPU.ActiveCfg = Release|Any CPU
23+
{72D33F40-9F9F-4471-A969-C35FC1C9BA4B}.Release|Any CPU.Build.0 = Release|Any CPU
1824
EndGlobalSection
1925
GlobalSection(SolutionProperties) = preSolution
2026
HideSolutionNode = FALSE

src/Umbraco.Commerce.PaymentProviders.Buckaroo/BuckarooOneTimePaymentProvider.cs

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.IO;
43
using System.Linq;
54
using System.Net;
65
using System.Net.Http;
7-
using System.Text;
86
using System.Threading;
97
using System.Threading.Tasks;
108
using BuckarooSdk.Connection;
119
using BuckarooSdk.DataTypes;
1210
using BuckarooSdk.DataTypes.RequestBases;
1311
using Microsoft.AspNetCore.Http;
14-
using Newtonsoft.Json;
1512
using Umbraco.Commerce.Common.Logging;
1613
using Umbraco.Commerce.Core.Api;
1714
using Umbraco.Commerce.Core.Models;
1815
using Umbraco.Commerce.Core.PaymentProviders;
1916
using Umbraco.Commerce.PaymentProviders.Buckaroo.Extensions;
2017
using Umbraco.Commerce.PaymentProviders.Buckaroo.Webhooks;
18+
using Umbraco.Commerce.PaymentProviders.Buckaroo.Webhooks.Exceptions;
2119

2220
namespace Umbraco.Commerce.PaymentProviders.Buckaroo
2321
{
@@ -136,43 +134,31 @@ public override async Task<CallbackResult> ProcessCallbackAsync(PaymentProviderC
136134
request.Headers.TryGetValues("Authorization", out IEnumerable<string>? headers);
137135
if (headers == null || string.IsNullOrEmpty(headers.FirstOrDefault()))
138136
{
139-
return null;
137+
throw new BuckarooWebhookInvalidAuthorizationHeaderException(context.Order.OrderNumber, context.Order.CartNumber, request.RequestUri!);
140138
}
141139

142140
if (request.Content == null)
143141
{
144-
return null;
142+
throw new BuckarooWebhookEmptyBodyException(context.Order.OrderNumber, context.Order.CartNumber, request.RequestUri!);
145143
}
146144

147-
string authorizationHeader = headers.First();
148-
BuckarooApiCredentials apiCredentials = context.Settings.GetApiCredentials();
149-
byte[] requestBody = await request.Content.ReadAsByteArrayAsync(cancellationToken).ConfigureAwait(false);
150-
SignatureCalculationService signatureService = new();
151-
152145
#pragma warning disable CA1308 // Do not normalize strings to uppercase because Buckaroo asks for lowercase string ¯\_(ツ)_/¯
153146
string webhookHostname = !string.IsNullOrWhiteSpace(context.Settings.WebhookHostnameOverwrite) ? context.Settings.WebhookHostnameOverwrite : request.RequestUri!.Authority;
154147
string encodedUri = WebUtility.UrlEncode(webhookHostname + request.RequestUri!.PathAndQuery).ToLowerInvariant();
155148
#pragma warning restore CA1308 // Normalize strings to uppercase
156149

150+
byte[] requestBody = await request.Content.ReadAsByteArrayAsync(cancellationToken).ConfigureAwait(false);
151+
string authorizationHeader = headers.First();
152+
BuckarooApiCredentials apiCredentials = context.Settings.GetApiCredentials();
153+
154+
SignatureCalculationService signatureService = new();
157155
bool signatureVerified = signatureService.VerifySignature(requestBody, request.Method.Method.ToUpperInvariant(), encodedUri, apiCredentials.SecretKey, authorizationHeader);
158156
if (!signatureVerified)
159157
{
160-
Logger.Error("Buckaroo - Invalid signature. OrderNumber: '{OrderNumber}', CartNumber: '{CartNumber}'. encodedUri: '{encodedUri}'", context.Order.OrderNumber, context.Order.CartNumber, encodedUri);
161-
return null;
158+
throw new BuckarooWebhookInvalidSignatureException(context.Order.OrderNumber, context.Order.CartNumber, encodedUri);
162159
}
163160

164-
Stream stream = new MemoryStream(requestBody);
165-
if (stream.CanSeek)
166-
{
167-
stream.Seek(0, SeekOrigin.Begin);
168-
}
169-
170-
using (var reader = new StreamReader(stream, Encoding.UTF8))
171-
{
172-
string requestBodyContent = await reader.ReadToEndAsync(cancellationToken).ConfigureAwait(false);
173-
BuckarooWebhookTransaction buckarooEvent = JsonConvert.DeserializeObject<BuckarooWebhookResponse?>(requestBodyContent)?.Transaction ?? throw new NotImplementedException("Unable to parse buckaroo push message to object");
174-
return buckarooEvent;
175-
}
161+
return BuckarooWebhookHelper.ParseDataFromBytes(requestBody);
176162
}
177163

178164
public override Task<ApiResult> FetchPaymentStatusAsync(PaymentProviderContext<BuckarooOneTimeSettings> context, CancellationToken cancellationToken = default)

src/Umbraco.Commerce.PaymentProviders.Buckaroo/BuckarooPaymentProviderBase.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,21 @@ protected BuckarooPaymentProviderBase(
2121

2222
public override string GetCancelUrl(PaymentProviderContext<TSettings> context)
2323
{
24-
ArgumentNullException.ThrowIfNull(context);
25-
ArgumentNullException.ThrowIfNull(context.Settings, "settings");
26-
ArgumentNullException.ThrowIfNull(context.Settings.CancelUrl, "settings.CancelUrl");
24+
ArgumentNullException.ThrowIfNull(context?.Settings.CancelUrl, "settings.CancelUrl");
2725

2826
return context.Settings.CancelUrl;
2927
}
3028

3129
public override string GetContinueUrl(PaymentProviderContext<TSettings> context)
3230
{
33-
ArgumentNullException.ThrowIfNull(context);
31+
ArgumentNullException.ThrowIfNull(context?.Settings.ContinueUrl);
3432

35-
return context.Settings.ContinueUrl; // + (settings.ContinueUrl.Contains("?") ? "&" : "?") + "session_id={CHECKOUT_SESSION_ID}";
33+
return context.Settings.ContinueUrl;
3634
}
3735

3836
public override string GetErrorUrl(PaymentProviderContext<TSettings> context)
3937
{
40-
ArgumentNullException.ThrowIfNull(context);
38+
ArgumentNullException.ThrowIfNull(context?.Settings.ErrorUrl);
4139

4240
return context.Settings.ErrorUrl;
4341
}

src/Umbraco.Commerce.PaymentProviders.Buckaroo/Extensions/BuckarooClientHelper.cs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,19 @@ internal class BuckarooClientHelper
1111
/// Get a new instance of <see cref="AuthenticatedRequest"/> each time it is called.
1212
/// </summary>
1313
/// <param name="settings"></param>
14+
/// <exception cref="BuckarooInvalidSettingsException"></exception>
1415
/// <returns></returns>
1516
public static AuthenticatedRequest GetAuthenticatedRequest(BuckarooSettingsBase settings)
1617
{
17-
BuckarooApiCredentials input = settings.GetApiCredentials();
18+
BuckarooApiCredentials credentials = settings.GetApiCredentials();
19+
if (string.IsNullOrWhiteSpace(credentials.SecretKey) || string.IsNullOrWhiteSpace(credentials.WebsiteKey))
20+
{
21+
throw new BuckarooInvalidSettingsException();
22+
}
23+
1824
return new SdkClient()
1925
.CreateRequest()
20-
.Authenticate(input.WebsiteKey, input.SecretKey, input.IsLive, CultureInfo.CurrentCulture);
26+
.Authenticate(credentials.WebsiteKey, credentials.SecretKey, credentials.IsLive, CultureInfo.CurrentCulture);
2127
}
2228
}
2329
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System;
2+
3+
namespace Umbraco.Commerce.PaymentProviders.Buckaroo.Extensions
4+
{
5+
public class BuckarooInvalidSettingsException : Exception
6+
{
7+
private const string DefaultMessage = "Invalid payment provider settings. Please make sure that website key and secret key are set correctly in Umbraco backoffice.";
8+
9+
10+
public BuckarooInvalidSettingsException() : base(DefaultMessage)
11+
{
12+
}
13+
14+
public BuckarooInvalidSettingsException(string message = DefaultMessage) : base(message)
15+
{
16+
}
17+
18+
public BuckarooInvalidSettingsException(string message, Exception innerException) : base(message, innerException)
19+
{
20+
}
21+
}
22+
}

src/Umbraco.Commerce.PaymentProviders.Buckaroo/Extensions/BuckarooSettingBaseExtensions.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ internal static class BuckarooSettingBaseExtensions
88
/// Get Buckaroo api credentials from backoffice settings.
99
/// </summary>
1010
/// <param name="settings"></param>
11-
/// <returns>Live credentials or test credentials depends on <see cref="BuckarooSettingsBase.IsTestMode"/> value.</returns>
1211
public static BuckarooApiCredentials GetApiCredentials(this BuckarooSettingsBase settings) => new BuckarooApiCredentials
1312
{
1413
WebsiteKey = settings.WebsiteKey,

src/Umbraco.Commerce.PaymentProviders.Buckaroo/Umbraco.Commerce.PaymentProviders.Buckaroo.csproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
<Nullable>enable</Nullable>
77
</PropertyGroup>
88

9+
<ItemGroup>
10+
<InternalsVisibleTo Include="Umbraco.Commerce.PaymentProviders.Buckaroo.UnitTests" />
11+
</ItemGroup>
12+
913
<ItemGroup>
1014
<PackageReference Include="BuckarooSdk" />
1115
<PackageReference Include="Microsoft.AspNet.WebApi.Client" />
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System;
2+
using System.Text.Json;
3+
4+
namespace Umbraco.Commerce.PaymentProviders.Buckaroo.Webhooks
5+
{
6+
internal static class BuckarooWebhookHelper
7+
{
8+
public static BuckarooWebhookTransaction ParseDataFromBytes(byte[] data)
9+
{
10+
string jsonContent = System.Text.Encoding.UTF8.GetString(data);
11+
BuckarooWebhookTransaction buckarooEvent = JsonSerializer.Deserialize<BuckarooWebhookResponse?>(jsonContent)?.Transaction ?? throw new NotImplementedException("Unable to parse buckaroo push message to object");
12+
return buckarooEvent;
13+
}
14+
}
15+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
using System;
2+
using System.Globalization;
3+
using System.Text;
4+
5+
namespace Umbraco.Commerce.PaymentProviders.Buckaroo.Webhooks.Exceptions
6+
{
7+
public class BuckarooWebhookEmptyBodyException : Exception
8+
{
9+
private static readonly CompositeFormat _messageFormat = CompositeFormat.Parse("Buckaroo - Empty body content. OrderNumber: '{0}', CartNumber: '{1}'. encodedUri: '{2}'");
10+
11+
public BuckarooWebhookEmptyBodyException(
12+
string orderNumber,
13+
string cartNumber,
14+
Uri webhookUri)
15+
: base(string.Format(CultureInfo.InvariantCulture, _messageFormat, orderNumber, cartNumber, webhookUri))
16+
{
17+
}
18+
19+
public BuckarooWebhookEmptyBodyException(string message) : base(message)
20+
{
21+
}
22+
23+
public BuckarooWebhookEmptyBodyException(string message, Exception innerException) : base(message, innerException)
24+
{
25+
}
26+
}
27+
}

0 commit comments

Comments
 (0)