Refactored shasher payfast confirmation response handling
continuous-integration/drone/pr Build is passing

This commit is contained in:
Khwezi Mngoma
2026-06-01 16:36:33 +02:00
parent afc984f3bc
commit 5eb6dbc8b2
4 changed files with 95 additions and 15 deletions
+16 -9
View File
@@ -1,5 +1,6 @@
using LiteCharms.Features.Abstractions;
using LiteCharms.Features.Hasher.Configuration;
using LiteCharms.Features.Models;
namespace LiteCharms.Features.Hasher;
@@ -40,24 +41,30 @@ public sealed partial class HashService(IHashids hasher, IOptions<HasherSettings
return Result.Ok(Convert.ToHexString(bytes).ToLowerInvariant());
}
public Result<bool> VerifyPayfastWebhookSignature(IDictionary<string, string> incomingFormData, string incomingSignature)
public Result<bool> VerifyPayfastWebhookSignature(PayfastWebhookPayload payload, string incomingSignature)
{
try
{
if (string.IsNullOrWhiteSpace(incomingSignature))
return Result.Fail<bool>("Validation failed: Missing signature string parameter.");
var sortedFields = incomingFormData
.Where(field => !string.Equals(field.Key, "signature", StringComparison.OrdinalIgnoreCase))
.OrderBy(field => field.Key, StringComparer.Ordinal)
.Select(field => $"{field.Key}={WebUtility.UrlEncode(field.Value)}");
var parameters = new List<string>();
string payload = string.Join("&", sortedFields);
if (!string.IsNullOrWhiteSpace(payload.Amount))
parameters.Add($"amount={WebUtility.UrlEncode(payload.Amount)}");
if (!string.IsNullOrWhiteSpace(payload.ItemName))
parameters.Add($"item_name={WebUtility.UrlEncode(payload.ItemName)}");
if (!string.IsNullOrWhiteSpace(payload.MPaymentId))
parameters.Add($"m_payment_id={WebUtility.UrlEncode(payload.MPaymentId)}");
string signatureString = string.Join("&", parameters);
if (!string.IsNullOrWhiteSpace(settings.PayfastPassphrase))
payload += $"&passphrase={WebUtility.UrlEncode(settings.PayfastPassphrase)}";
signatureString += $"&passphrase={WebUtility.UrlEncode(settings.PayfastPassphrase)}";
var localHashResult = ToMd5Hash(payload);
var localHashResult = ToMd5Hash(signatureString);
if (!localHashResult.IsSuccess)
return Result.Fail<bool>(localHashResult.Errors);
@@ -68,7 +75,7 @@ public sealed partial class HashService(IHashids hasher, IOptions<HasherSettings
}
catch (Exception ex)
{
return Result.Fail<bool>(new Error("An error occurred during MD5 verification loop.").CausedBy(ex));
return Result.Fail<bool>(new Error("An error occurred during Payfast MD5 verification.").CausedBy(ex));
}
}