Compare commits

...

4 Commits

Author SHA1 Message Date
khwezi 2ed15b548f Merge pull request 'Refactored PayfastService.GenerateSignature()' (#104) from payments into master
Reviewed-on: #104
2026-06-12 23:27:21 +02:00
Khwezi Mngoma 7d2bc7f1f2 Refactored PayfastService.GenerateSignature()
continuous-integration/drone/pr Build is passing
2026-06-12 23:26:54 +02:00
khwezi ef2428f8e3 Merge pull request 'Refactored GenerateSignature' (#103) from payments into master
Reviewed-on: #103
2026-06-12 23:20:08 +02:00
Khwezi Mngoma 5edff5e272 Refactored GenerateSignature
continuous-integration/drone/pr Build is passing
2026-06-12 23:19:40 +02:00
2 changed files with 12 additions and 15 deletions
@@ -11,20 +11,12 @@ public class CustomerServiceFeatureTests(Fixture fixture) : IClassFixture<Fixtur
[IntegrationFact] [IntegrationFact]
public async Task CreateCustomerAsync_ShouldReturn_ResultWithCustomerId() public async Task CreateCustomerAsync_ShouldReturn_ResultWithCustomerId()
{ {
//var request = new CreateCustomer
//{
// Company = "Book Lovers",
// Email = "hank@booklovers.com",
// Phone = "555 1245 8577",
// Website = "https://www.booklovers.com"
//};
var request = new CreateCustomer var request = new CreateCustomer
{ {
//Company = "Book Lovers", Company = "Book Lovers",
Email = "hank@booklovers.com", Email = "hank@booklovers.com",
//Phone = "555 1245 8577", Phone = "555 1245 8577",
//Website = "https://www.booklovers.com" Website = "https://www.booklovers.com"
}; };
var result = await customerService.CreateCustomerAsync(request, fixture.CancellationToken); var result = await customerService.CreateCustomerAsync(request, fixture.CancellationToken);
@@ -152,11 +152,16 @@ public sealed partial class PayfastService(IDbContextFactory<MidrandBooksDbConte
if (string.IsNullOrEmpty(kvp.Value)) if (string.IsNullOrEmpty(kvp.Value))
continue; continue;
if (kvp.Key.Equals("signature", StringComparison.OrdinalIgnoreCase))
continue;
string key = kvp.Key; string key = kvp.Key;
// 1. Payfast requires spaces to be '+' signs. HttpUtility does this perfectly.
string encodedVal = HttpUtility.UrlEncode(kvp.Value.Trim()); string encodedVal = HttpUtility.UrlEncode(kvp.Value.Trim());
string val = PercentEncodingRegex.Replace(encodedVal, m => m.Value.ToLowerInvariant()); // 2. Payfast requires all OTHER percent-encoded hex arrays to be UPPERCASE (e.g., %3A instead of %3a)
string val = Regex.Replace(encodedVal, "%[0-9A-Fa-f]{2}", m => m.Value.ToUpperInvariant());
pfOutput.Append($"{key}={val}&"); pfOutput.Append($"{key}={val}&");
} }
@@ -167,9 +172,9 @@ public sealed partial class PayfastService(IDbContextFactory<MidrandBooksDbConte
if (!string.IsNullOrWhiteSpace(passPhrase)) if (!string.IsNullOrWhiteSpace(passPhrase))
{ {
// Apply the exact same encoding rule to your passphrase
string encodedPassphrase = HttpUtility.UrlEncode(passPhrase.Trim()); string encodedPassphrase = HttpUtility.UrlEncode(passPhrase.Trim());
string safePassphrase = Regex.Replace(encodedPassphrase, "%[0-9A-Fa-f]{2}", m => m.Value.ToUpperInvariant());
string safePassphrase = PercentEncodingRegex.Replace(encodedPassphrase, m => m.Value.ToLowerInvariant());
getString += $"&passphrase={safePassphrase}"; getString += $"&passphrase={safePassphrase}";
} }