Skip to content

Commit 901250b

Browse files
authored
Merge pull request #1095 from alexander-olesiyuk-apaleo/1093-serialization-configuration
Explicitly configure ContractResolver for SaleToPOIMessage serialization
2 parents 5eed0df + 8b2899f commit 901250b

File tree

4 files changed

+169
-15
lines changed

4 files changed

+169
-15
lines changed

Adyen.Test/SerializerTest.cs

Lines changed: 145 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,12 @@
44
using Adyen.ApiSerialization;
55
using Adyen.Model.Checkout;
66
using Adyen.Model.TerminalApi;
7+
using Adyen.Model.TerminalApi.Message;
8+
using Adyen.Security;
79
using Microsoft.VisualStudio.TestTools.UnitTesting;
810
using Newtonsoft.Json;
9-
using Newtonsoft.Json.Linq;
11+
using Newtonsoft.Json.Serialization;
12+
using PaymentRequest = Adyen.Model.TerminalApi.PaymentRequest;
1013
using PaymentResponse = Adyen.Model.TerminalApi.PaymentResponse;
1114

1215
namespace Adyen.Test
@@ -87,9 +90,150 @@ public void CheckoutSessionResponseCheckForIdTest()
8790
Assert.IsTrue(deserializedResponse.ToJson().Contains("\"id\": \"CS0068299CB8DA273A\","));
8891
}
8992

93+
[TestMethod]
94+
public void SaleToPoiMessageSerializationTest()
95+
{
96+
var saleToPoiMessage = PosPaymentRequest;
97+
var serialized = SerializeSaleToPoiMessage(saleToPoiMessage);
98+
Assert.AreEqual(serialized, ExpectedSaleToPoiMessageJson);
99+
}
100+
101+
[TestMethod]
102+
public void SaleToPoiMessageWithUpdatedJsonConvertDefaultSettingsSerializationTest()
103+
{
104+
var saleToPoiMessage = PosPaymentRequest;
105+
106+
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
107+
{
108+
ContractResolver = new DefaultContractResolver
109+
{
110+
NamingStrategy = new CamelCaseNamingStrategy()
111+
}
112+
};
113+
114+
try
115+
{
116+
var serialized = SerializeSaleToPoiMessage(saleToPoiMessage);
117+
118+
Assert.AreEqual(serialized, ExpectedSaleToPoiMessageJson);
119+
}
120+
finally
121+
{
122+
JsonConvert.DefaultSettings = null;
123+
}
124+
}
125+
126+
[TestMethod]
127+
public void SaleToPoiMessageSecuredSerializationTest()
128+
{
129+
var saleToPoiMessage = PosPaymentRequest;
130+
var serialized = SerializeSaleToPoiMessageSecured(saleToPoiMessage);
131+
Assert.AreEqual(serialized, ExpectedSaleToPoiMessageSecuredJson);
132+
}
133+
134+
[TestMethod]
135+
public void SaleToPoiMessageSecuredWithUpdatedJsonConvertDefaultSettingsSerializationTest()
136+
{
137+
var saleToPoiMessage = PosPaymentRequest;
138+
139+
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
140+
{
141+
ContractResolver = new DefaultContractResolver
142+
{
143+
NamingStrategy = new CamelCaseNamingStrategy()
144+
}
145+
};
146+
147+
try
148+
{
149+
var serialized = SerializeSaleToPoiMessageSecured(saleToPoiMessage);
150+
151+
Assert.AreEqual(serialized, ExpectedSaleToPoiMessageSecuredJson);
152+
}
153+
finally
154+
{
155+
JsonConvert.DefaultSettings = null;
156+
}
157+
}
158+
90159
private static string GetSaleToPoiMessage(string online)
91160
{
92161
return "{\"SaleToPOIResponse\": {\"PaymentResponse\": {\"POIData\": {},\"PaymentResult\": {\"AuthenticationMethod\": [\"" + online + "\"],\"PaymentAcquirerData\": {\"AcquirerPOIID\": \"MX925-260390740\",\"MerchantID\": \"PME_POS\"},\"PaymentType\": \"Normal\"},\"Response\": {\"Result\": \"Success\"}},\"MessageHeader\": {\"ProtocolVersion\": \"3.0\",\"SaleID\": \"Appie\",\"MessageClass\": \"Service\",\"MessageCategory\": \"Payment\",\"ServiceID\": \"20095135\",\"POIID\": \"MX925-260390740\",\"MessageType\": \"Response\"}}}";
93162
}
163+
164+
private static string SerializeSaleToPoiMessage(SaleToPOIMessage saleToPoiMessage)
165+
{
166+
var saleToPoiMessageSerializer = new SaleToPoiMessageSerializer();
167+
return saleToPoiMessageSerializer.Serialize(saleToPoiMessage);
168+
}
169+
170+
171+
private static string SerializeSaleToPoiMessageSecured(SaleToPOIMessage saleToPoiMessage)
172+
{
173+
var saleToPoiMessageSerializer = new SaleToPoiMessageSerializer();
174+
var serializedSaleToPoiMessage = saleToPoiMessageSerializer.Serialize(saleToPoiMessage);
175+
176+
var encryptionCredentialDetails = new EncryptionCredentialDetails
177+
{
178+
AdyenCryptoVersion = 1,
179+
KeyIdentifier = "CryptoKeyIdentifier12345",
180+
Password = "p@ssw0rd123456"
181+
};
182+
var messageSecuredEncryptor = new SaleToPoiMessageSecuredEncryptor();
183+
var saleToPoiMessageSecured = messageSecuredEncryptor.Encrypt(
184+
serializedSaleToPoiMessage,
185+
saleToPoiMessage.MessageHeader,
186+
encryptionCredentialDetails);
187+
188+
// Clear SecurityTrailer.Nonce and NexoBlob as they are randomly generated every run
189+
saleToPoiMessageSecured.NexoBlob = null;
190+
saleToPoiMessageSecured.SecurityTrailer.Nonce = null;
191+
192+
return saleToPoiMessageSerializer.Serialize(saleToPoiMessageSecured);
193+
}
194+
195+
private static SaleToPOIRequest PosPaymentRequest =>
196+
new SaleToPOIRequest
197+
{
198+
MessageHeader = new MessageHeader
199+
{
200+
MessageType = MessageType.Request,
201+
MessageClass = MessageClassType.Service,
202+
MessageCategory = MessageCategoryType.Payment,
203+
SaleID = "POSSystemID12345",
204+
POIID = "MX915-284251016",
205+
ServiceID = "12345678"
206+
},
207+
MessagePayload = new PaymentRequest
208+
{
209+
SaleData = new SaleData
210+
{
211+
SaleTransactionID = new TransactionIdentification
212+
{
213+
TransactionID = "PosAuth",
214+
TimeStamp = new DateTime(2025, 1, 1)
215+
},
216+
TokenRequestedType = TokenRequestedType.Customer,
217+
},
218+
PaymentTransaction = new PaymentTransaction
219+
{
220+
AmountsReq = new AmountsReq
221+
{
222+
Currency = "EUR",
223+
RequestedAmount = 10100
224+
}
225+
},
226+
PaymentData = new PaymentData
227+
{
228+
PaymentType = PaymentType.Normal
229+
}
230+
}
231+
};
232+
233+
private static string ExpectedSaleToPoiMessageJson =>
234+
"{\"SaleToPOIRequest\":{\"MessageHeader\":{\"MessageClass\":\"Service\",\"MessageCategory\":\"Payment\",\"MessageType\":\"Request\",\"ServiceID\":\"12345678\",\"SaleID\":\"POSSystemID12345\",\"POIID\":\"MX915-284251016\",\"ProtocolVersion\":\"3.0\"},\"PaymentRequest\":{\"SaleData\":{\"SaleTransactionID\":{\"TransactionID\":\"PosAuth\",\"TimeStamp\":\"2025-01-01T00:00:00\"},\"SaleToAcquirerData\":\"eyJhcHBsaWNhdGlvbkluZm8iOnsiYWR5ZW5MaWJyYXJ5Ijp7Im5hbWUiOiJhZHllbi1kb3RuZXQtYXBpLWxpYnJhcnkiLCJ2ZXJzaW9uIjoiMjYuMC4wIn19fQ==\",\"TokenRequestedType\":\"Customer\"},\"PaymentTransaction\":{\"AmountsReq\":{\"Currency\":\"EUR\",\"RequestedAmount\":10100.0}},\"PaymentData\":{\"PaymentType\":\"Normal\"}}}}";
235+
236+
private static string ExpectedSaleToPoiMessageSecuredJson =>
237+
"{\"SaleToPOIRequest\":{\"MessageHeader\":{\"MessageClass\":\"Service\",\"MessageCategory\":\"Payment\",\"MessageType\":\"Request\",\"ServiceID\":\"12345678\",\"SaleID\":\"POSSystemID12345\",\"POIID\":\"MX915-284251016\",\"ProtocolVersion\":\"3.0\"},\"NexoBlob\":null,\"SecurityTrailer\":{\"AdyenCryptoVersion\":1,\"KeyIdentifier\":\"CryptoKeyIdentifier12345\",\"KeyVersion\":0,\"Hmac\":\"0lPogF5Mg97Nty9ZUuAnb3v8pvZTZvwouxdMp0HV+yQ=\"}}}";
94238
}
95239
}
Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,43 @@
1-
using Adyen.Model.TerminalApi;
1+
using System.Collections.Generic;
2+
using Adyen.Model.TerminalApi;
23
using Adyen.Security;
34
using Newtonsoft.Json;
45
using Newtonsoft.Json.Converters;
6+
using Newtonsoft.Json.Serialization;
57

68
namespace Adyen.ApiSerialization.Converter
79
{
810
internal class JsonConvertSerializerWrapper
911
{
1012
private const string DateTimeFormat = "yyyy-MM-ddTHH\\:mm\\:ss";
1113

14+
private static readonly JsonSerializerSettings SaleToPoiMessageSerializerSettings = CreateSerializerSettings(new SaleToPoiMessageConverter());
15+
private static readonly JsonSerializerSettings SaleToPoiMessageSecuredSerializerSettings = CreateSerializerSettings(new SaleToPoiMessageSecuredConverter());
16+
1217
internal static string Serialize(SaleToPOIMessage saleToPoiMessage)
1318
{
14-
var serialize= JsonConvert.SerializeObject(saleToPoiMessage,
15-
new SaleToPoiMessageConverter(),
16-
new StringEnumConverter(),
17-
new IsoDateTimeConverter { DateTimeFormat = DateTimeFormat });
18-
return serialize;
19+
return JsonConvert.SerializeObject(saleToPoiMessage, SaleToPoiMessageSerializerSettings);
1920
}
2021

2122
internal static string Serialize(SaleToPoiMessageSecured saleToPoiMessageSecured)
2223
{
23-
return JsonConvert.SerializeObject(saleToPoiMessageSecured,
24-
new SaleToPoiMessageSecuredConverter(),
25-
new StringEnumConverter(),
26-
new IsoDateTimeConverter { DateTimeFormat = DateTimeFormat });
24+
return JsonConvert.SerializeObject(saleToPoiMessageSecured, SaleToPoiMessageSecuredSerializerSettings);
25+
}
26+
27+
private static JsonSerializerSettings CreateSerializerSettings(JsonConverter messageConverter)
28+
{
29+
return new JsonSerializerSettings
30+
{
31+
Converters = new List<JsonConverter>
32+
{
33+
messageConverter,
34+
new StringEnumConverter(),
35+
new IsoDateTimeConverter { DateTimeFormat = DateTimeFormat }
36+
},
37+
NullValueHandling = NullValueHandling.Ignore,
38+
MissingMemberHandling = MissingMemberHandling.Ignore,
39+
ContractResolver = new DefaultContractResolver()
40+
};
2741
}
2842
}
2943
}

Adyen/ApiSerialization/Converter/SaleToPoiMessageConverter.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ internal class SaleToPoiMessageConverter : JsonConverter
88
{
99
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
1010
{
11-
serializer.NullValueHandling = NullValueHandling.Ignore;
12-
serializer.MissingMemberHandling = MissingMemberHandling.Ignore;
1311
writer.WriteStartObject();
1412
writer.WritePropertyName(value.GetType().Name);
1513
writer.WriteStartObject();

Adyen/ApiSerialization/Converter/SaleToPoiMessageSecuredConverter.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ internal class SaleToPoiMessageSecuredConverter : JsonConverter
1414

1515
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
1616
{
17-
serializer.NullValueHandling = NullValueHandling.Ignore;
18-
1917
writer.WriteStartObject();
2018
writer.WritePropertyName(GetProperTypeNameForSerialization(value.GetType()));
2119

0 commit comments

Comments
 (0)