Merge pull request 'Honoring the mandatory field sequence' (#105) from payments into master
Reviewed-on: #105
This commit was merged in pull request #105.
This commit is contained in:
@@ -147,23 +147,56 @@ public sealed partial class PayfastService(IDbContextFactory<MidrandBooksDbConte
|
|||||||
{
|
{
|
||||||
var pfOutput = new StringBuilder();
|
var pfOutput = new StringBuilder();
|
||||||
|
|
||||||
foreach (var kvp in data)
|
// Define the exact structural sequence mandated by Payfast's documentation
|
||||||
|
string[] mandatorySequence =
|
||||||
|
[
|
||||||
|
"merchant_id",
|
||||||
|
"merchant_key",
|
||||||
|
"return_url",
|
||||||
|
"cancel_url",
|
||||||
|
"notify_url",
|
||||||
|
"name_first",
|
||||||
|
"name_last",
|
||||||
|
"email_address",
|
||||||
|
"cell_number",
|
||||||
|
"m_payment_id",
|
||||||
|
"amount",
|
||||||
|
"item_name",
|
||||||
|
"item_description",
|
||||||
|
"custom_int1",
|
||||||
|
"custom_int2",
|
||||||
|
"custom_int3",
|
||||||
|
"custom_int4",
|
||||||
|
"custom_int5",
|
||||||
|
"custom_str1",
|
||||||
|
"custom_str2",
|
||||||
|
"custom_str3",
|
||||||
|
"custom_str4",
|
||||||
|
"custom_str5",
|
||||||
|
"email_confirmation",
|
||||||
|
"confirmation_address",
|
||||||
|
"payment_method",
|
||||||
|
"subscription_type",
|
||||||
|
"billing_date",
|
||||||
|
"recurring_amount",
|
||||||
|
"frequency",
|
||||||
|
"cycles"
|
||||||
|
];
|
||||||
|
|
||||||
|
// 1. Iterate explicitly by the mandatory positional array sequence instead of the dictionary's internal order
|
||||||
|
foreach (string key in mandatorySequence)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(kvp.Value))
|
// Only append if the key exists in your source dictionary and contains data
|
||||||
continue;
|
if (data.TryGetValue(key, out string? rawValue) && !string.IsNullOrEmpty(rawValue))
|
||||||
|
{
|
||||||
|
// Payfast requires spaces to be '+' signs. HttpUtility does this natively.
|
||||||
|
string encodedVal = HttpUtility.UrlEncode(rawValue.Trim());
|
||||||
|
|
||||||
if (kvp.Key.Equals("signature", StringComparison.OrdinalIgnoreCase))
|
// Payfast requires all OTHER percent-encoded hex arrays to be UPPERCASE (e.g., %3A instead of %3a)
|
||||||
continue;
|
string val = Regex.Replace(encodedVal, "%[0-9A-Fa-f]{2}", m => m.Value.ToUpperInvariant());
|
||||||
|
|
||||||
string key = kvp.Key;
|
pfOutput.Append($"{key}={val}&");
|
||||||
|
}
|
||||||
// 1. Payfast requires spaces to be '+' signs. HttpUtility does this perfectly.
|
|
||||||
string encodedVal = HttpUtility.UrlEncode(kvp.Value.Trim());
|
|
||||||
|
|
||||||
// 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}&");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string getString = pfOutput.Length > 0
|
string getString = pfOutput.Length > 0
|
||||||
@@ -172,7 +205,6 @@ 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 = Regex.Replace(encodedPassphrase, "%[0-9A-Fa-f]{2}", m => m.Value.ToUpperInvariant());
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user