Skip to content

Commit b2ae4c1

Browse files
committed
Added error values for PR and SR codes to have better error request reason for better debugging.
1 parent 1cb6e1d commit b2ae4c1

File tree

3 files changed

+147
-6
lines changed

3 files changed

+147
-6
lines changed

Sdk/ErrorCodesValues.cs

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
using System.Collections.Generic;
2+
3+
namespace GPWebpayNet.Sdk
4+
{
5+
/// <summary>
6+
/// Helper class with PR and SR codes values.
7+
/// </summary>
8+
public static class ErrorCodesValues
9+
{
10+
private static readonly IReadOnlyDictionary<int, string> PRCodes = new Dictionary<int, string>()
11+
{
12+
{0, "OK" },
13+
{1, "Field too long." },
14+
{2, "Field too short." },
15+
{3, "Incorrect content of field." },
16+
{4, "Field is null." },
17+
{5, "Missing required field." },
18+
{11, "Unknown merchant." },
19+
{14, "Duplicate order number." },
20+
{15, "Object not found." },
21+
{17, "Amount to deposit exceeds approved amount." },
22+
{18, "Total sum of credited amounts exceeded deposited amount." },
23+
{20, "Object not in valid state for operation." },
24+
{25, "Operation not allowed for user." },
25+
{26, "Technical problem in connection to authorization center." },
26+
{27, "Incorrect order type." },
27+
{28, "Declined in 3D." },
28+
{30, "Declined in AC." },
29+
{31, "Wrong digest." },
30+
{35, "Session expired." },
31+
{50, "The cardholder canceled the payment." },
32+
{200, "Additional info request." },
33+
{1000, "Technical problem." },
34+
};
35+
36+
private static readonly IReadOnlyDictionary<int, string> SRCodes1_5_15_20 = new Dictionary<int, string>()
37+
{
38+
{0, string.Empty },
39+
{1, "ORDERNUMBER" },
40+
{2, "MERCHANTNUMBER" },
41+
{6, "AMOUNT" },
42+
{7, "CURRENCY" },
43+
{8, "DEPOSITFLAG" },
44+
{10, "MERORDERNUM" },
45+
{11, "CREDITNUMBER" },
46+
{12, "OPERATION" },
47+
{18, "BATCH" },
48+
{22, "ORDER" },
49+
{24, "URL" },
50+
{25, "MD" },
51+
{26, "DESC" },
52+
{34, "DIGEST" },
53+
};
54+
55+
private static readonly IReadOnlyDictionary<int, string> SRCodes28 = new Dictionary<int, string>()
56+
{
57+
{0, string.Empty },
58+
{3000, "Declined in 3D. Cardholder not authenticated in 3D." },
59+
{3001, "Authenticated." },
60+
{3002, "Not Authenticated in 3D. Issuer or Cardholder not participating in 3D." },
61+
{3004, "Not Authenticated in 3D. Issuer not participating or Cardholder not enrolled." },
62+
{3005, "Declined in 3D. Technical problem during Cardholder authentication." },
63+
{3006, "Declined in 3D. Technical problem during Cardholder authentication." },
64+
{3007, "Declined in 3D. Acquirer technical problem. Contact the merchant." },
65+
{3008, "Declined in 3D. Unsupported card product." },
66+
};
67+
68+
private static readonly IReadOnlyDictionary<int, string> SRCodes30 = new Dictionary<int, string>()
69+
{
70+
{0, string.Empty },
71+
{1001, "Declined in AC, Card blocked." },
72+
{1002, "Declined in AC, Declined." },
73+
{1003, "Declined in AC, Card problem." },
74+
{1004, "Declined in AC, Technical problem in authorization process." },
75+
{1005, "Declined in AC, Account problem." },
76+
};
77+
78+
/// <summary>
79+
/// Gets value of PR code
80+
/// </summary>
81+
/// <param name="prCode">id of the PR code</param>
82+
/// <returns>PR code value</returns>
83+
public static string GetPRCode(int prCode)
84+
{
85+
if (PRCodes.TryGetValue(prCode, out string value))
86+
{
87+
return value;
88+
}
89+
90+
return $"Unknown value for PR code {prCode}";
91+
}
92+
93+
/// <summary>
94+
/// Gets value of SR code
95+
/// </summary>
96+
/// <param name="prCode">id of the PR code</param>
97+
/// <param name="srCode">id of the PR code</param>
98+
/// <returns>SR code value</returns>
99+
public static string GetSRCode(int prCode, int srCode)
100+
{
101+
IReadOnlyDictionary<int, string> srCodes;
102+
103+
switch (prCode)
104+
{
105+
case 1:
106+
case 2:
107+
case 3:
108+
case 4:
109+
case 5:
110+
case 15:
111+
case 20:
112+
srCodes = SRCodes1_5_15_20;
113+
break;
114+
case 28:
115+
srCodes = SRCodes28;
116+
break;
117+
case 30:
118+
srCodes = SRCodes30;
119+
break;
120+
default:
121+
srCodes = new Dictionary<int, string>();
122+
break;
123+
}
124+
125+
if (srCodes.TryGetValue(srCode, out string value))
126+
{
127+
return value;
128+
}
129+
130+
return $"Unknown value for PR code {prCode} and SR code {srCode}.";
131+
}
132+
}
133+
}

Sdk/Services/ClientService.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Linq;
44
using System.Net.Http;
55
using System.Security.Cryptography.X509Certificates;
6+
using System.Text;
67
using System.Threading.Tasks;
78
using GPWebpayNet.Sdk.Exceptions;
89
using GPWebpayNet.Sdk.Models;
@@ -324,8 +325,11 @@ public void ProcessGPWebPayResponse(
324325

325326
if (paymentResponse.PRCode != 0 || paymentResponse.SRCode != 0)
326327
{
327-
this.logger.LogError("Bad response");
328-
throw new PaymentResponseException(paymentResponse.PRCode, paymentResponse.SRCode, "Bad response",
328+
var errorMessage = new StringBuilder("Bad request:\n");
329+
errorMessage.AppendLine($"PR {paymentResponse.PRCode}: {ErrorCodesValues.GetPRCode(paymentResponse.PRCode)}");
330+
errorMessage.AppendLine($"SR {paymentResponse.SRCode}: {ErrorCodesValues.GetSRCode(paymentResponse.PRCode, paymentResponse.SRCode)}");
331+
this.logger.LogError(errorMessage.ToString());
332+
throw new PaymentResponseException(paymentResponse.PRCode, paymentResponse.SRCode, errorMessage.ToString(),
329333
null);
330334
}
331335
}

Spec/Services/ClientService.Spec.cs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -830,7 +830,9 @@ public void
830830
Action action = () => testee.ProcessGPWebPayResponse(response, merchantNumber, publicCert);
831831
action
832832
.Should().Throw<PaymentResponseException>()
833-
.WithMessage("Bad response");
833+
.WithMessage(@"Bad request:
834+
PR 1: Field too long.
835+
SR 0: ");
834836
}
835837

836838
[Fact]
@@ -888,8 +890,8 @@ public void
888890
Operation = "Operation",
889891
OrderNumber = 12332,
890892
MerOrderNumber = 0,
891-
PRCode = 0,
892-
SRCode = 3,
893+
PRCode = 28,
894+
SRCode = 3006,
893895
ResultText = "ResultText",
894896
UserParam1 = "UserParam1",
895897
AddInfo = null,
@@ -908,7 +910,9 @@ public void
908910
Action action = () => testee.ProcessGPWebPayResponse(response, merchantNumber, publicCert);
909911
action
910912
.Should().Throw<PaymentResponseException>()
911-
.WithMessage("Bad response");
913+
.WithMessage(@"Bad request:
914+
PR 28: Declined in 3D.
915+
SR 3006: Declined in 3D. Technical problem during Cardholder authentication.");
912916
}
913917

914918
private Mock<IEncodingService> GetEncodingServiceMock(string digest, bool validationResult)

0 commit comments

Comments
 (0)