Skip to content

Commit

Permalink
Merge pull request #1095 from alexander-olesiyuk-apaleo/1093-serializ…
Browse files Browse the repository at this point in the history
…ation-configuration

Explicitly configure ContractResolver for SaleToPOIMessage serialization
  • Loading branch information
Kwok-he-Chu authored Jan 2, 2025
2 parents 5eed0df + 8b2899f commit 901250b
Show file tree
Hide file tree
Showing 4 changed files with 169 additions and 15 deletions.
146 changes: 145 additions & 1 deletion Adyen.Test/SerializerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@
using Adyen.ApiSerialization;
using Adyen.Model.Checkout;
using Adyen.Model.TerminalApi;
using Adyen.Model.TerminalApi.Message;
using Adyen.Security;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using PaymentRequest = Adyen.Model.TerminalApi.PaymentRequest;
using PaymentResponse = Adyen.Model.TerminalApi.PaymentResponse;

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

[TestMethod]
public void SaleToPoiMessageSerializationTest()
{
var saleToPoiMessage = PosPaymentRequest;
var serialized = SerializeSaleToPoiMessage(saleToPoiMessage);
Assert.AreEqual(serialized, ExpectedSaleToPoiMessageJson);
}

[TestMethod]
public void SaleToPoiMessageWithUpdatedJsonConvertDefaultSettingsSerializationTest()
{
var saleToPoiMessage = PosPaymentRequest;

JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy()
}
};

try
{
var serialized = SerializeSaleToPoiMessage(saleToPoiMessage);

Assert.AreEqual(serialized, ExpectedSaleToPoiMessageJson);
}
finally
{
JsonConvert.DefaultSettings = null;
}
}

[TestMethod]
public void SaleToPoiMessageSecuredSerializationTest()
{
var saleToPoiMessage = PosPaymentRequest;
var serialized = SerializeSaleToPoiMessageSecured(saleToPoiMessage);
Assert.AreEqual(serialized, ExpectedSaleToPoiMessageSecuredJson);
}

[TestMethod]
public void SaleToPoiMessageSecuredWithUpdatedJsonConvertDefaultSettingsSerializationTest()
{
var saleToPoiMessage = PosPaymentRequest;

JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy()
}
};

try
{
var serialized = SerializeSaleToPoiMessageSecured(saleToPoiMessage);

Assert.AreEqual(serialized, ExpectedSaleToPoiMessageSecuredJson);
}
finally
{
JsonConvert.DefaultSettings = null;
}
}

private static string GetSaleToPoiMessage(string online)
{
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\"}}}";
}

private static string SerializeSaleToPoiMessage(SaleToPOIMessage saleToPoiMessage)
{
var saleToPoiMessageSerializer = new SaleToPoiMessageSerializer();
return saleToPoiMessageSerializer.Serialize(saleToPoiMessage);
}


private static string SerializeSaleToPoiMessageSecured(SaleToPOIMessage saleToPoiMessage)
{
var saleToPoiMessageSerializer = new SaleToPoiMessageSerializer();
var serializedSaleToPoiMessage = saleToPoiMessageSerializer.Serialize(saleToPoiMessage);

var encryptionCredentialDetails = new EncryptionCredentialDetails
{
AdyenCryptoVersion = 1,
KeyIdentifier = "CryptoKeyIdentifier12345",
Password = "p@ssw0rd123456"
};
var messageSecuredEncryptor = new SaleToPoiMessageSecuredEncryptor();
var saleToPoiMessageSecured = messageSecuredEncryptor.Encrypt(
serializedSaleToPoiMessage,
saleToPoiMessage.MessageHeader,
encryptionCredentialDetails);

// Clear SecurityTrailer.Nonce and NexoBlob as they are randomly generated every run
saleToPoiMessageSecured.NexoBlob = null;
saleToPoiMessageSecured.SecurityTrailer.Nonce = null;

return saleToPoiMessageSerializer.Serialize(saleToPoiMessageSecured);
}

private static SaleToPOIRequest PosPaymentRequest =>
new SaleToPOIRequest
{
MessageHeader = new MessageHeader
{
MessageType = MessageType.Request,
MessageClass = MessageClassType.Service,
MessageCategory = MessageCategoryType.Payment,
SaleID = "POSSystemID12345",
POIID = "MX915-284251016",
ServiceID = "12345678"
},
MessagePayload = new PaymentRequest
{
SaleData = new SaleData
{
SaleTransactionID = new TransactionIdentification
{
TransactionID = "PosAuth",
TimeStamp = new DateTime(2025, 1, 1)
},
TokenRequestedType = TokenRequestedType.Customer,
},
PaymentTransaction = new PaymentTransaction
{
AmountsReq = new AmountsReq
{
Currency = "EUR",
RequestedAmount = 10100
}
},
PaymentData = new PaymentData
{
PaymentType = PaymentType.Normal
}
}
};

private static string ExpectedSaleToPoiMessageJson =>
"{\"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\"}}}}";

private static string ExpectedSaleToPoiMessageSecuredJson =>
"{\"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=\"}}}";
}
}
34 changes: 24 additions & 10 deletions Adyen/ApiSerialization/Converter/JsonConvertSerializerWrapper.cs
Original file line number Diff line number Diff line change
@@ -1,29 +1,43 @@
using Adyen.Model.TerminalApi;
using System.Collections.Generic;
using Adyen.Model.TerminalApi;
using Adyen.Security;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;

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

private static readonly JsonSerializerSettings SaleToPoiMessageSerializerSettings = CreateSerializerSettings(new SaleToPoiMessageConverter());
private static readonly JsonSerializerSettings SaleToPoiMessageSecuredSerializerSettings = CreateSerializerSettings(new SaleToPoiMessageSecuredConverter());

internal static string Serialize(SaleToPOIMessage saleToPoiMessage)
{
var serialize= JsonConvert.SerializeObject(saleToPoiMessage,
new SaleToPoiMessageConverter(),
new StringEnumConverter(),
new IsoDateTimeConverter { DateTimeFormat = DateTimeFormat });
return serialize;
return JsonConvert.SerializeObject(saleToPoiMessage, SaleToPoiMessageSerializerSettings);
}

internal static string Serialize(SaleToPoiMessageSecured saleToPoiMessageSecured)
{
return JsonConvert.SerializeObject(saleToPoiMessageSecured,
new SaleToPoiMessageSecuredConverter(),
new StringEnumConverter(),
new IsoDateTimeConverter { DateTimeFormat = DateTimeFormat });
return JsonConvert.SerializeObject(saleToPoiMessageSecured, SaleToPoiMessageSecuredSerializerSettings);
}

private static JsonSerializerSettings CreateSerializerSettings(JsonConverter messageConverter)
{
return new JsonSerializerSettings
{
Converters = new List<JsonConverter>
{
messageConverter,
new StringEnumConverter(),
new IsoDateTimeConverter { DateTimeFormat = DateTimeFormat }
},
NullValueHandling = NullValueHandling.Ignore,
MissingMemberHandling = MissingMemberHandling.Ignore,
ContractResolver = new DefaultContractResolver()
};
}
}
}
2 changes: 0 additions & 2 deletions Adyen/ApiSerialization/Converter/SaleToPoiMessageConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ internal class SaleToPoiMessageConverter : JsonConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.NullValueHandling = NullValueHandling.Ignore;
serializer.MissingMemberHandling = MissingMemberHandling.Ignore;
writer.WriteStartObject();
writer.WritePropertyName(value.GetType().Name);
writer.WriteStartObject();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ internal class SaleToPoiMessageSecuredConverter : JsonConverter

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.NullValueHandling = NullValueHandling.Ignore;

writer.WriteStartObject();
writer.WritePropertyName(GetProperTypeNameForSerialization(value.GetType()));

Expand Down

0 comments on commit 901250b

Please sign in to comment.