From e08b849a3e6fa678510530d040a5b4853896caae Mon Sep 17 00:00:00 2001 From: alexandros Date: Sun, 23 Dec 2018 12:19:57 +0100 Subject: [PATCH 1/5] deserialize payload for RepeatedresponseMessageBody --- .../CloudApiPosRequestTest.cs | 52 ++++++++- .../pospayment-cancelled.json | 0 .../pospayment-encrypted-success.json | 0 .../{ => terminalapi}/pospayment-success.json | 0 ...ospayment-transaction-status-response.json | 91 ++++++++++++++++ .../TerminalApiPosRequestTest.cs | 2 +- Adyen.EcommLibrary/Adyen.EcommLibrary.csproj | 2 +- .../SaleToPoiMessageSecuredConverter.cs | 2 +- .../MessagePayloadSerializer.cs | 3 + .../MessagePayloadSerializerFactory.cs | 1 + .../SaleToPoiMessageSerializer.cs | 100 ++++++++++-------- .../Model/Nexo/MessageHeader.cs | 1 - .../Model/Nexo/PaymentResponse.cs | 2 +- .../Model/Nexo/RepeatedMessageResponse.cs | 19 ++-- .../Model/Nexo/RepeatedResponseMessageBody.cs | 24 +++++ .../Model/Nexo/SaleToPOIResponse.cs | 2 +- .../Model/Nexo/TransactionStatusResponse.cs | 1 - .../Service/PosPaymentCloudApi.cs | 2 +- .../Service/PosPaymentLocalApi.cs | 2 +- 19 files changed, 240 insertions(+), 66 deletions(-) rename Adyen.EcommLibrary.Test/Mocks/{ => terminalapi}/pospayment-cancelled.json (100%) rename Adyen.EcommLibrary.Test/Mocks/{ => terminalapi}/pospayment-encrypted-success.json (100%) rename Adyen.EcommLibrary.Test/Mocks/{ => terminalapi}/pospayment-success.json (100%) create mode 100644 Adyen.EcommLibrary.Test/Mocks/terminalapi/pospayment-transaction-status-response.json create mode 100644 Adyen.EcommLibrary/Model/Nexo/RepeatedResponseMessageBody.cs diff --git a/Adyen.EcommLibrary.Test/CloudApiPosRequestTest.cs b/Adyen.EcommLibrary.Test/CloudApiPosRequestTest.cs index 72bfbe69e..8134e3282 100644 --- a/Adyen.EcommLibrary.Test/CloudApiPosRequestTest.cs +++ b/Adyen.EcommLibrary.Test/CloudApiPosRequestTest.cs @@ -1,4 +1,5 @@ -using Adyen.EcommLibrary.Service; +using Adyen.EcommLibrary.Model.Nexo; +using Adyen.EcommLibrary.Service; using Microsoft.VisualStudio.TestTools.UnitTesting; using System; @@ -9,13 +10,32 @@ public class CloudApiPosRequestTest : BaseTest { [TestMethod] - public void TestCloudApiRequest() + public void TestCloudApiSyncRequest() { try { //Create a mock pos payment request var paymentRequest = MockPosApiRequest.CreatePosPaymentRequest("Request"); - var client = CreateMockTestClientPosApiRequest("Mocks/pospayment-success.json"); + var client = CreateMockTestClientPosApiRequest("Mocks/terminalapi/pospayment-success.json"); + var payment = new PosPaymentCloudApi(client); + var saleToPoiResponse = payment.TerminalApiCloudSync(paymentRequest); + + Assert.IsNotNull(saleToPoiResponse); + } + catch (Exception) + { + Assert.Fail(); + } + } + + [TestMethod] + public void TestCloudApiAsyncRequest() + { + try + { + //Create a mock pos payment request + var paymentRequest = MockPosApiRequest.CreatePosPaymentRequest("Request"); + var client = CreateMockTestClientPosApiRequest("Mocks/terminalapi/pospayment-success.json"); var payment = new PosPaymentCloudApi(client); var saleToPoiResponse = payment.TerminalApiCloudAsync(paymentRequest); @@ -26,5 +46,31 @@ public void TestCloudApiRequest() Assert.Fail(); } } + + [TestMethod] + public void TestCloudApiTransactionStatusResponseSuccess() + { + var paymentRequest = MockPosApiRequest.CreatePosPaymentRequest("Request"); + var client = CreateMockTestClientPosApiRequest("Mocks/terminalapi/pospayment-transaction-status-response.json"); + var payment = new PosPaymentCloudApi(client); + var saleToPoiResponse = payment.TerminalApiCloudSync(paymentRequest); + + try + { + var transactionStatusResponse = (TransactionStatusResponse)saleToPoiResponse.MessagePayload; + var paymentResponse = (PaymentResponse)transactionStatusResponse.RepeatedMessageResponse.RepeatedResponseMessageBody.MessagePayload; + + Assert.IsNotNull(saleToPoiResponse); + Assert.AreEqual(saleToPoiResponse.MessageHeader.ServiceID, "35543420"); + Assert.AreEqual(saleToPoiResponse.MessageHeader.SaleID, "TOSIM_1_1_6"); + Assert.AreEqual(saleToPoiResponse.MessageHeader.POIID, "P400Plus-12345678"); + Assert.AreEqual(transactionStatusResponse.Response.Result, "Success"); + Assert.AreEqual(paymentResponse.PaymentResult.PaymentInstrumentData.CardData.EntryMode[0], "ICC"); + } + catch (Exception) + { + Assert.Fail(); + } + } } } diff --git a/Adyen.EcommLibrary.Test/Mocks/pospayment-cancelled.json b/Adyen.EcommLibrary.Test/Mocks/terminalapi/pospayment-cancelled.json similarity index 100% rename from Adyen.EcommLibrary.Test/Mocks/pospayment-cancelled.json rename to Adyen.EcommLibrary.Test/Mocks/terminalapi/pospayment-cancelled.json diff --git a/Adyen.EcommLibrary.Test/Mocks/pospayment-encrypted-success.json b/Adyen.EcommLibrary.Test/Mocks/terminalapi/pospayment-encrypted-success.json similarity index 100% rename from Adyen.EcommLibrary.Test/Mocks/pospayment-encrypted-success.json rename to Adyen.EcommLibrary.Test/Mocks/terminalapi/pospayment-encrypted-success.json diff --git a/Adyen.EcommLibrary.Test/Mocks/pospayment-success.json b/Adyen.EcommLibrary.Test/Mocks/terminalapi/pospayment-success.json similarity index 100% rename from Adyen.EcommLibrary.Test/Mocks/pospayment-success.json rename to Adyen.EcommLibrary.Test/Mocks/terminalapi/pospayment-success.json diff --git a/Adyen.EcommLibrary.Test/Mocks/terminalapi/pospayment-transaction-status-response.json b/Adyen.EcommLibrary.Test/Mocks/terminalapi/pospayment-transaction-status-response.json new file mode 100644 index 000000000..b33d5728b --- /dev/null +++ b/Adyen.EcommLibrary.Test/Mocks/terminalapi/pospayment-transaction-status-response.json @@ -0,0 +1,91 @@ +{ + "SaleToPOIResponse" : { + "MessageHeader" : { + "MessageCategory" : "TransactionStatus", + "ServiceID" : "35543420", + "MessageType" : "Response", + "SaleID" : "TOSIM_1_1_6", + "POIID" : "P400Plus-12345678", + "ProtocolVersion" : "3.0", + "MessageClass" : "Service" + }, + "TransactionStatusResponse" : { + "Response" : { + "Result" : "Success" + }, + "MessageReference" : { + "SaleID" : "TOSIM_1_100_6", + "ServiceID" : "05140342", + "MessageCategory" : "Payment" + }, + + "RepeatedMessageResponse" : { + "RepeatedResponseMessageBody" : { + "PaymentResponse" : { + "PaymentResult" : { + "PaymentInstrumentData" : { + "PaymentInstrumentType" : "Card", + "CardData" : { + "EntryMode" : [ + "ICC" + ], + "PaymentBrand" : "mc", + "SensitiveCardData" : { + "ExpiryDate" : "0228", + "CardSeqNumb" : "53" + }, + "CardCountryCode" : "056", + "MaskedPan" : "679999 **** 9990" + } + }, + "AuthenticationMethod" : [ + "SignatureCapture" + ], + "PaymentAcquirerData" : { + "AcquirerPOIID" : "P400Plus-275102737", + "MerchantID" : "EG_Adyen_test", + "AcquirerTransactionID" : { + "TimeStamp" : "2018-12-05T13:03:47.000Z", + "TransactionID" : "8815440150351036" + } + }, + "OnlineFlag" : true, + "PaymentType" : "Normal", + "AmountsResp" : { + "AuthorizedAmount" : 79, + "Currency" : "EUR" + }, + "MerchantOverrideFlag" : false + }, + "SaleData" : { + "SaleTransactionID" : { + "TransactionID" : "0000060001078117", + "TimeStamp" : "2018-12-05T14:03:42.000Z" + } + }, + "Response" : { + "Result" : "Success", + "AdditionalResponse" : "tid=75102737&AID=A000000004306001&transactionType=GOODS_SERVICES&backendGiftcardIndicator=false&giftcardIndicator=false&pspReference=8815440150351036&cardHolderName=TC03_MS_Approved&paymentMethodVariant=maestro&applicationPreferredName=ms%20en&offline=false&tc=9011DDEE7EA21173&mid=1000&cardHolderVerificationMethodResults=1E0000" + }, + "POIData" : { + "POITransactionID" : { + "TimeStamp" : "2018-12-05T13:03:47.000Z", + "TransactionID" : "57eT001544015027011.8815440150351036" + }, + "POIReconciliationID" : "1000" + } + } + }, + "MessageHeader" : { + "POIID" : "P400Plus-12345678", + "ProtocolVersion" : "3.0", + "MessageClass" : "Service", + "MessageCategory" : "Payment", + "ServiceID" : "35543420", + "MessageType" : "Response", + "SaleID" : "TOSIM_1_1_6" + } + } + } + } +} diff --git a/Adyen.EcommLibrary.Test/TerminalApiPosRequestTest.cs b/Adyen.EcommLibrary.Test/TerminalApiPosRequestTest.cs index 39461dded..fcf57978d 100644 --- a/Adyen.EcommLibrary.Test/TerminalApiPosRequestTest.cs +++ b/Adyen.EcommLibrary.Test/TerminalApiPosRequestTest.cs @@ -30,7 +30,7 @@ public void TestTerminalApiRequest() //encrypt the request using encryption credentials var paymentRequest = MockPosApiRequest.CreatePosPaymentRequest("Request"); //create a mock client - var client = CreateMockTestClientPosApiRequest("Mocks/pospayment-encrypted-success.json"); + var client = CreateMockTestClientPosApiRequest("Mocks/terminalapi/pospayment-encrypted-success.json"); var payment = new PosPaymentLocalApi(client); var configEndpoint = payment.Client.Config.Endpoint; var saleToPoiResponse = payment.TerminalApiLocal(paymentRequest, _encryptionCredentialDetails); diff --git a/Adyen.EcommLibrary/Adyen.EcommLibrary.csproj b/Adyen.EcommLibrary/Adyen.EcommLibrary.csproj index 607b292e7..ccc589062 100644 --- a/Adyen.EcommLibrary/Adyen.EcommLibrary.csproj +++ b/Adyen.EcommLibrary/Adyen.EcommLibrary.csproj @@ -25,7 +25,7 @@ - + diff --git a/Adyen.EcommLibrary/CloudApiSerialization/Converter/SaleToPoiMessageSecuredConverter.cs b/Adyen.EcommLibrary/CloudApiSerialization/Converter/SaleToPoiMessageSecuredConverter.cs index ca7463a4c..78fad7410 100644 --- a/Adyen.EcommLibrary/CloudApiSerialization/Converter/SaleToPoiMessageSecuredConverter.cs +++ b/Adyen.EcommLibrary/CloudApiSerialization/Converter/SaleToPoiMessageSecuredConverter.cs @@ -44,7 +44,7 @@ private string GetProperTypeNameForSerialization(Type type) return SaleToPoiRequestSecuredForSerialization; } - if (type == typeof(SaleToPOIResponse) || type == typeof(SaleToPoiResponseSecured)) + if (type == typeof(SaleToPoiResponse) || type == typeof(SaleToPoiResponseSecured)) { return SaleToPoiResponseSecuredForSerialization; } diff --git a/Adyen.EcommLibrary/CloudApiSerialization/MessagePayloadSerializer.cs b/Adyen.EcommLibrary/CloudApiSerialization/MessagePayloadSerializer.cs index f78619ec4..ac3bd406e 100644 --- a/Adyen.EcommLibrary/CloudApiSerialization/MessagePayloadSerializer.cs +++ b/Adyen.EcommLibrary/CloudApiSerialization/MessagePayloadSerializer.cs @@ -1,4 +1,6 @@ using Adyen.EcommLibrary.Model.Nexo; +using Newtonsoft.Json.Linq; +using System; namespace Adyen.EcommLibrary.CloudApiSerialization { @@ -8,5 +10,6 @@ public IMessagePayload Deserialize(string messagePayloadJson) { return Converter.JSonConvertDeserializerWrapper.DeserializeObject(messagePayloadJson); } + } } diff --git a/Adyen.EcommLibrary/CloudApiSerialization/MessagePayloadSerializerFactory.cs b/Adyen.EcommLibrary/CloudApiSerialization/MessagePayloadSerializerFactory.cs index 5efa7746b..f6ef94b95 100644 --- a/Adyen.EcommLibrary/CloudApiSerialization/MessagePayloadSerializerFactory.cs +++ b/Adyen.EcommLibrary/CloudApiSerialization/MessagePayloadSerializerFactory.cs @@ -9,6 +9,7 @@ internal class MessagePayloadSerializerFactory internal IMessagePayloadSerializer CreateSerializer(string messageCategory, string messageType) { var messagePayoadFullName = CreateMessagePayloadFullName(messageCategory, messageType); + var messagePayloadSerializer = TypeHelper.CreateGenericTypeFromStringFullNamespace(typeof(MessagePayloadSerializer<>), messagePayoadFullName); return (IMessagePayloadSerializer)Activator.CreateInstance(messagePayloadSerializer); diff --git a/Adyen.EcommLibrary/CloudApiSerialization/SaleToPoiMessageSerializer.cs b/Adyen.EcommLibrary/CloudApiSerialization/SaleToPoiMessageSerializer.cs index de533f382..580eb96e5 100644 --- a/Adyen.EcommLibrary/CloudApiSerialization/SaleToPoiMessageSerializer.cs +++ b/Adyen.EcommLibrary/CloudApiSerialization/SaleToPoiMessageSerializer.cs @@ -1,9 +1,9 @@ using System; -using System.Collections.Generic; +using System.Linq; using Adyen.EcommLibrary.Model.Nexo; using Adyen.EcommLibrary.Security; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; -using Adyen.EcommLibrary.Model.Nexo.Message; namespace Adyen.EcommLibrary.CloudApiSerialization { @@ -17,34 +17,35 @@ public SaleToPoiMessageSerializer() _messageHeaderSerializer = new MessageHeaderSerializer(); _messagePayloadSerializerFactory = new MessagePayloadSerializerFactory(); } - - public SaleToPOIResponse Deserialize(string saleToPoiMessageDto) + public SaleToPoiResponse Deserialize(string saleToPoiMessageDto) { - try + //todo temporary solution until we have an improved response + if (string.Equals("ok", saleToPoiMessageDto)) { - //todo temporary solution until we have an improved response - if (string.Equals("ok", saleToPoiMessageDto)) - { - return null; - } - var saleToPoiMessageJObject = JObject.Parse(saleToPoiMessageDto); - var saleToPoiMessageRootJToken = saleToPoiMessageJObject.First; - var saleToPoiMessageWithoutRootJToken = saleToPoiMessageRootJToken.First; - var messageHeader = DeserializeMessageHeader(saleToPoiMessageWithoutRootJToken); + return null; + } + var saleToPoiMessageJObject = JObject.Parse(saleToPoiMessageDto); + var saleToPoiMessageRootJToken = saleToPoiMessageJObject.First; + var saleToPoiMessageWithoutRootJToken = saleToPoiMessageRootJToken.First; + //Messageheader + var messageHeader = DeserializeMessageHeader(saleToPoiMessageWithoutRootJToken); + //Message payload + object messagePayload = DeserializeMessagePayload(messageHeader, saleToPoiMessageWithoutRootJToken); - var messagePayload = DeserializeMessagePayload(messageHeader, saleToPoiMessageWithoutRootJToken); - var deserializedOutputMessage = new SaleToPOIResponse - { - MessageHeader = messageHeader, - MessagePayload = messagePayload - }; + var deserializedOutputMessage = new SaleToPoiResponse + { + MessageHeader = messageHeader, + MessagePayload = messagePayload + }; - return deserializedOutputMessage; - } - catch (Exception exception) + //Check and deserialize RepeatedMessageResponse + if (saleToPoiMessageDto.Contains("RepeatedMessageResponse") && saleToPoiMessageDto.Contains("RepeatedResponseMessageBody")) { - throw exception; + var response = GetDeserializedRepeatedResponseMessagePayload(saleToPoiMessageWithoutRootJToken); + var deserializedOutput = (TransactionStatusResponse)deserializedOutputMessage.MessagePayload; + deserializedOutput.RepeatedMessageResponse.RepeatedResponseMessageBody.MessagePayload = response; } + return deserializedOutputMessage; } private object DeserializeMessagePayload(MessageHeader messageHeader, JToken saleToPoiMessageWithoutRootJToken) @@ -57,10 +58,19 @@ private object DeserializeMessagePayload(MessageHeader messageHeader, JToken sal return messagePayloadSerializer.Deserialize(messagePayloadJson); } + public string Serialize(SaleToPOIMessage saleToPoiMessage) + { + return Converter.JSonConvertSerializerWrapper.Serialize(saleToPoiMessage); + } + + public string Serialize(SaleToPoiMessageSecured saleToPoiMessage) + { + return Converter.JSonConvertSerializerWrapper.Serialize(saleToPoiMessage); + } + private string GetMessagePayloadJSon(JToken saleToPoiMessageWithoutRootJToken, string messageCategory, string messageType) { var messagePayloadTypedJson = saleToPoiMessageWithoutRootJToken.SelectToken(messageCategory + messageType.ToString()); - if (messagePayloadTypedJson == null) { return saleToPoiMessageWithoutRootJToken.SelectToken("MessagePayload").ToString(); @@ -70,34 +80,40 @@ private string GetMessagePayloadJSon(JToken saleToPoiMessageWithoutRootJToken, s private MessageHeader DeserializeMessageHeader(JToken saleToPoiMessageWithoutRootJObject) { var messageHeaderJson = saleToPoiMessageWithoutRootJObject.SelectToken("MessageHeader").ToString(); - var messageHeader = _messageHeaderSerializer.Deserialize(messageHeaderJson); - - return messageHeader; + return _messageHeaderSerializer.Deserialize(messageHeaderJson); } - public string Serialize(SaleToPOIMessage saleToPoiMessage) + private object GetDeserializedRepeatedResponseMessagePayload(JToken saletoPoiMessageJtoken) { - try + var repeatedMessageResponse = saletoPoiMessageJtoken.ToString(); + var repeatedMessage = saletoPoiMessageJtoken["TransactionStatusResponse"]["RepeatedMessageResponse"]["RepeatedResponseMessageBody"].ToString(); + var objMessage = JObject.Parse(repeatedMessage); + + if (repeatedMessageResponse.Contains("CardAcquisitionResponse")) { - return Converter.JSonConvertSerializerWrapper.Serialize(saleToPoiMessage); + return objMessage[repeatedMessageResponse].ToObject(); } - catch (Exception e) + if (repeatedMessageResponse.Contains("CardReaderAPDUResponse")) { - throw e; + return objMessage[repeatedMessageResponse].ToObject(); } - } - - public string Serialize(SaleToPoiMessageSecured saleToPoiMessage) - { - try + if (repeatedMessageResponse.Contains("LoyaltyResponse")) + { + return objMessage[repeatedMessageResponse].ToObject(); + } + if (repeatedMessageResponse.Contains("PaymentResponse")) { - return Converter.JSonConvertSerializerWrapper.Serialize(saleToPoiMessage); + return objMessage["PaymentResponse"].ToObject(); } - catch (Exception e) + if (repeatedMessageResponse.Contains("ReversalResponse")) { - throw e; + return objMessage[repeatedMessageResponse].ToObject(); } + if (repeatedMessageResponse.Contains("StoredValueResponse")) + { + return objMessage[repeatedMessageResponse].ToObject(); + } + return null; } - } } diff --git a/Adyen.EcommLibrary/Model/Nexo/MessageHeader.cs b/Adyen.EcommLibrary/Model/Nexo/MessageHeader.cs index 2bf04906d..5e623a8f0 100644 --- a/Adyen.EcommLibrary/Model/Nexo/MessageHeader.cs +++ b/Adyen.EcommLibrary/Model/Nexo/MessageHeader.cs @@ -7,7 +7,6 @@ [System.ComponentModel.DesignerCategoryAttribute("code")] public partial class MessageHeader { - /// [System.Xml.Serialization.XmlAttributeAttribute()] public string ProtocolVersion; diff --git a/Adyen.EcommLibrary/Model/Nexo/PaymentResponse.cs b/Adyen.EcommLibrary/Model/Nexo/PaymentResponse.cs index 5364d2f57..ede69293b 100644 --- a/Adyen.EcommLibrary/Model/Nexo/PaymentResponse.cs +++ b/Adyen.EcommLibrary/Model/Nexo/PaymentResponse.cs @@ -7,7 +7,7 @@ namespace Adyen.EcommLibrary.Model.Nexo [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] - public partial class PaymentResponse : IMessagePayload + public partial class PaymentResponse :IMessagePayload { /// diff --git a/Adyen.EcommLibrary/Model/Nexo/RepeatedMessageResponse.cs b/Adyen.EcommLibrary/Model/Nexo/RepeatedMessageResponse.cs index 440841aaa..5477b1be4 100644 --- a/Adyen.EcommLibrary/Model/Nexo/RepeatedMessageResponse.cs +++ b/Adyen.EcommLibrary/Model/Nexo/RepeatedMessageResponse.cs @@ -1,24 +1,19 @@ -namespace Adyen.EcommLibrary.Model.Nexo +using Adyen.EcommLibrary.CloudApiSerialization; + +namespace Adyen.EcommLibrary.Model.Nexo { /// [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")] [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] - public partial class RepeatedMessageResponse - { + public partial class RepeatedMessageResponse : IMessagePayload + { /// + [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] + public RepeatedResponseMessageBody RepeatedResponseMessageBody; /// [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public MessageHeader MessageHeader; - - /// - [System.Xml.Serialization.XmlElementAttribute("CardAcquisitionResponse", typeof(CardAcquisitionResponse), Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] - [System.Xml.Serialization.XmlElementAttribute("CardReaderAPDUResponse", typeof(CardReaderAPDUResponse), Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] - [System.Xml.Serialization.XmlElementAttribute("LoyaltyResponse", typeof(LoyaltyResponse), Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] - [System.Xml.Serialization.XmlElementAttribute("PaymentResponse", typeof(PaymentResponse), Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] - [System.Xml.Serialization.XmlElementAttribute("ReversalResponse", typeof(ReversalResponse), Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] - [System.Xml.Serialization.XmlElementAttribute("StoredValueResponse", typeof(StoredValueResponse), Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] - public object Item; } } \ No newline at end of file diff --git a/Adyen.EcommLibrary/Model/Nexo/RepeatedResponseMessageBody.cs b/Adyen.EcommLibrary/Model/Nexo/RepeatedResponseMessageBody.cs new file mode 100644 index 000000000..b13ab5d96 --- /dev/null +++ b/Adyen.EcommLibrary/Model/Nexo/RepeatedResponseMessageBody.cs @@ -0,0 +1,24 @@ +using Adyen.EcommLibrary.CloudApiSerialization; +using Newtonsoft.Json; +using System.Runtime.Serialization; + +namespace Adyen.EcommLibrary.Model.Nexo +{ + /// + [System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")] + [System.SerializableAttribute()] + [System.Diagnostics.DebuggerStepThroughAttribute()] + [System.ComponentModel.DesignerCategoryAttribute("code")] + [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] + [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)] + public partial class RepeatedResponseMessageBody :IMessagePayload + { + [System.Xml.Serialization.XmlElementAttribute("CardAcquisitionResponse", typeof(CardAcquisitionResponse), Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] + [System.Xml.Serialization.XmlElementAttribute("CardReaderAPDUResponse", typeof(CardReaderAPDUResponse), Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] + [System.Xml.Serialization.XmlElementAttribute("LoyaltyResponse", typeof(LoyaltyResponse), Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] + [System.Xml.Serialization.XmlElementAttribute("PaymentResponse", typeof(PaymentResponse), Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] + [System.Xml.Serialization.XmlElementAttribute("ReversalResponse", typeof(ReversalResponse), Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] + [System.Xml.Serialization.XmlElementAttribute("StoredValueResponse", typeof(StoredValueResponse), Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] + public object MessagePayload; + } +} \ No newline at end of file diff --git a/Adyen.EcommLibrary/Model/Nexo/SaleToPOIResponse.cs b/Adyen.EcommLibrary/Model/Nexo/SaleToPOIResponse.cs index 6271e3e9b..4f04906b6 100644 --- a/Adyen.EcommLibrary/Model/Nexo/SaleToPOIResponse.cs +++ b/Adyen.EcommLibrary/Model/Nexo/SaleToPOIResponse.cs @@ -7,7 +7,7 @@ [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)] - public partial class SaleToPOIResponse + public partial class SaleToPoiResponse { /// diff --git a/Adyen.EcommLibrary/Model/Nexo/TransactionStatusResponse.cs b/Adyen.EcommLibrary/Model/Nexo/TransactionStatusResponse.cs index 32d12f964..92adeb919 100644 --- a/Adyen.EcommLibrary/Model/Nexo/TransactionStatusResponse.cs +++ b/Adyen.EcommLibrary/Model/Nexo/TransactionStatusResponse.cs @@ -9,7 +9,6 @@ namespace Adyen.EcommLibrary.Model.Nexo [System.ComponentModel.DesignerCategoryAttribute("code")] public partial class TransactionStatusResponse : IMessagePayload { - /// [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] public Response Response; diff --git a/Adyen.EcommLibrary/Service/PosPaymentCloudApi.cs b/Adyen.EcommLibrary/Service/PosPaymentCloudApi.cs index dad3dcad4..e2e7a02be 100644 --- a/Adyen.EcommLibrary/Service/PosPaymentCloudApi.cs +++ b/Adyen.EcommLibrary/Service/PosPaymentCloudApi.cs @@ -38,7 +38,7 @@ public string TerminalApiCloudAsync(SaleToPOIMessage saleToPoiRequest) /// /// /// - public SaleToPOIResponse TerminalApiCloudSync(SaleToPOIMessage saleToPoiRequest) + public SaleToPoiResponse TerminalApiCloudSync(SaleToPOIMessage saleToPoiRequest) { var serializedMessage = _saleToPoiMessageSerializer.Serialize(saleToPoiRequest); this.Client.LogLine("Request: \n"+ serializedMessage); diff --git a/Adyen.EcommLibrary/Service/PosPaymentLocalApi.cs b/Adyen.EcommLibrary/Service/PosPaymentLocalApi.cs index 4bfc8e59a..16798e87e 100644 --- a/Adyen.EcommLibrary/Service/PosPaymentLocalApi.cs +++ b/Adyen.EcommLibrary/Service/PosPaymentLocalApi.cs @@ -29,7 +29,7 @@ public PosPaymentLocalApi(Client client) /// /// /// - public SaleToPOIResponse TerminalApiLocal(SaleToPOIMessage saleToPoiRequest, EncryptionCredentialDetails encryptionCredentialDetails) + public SaleToPoiResponse TerminalApiLocal(SaleToPOIMessage saleToPoiRequest, EncryptionCredentialDetails encryptionCredentialDetails) { var saleToPoiRequestMessageSerialized = _saleToPoiMessageSerializer.Serialize(saleToPoiRequest); this.Client.LogLine("Request: \n" + saleToPoiRequestMessageSerialized); From e9562fd3bac69581c1c9fad3b0c68ff0e87dd2a5 Mon Sep 17 00:00:00 2001 From: alexandros Date: Sun, 23 Dec 2018 12:32:00 +0100 Subject: [PATCH 2/5] Small refactor --- Adyen.EcommLibrary/Adyen.EcommLibrary.csproj | 2 +- .../Converter/SaleToPoiMessageSecuredConverter.cs | 2 +- .../MessagePayloadSerializerFactory.cs | 1 - .../CloudApiSerialization/SaleToPoiMessageSerializer.cs | 9 +++------ Adyen.EcommLibrary/Model/Nexo/PaymentResponse.cs | 2 +- Adyen.EcommLibrary/Model/Nexo/SaleToPOIResponse.cs | 2 +- Adyen.EcommLibrary/Service/PosPaymentCloudApi.cs | 2 +- Adyen.EcommLibrary/Service/PosPaymentLocalApi.cs | 2 +- 8 files changed, 9 insertions(+), 13 deletions(-) diff --git a/Adyen.EcommLibrary/Adyen.EcommLibrary.csproj b/Adyen.EcommLibrary/Adyen.EcommLibrary.csproj index ccc589062..607b292e7 100644 --- a/Adyen.EcommLibrary/Adyen.EcommLibrary.csproj +++ b/Adyen.EcommLibrary/Adyen.EcommLibrary.csproj @@ -25,7 +25,7 @@ - + diff --git a/Adyen.EcommLibrary/CloudApiSerialization/Converter/SaleToPoiMessageSecuredConverter.cs b/Adyen.EcommLibrary/CloudApiSerialization/Converter/SaleToPoiMessageSecuredConverter.cs index 78fad7410..ca7463a4c 100644 --- a/Adyen.EcommLibrary/CloudApiSerialization/Converter/SaleToPoiMessageSecuredConverter.cs +++ b/Adyen.EcommLibrary/CloudApiSerialization/Converter/SaleToPoiMessageSecuredConverter.cs @@ -44,7 +44,7 @@ private string GetProperTypeNameForSerialization(Type type) return SaleToPoiRequestSecuredForSerialization; } - if (type == typeof(SaleToPoiResponse) || type == typeof(SaleToPoiResponseSecured)) + if (type == typeof(SaleToPOIResponse) || type == typeof(SaleToPoiResponseSecured)) { return SaleToPoiResponseSecuredForSerialization; } diff --git a/Adyen.EcommLibrary/CloudApiSerialization/MessagePayloadSerializerFactory.cs b/Adyen.EcommLibrary/CloudApiSerialization/MessagePayloadSerializerFactory.cs index f6ef94b95..5efa7746b 100644 --- a/Adyen.EcommLibrary/CloudApiSerialization/MessagePayloadSerializerFactory.cs +++ b/Adyen.EcommLibrary/CloudApiSerialization/MessagePayloadSerializerFactory.cs @@ -9,7 +9,6 @@ internal class MessagePayloadSerializerFactory internal IMessagePayloadSerializer CreateSerializer(string messageCategory, string messageType) { var messagePayoadFullName = CreateMessagePayloadFullName(messageCategory, messageType); - var messagePayloadSerializer = TypeHelper.CreateGenericTypeFromStringFullNamespace(typeof(MessagePayloadSerializer<>), messagePayoadFullName); return (IMessagePayloadSerializer)Activator.CreateInstance(messagePayloadSerializer); diff --git a/Adyen.EcommLibrary/CloudApiSerialization/SaleToPoiMessageSerializer.cs b/Adyen.EcommLibrary/CloudApiSerialization/SaleToPoiMessageSerializer.cs index 580eb96e5..96ba1ed54 100644 --- a/Adyen.EcommLibrary/CloudApiSerialization/SaleToPoiMessageSerializer.cs +++ b/Adyen.EcommLibrary/CloudApiSerialization/SaleToPoiMessageSerializer.cs @@ -1,8 +1,5 @@ -using System; -using System.Linq; -using Adyen.EcommLibrary.Model.Nexo; +using Adyen.EcommLibrary.Model.Nexo; using Adyen.EcommLibrary.Security; -using Newtonsoft.Json; using Newtonsoft.Json.Linq; namespace Adyen.EcommLibrary.CloudApiSerialization @@ -17,7 +14,7 @@ public SaleToPoiMessageSerializer() _messageHeaderSerializer = new MessageHeaderSerializer(); _messagePayloadSerializerFactory = new MessagePayloadSerializerFactory(); } - public SaleToPoiResponse Deserialize(string saleToPoiMessageDto) + public SaleToPOIResponse Deserialize(string saleToPoiMessageDto) { //todo temporary solution until we have an improved response if (string.Equals("ok", saleToPoiMessageDto)) @@ -32,7 +29,7 @@ public SaleToPoiResponse Deserialize(string saleToPoiMessageDto) //Message payload object messagePayload = DeserializeMessagePayload(messageHeader, saleToPoiMessageWithoutRootJToken); - var deserializedOutputMessage = new SaleToPoiResponse + var deserializedOutputMessage = new SaleToPOIResponse { MessageHeader = messageHeader, MessagePayload = messagePayload diff --git a/Adyen.EcommLibrary/Model/Nexo/PaymentResponse.cs b/Adyen.EcommLibrary/Model/Nexo/PaymentResponse.cs index ede69293b..5364d2f57 100644 --- a/Adyen.EcommLibrary/Model/Nexo/PaymentResponse.cs +++ b/Adyen.EcommLibrary/Model/Nexo/PaymentResponse.cs @@ -7,7 +7,7 @@ namespace Adyen.EcommLibrary.Model.Nexo [System.SerializableAttribute()] [System.Diagnostics.DebuggerStepThroughAttribute()] [System.ComponentModel.DesignerCategoryAttribute("code")] - public partial class PaymentResponse :IMessagePayload + public partial class PaymentResponse : IMessagePayload { /// diff --git a/Adyen.EcommLibrary/Model/Nexo/SaleToPOIResponse.cs b/Adyen.EcommLibrary/Model/Nexo/SaleToPOIResponse.cs index 4f04906b6..6271e3e9b 100644 --- a/Adyen.EcommLibrary/Model/Nexo/SaleToPOIResponse.cs +++ b/Adyen.EcommLibrary/Model/Nexo/SaleToPOIResponse.cs @@ -7,7 +7,7 @@ [System.ComponentModel.DesignerCategoryAttribute("code")] [System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)] [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)] - public partial class SaleToPoiResponse + public partial class SaleToPOIResponse { /// diff --git a/Adyen.EcommLibrary/Service/PosPaymentCloudApi.cs b/Adyen.EcommLibrary/Service/PosPaymentCloudApi.cs index e2e7a02be..dad3dcad4 100644 --- a/Adyen.EcommLibrary/Service/PosPaymentCloudApi.cs +++ b/Adyen.EcommLibrary/Service/PosPaymentCloudApi.cs @@ -38,7 +38,7 @@ public string TerminalApiCloudAsync(SaleToPOIMessage saleToPoiRequest) /// /// /// - public SaleToPoiResponse TerminalApiCloudSync(SaleToPOIMessage saleToPoiRequest) + public SaleToPOIResponse TerminalApiCloudSync(SaleToPOIMessage saleToPoiRequest) { var serializedMessage = _saleToPoiMessageSerializer.Serialize(saleToPoiRequest); this.Client.LogLine("Request: \n"+ serializedMessage); diff --git a/Adyen.EcommLibrary/Service/PosPaymentLocalApi.cs b/Adyen.EcommLibrary/Service/PosPaymentLocalApi.cs index 16798e87e..4bfc8e59a 100644 --- a/Adyen.EcommLibrary/Service/PosPaymentLocalApi.cs +++ b/Adyen.EcommLibrary/Service/PosPaymentLocalApi.cs @@ -29,7 +29,7 @@ public PosPaymentLocalApi(Client client) /// /// /// - public SaleToPoiResponse TerminalApiLocal(SaleToPOIMessage saleToPoiRequest, EncryptionCredentialDetails encryptionCredentialDetails) + public SaleToPOIResponse TerminalApiLocal(SaleToPOIMessage saleToPoiRequest, EncryptionCredentialDetails encryptionCredentialDetails) { var saleToPoiRequestMessageSerialized = _saleToPoiMessageSerializer.Serialize(saleToPoiRequest); this.Client.LogLine("Request: \n" + saleToPoiRequestMessageSerialized); From 8c948ac91bc7f820f19e863eedfb4e103fc3fb58 Mon Sep 17 00:00:00 2001 From: alexandros Date: Thu, 27 Dec 2018 14:09:57 +0100 Subject: [PATCH 3/5] Impove cloud api test adding dynamic casting --- Adyen.EcommLibrary.Test/CloudApiPosRequestTest.cs | 11 +++++++++-- .../SaleToPoiMessageSerializer.cs | 7 ++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Adyen.EcommLibrary.Test/CloudApiPosRequestTest.cs b/Adyen.EcommLibrary.Test/CloudApiPosRequestTest.cs index 8134e3282..3459993ae 100644 --- a/Adyen.EcommLibrary.Test/CloudApiPosRequestTest.cs +++ b/Adyen.EcommLibrary.Test/CloudApiPosRequestTest.cs @@ -58,19 +58,26 @@ public void TestCloudApiTransactionStatusResponseSuccess() try { var transactionStatusResponse = (TransactionStatusResponse)saleToPoiResponse.MessagePayload; - var paymentResponse = (PaymentResponse)transactionStatusResponse.RepeatedMessageResponse.RepeatedResponseMessageBody.MessagePayload; + var messagePayload = transactionStatusResponse.RepeatedMessageResponse.RepeatedResponseMessageBody.MessagePayload; + var messagePayloadResponse = DynamicCast(messagePayload, messagePayload.GetType()); Assert.IsNotNull(saleToPoiResponse); Assert.AreEqual(saleToPoiResponse.MessageHeader.ServiceID, "35543420"); Assert.AreEqual(saleToPoiResponse.MessageHeader.SaleID, "TOSIM_1_1_6"); Assert.AreEqual(saleToPoiResponse.MessageHeader.POIID, "P400Plus-12345678"); Assert.AreEqual(transactionStatusResponse.Response.Result, "Success"); - Assert.AreEqual(paymentResponse.PaymentResult.PaymentInstrumentData.CardData.EntryMode[0], "ICC"); + Assert.AreEqual(messagePayloadResponse.PaymentResult.PaymentInstrumentData.CardData.EntryMode[0], "ICC"); + Assert.AreEqual(messagePayloadResponse.POIData.POIReconciliationID, "1000"); } catch (Exception) { Assert.Fail(); } } + + private static dynamic DynamicCast(dynamic obj, Type castTo) + { + return Convert.ChangeType(obj, castTo); + } } } diff --git a/Adyen.EcommLibrary/CloudApiSerialization/SaleToPoiMessageSerializer.cs b/Adyen.EcommLibrary/CloudApiSerialization/SaleToPoiMessageSerializer.cs index 96ba1ed54..b311770e5 100644 --- a/Adyen.EcommLibrary/CloudApiSerialization/SaleToPoiMessageSerializer.cs +++ b/Adyen.EcommLibrary/CloudApiSerialization/SaleToPoiMessageSerializer.cs @@ -35,12 +35,13 @@ public SaleToPOIResponse Deserialize(string saleToPoiMessageDto) MessagePayload = messagePayload }; - //Check and deserialize RepeatedMessageResponse - if (saleToPoiMessageDto.Contains("RepeatedMessageResponse") && saleToPoiMessageDto.Contains("RepeatedResponseMessageBody")) + //Check and deserialize RepeatedMessageResponse. RepeatedMessageResponse is optional + if (saleToPoiMessageDto.Contains("TransactionStatusResponse") && saleToPoiMessageDto.Contains("RepeatedMessageResponse") && saleToPoiMessageDto.Contains("RepeatedResponseMessageBody")) { var response = GetDeserializedRepeatedResponseMessagePayload(saleToPoiMessageWithoutRootJToken); - var deserializedOutput = (TransactionStatusResponse)deserializedOutputMessage.MessagePayload; + TransactionStatusResponse deserializedOutput = (TransactionStatusResponse)deserializedOutputMessage.MessagePayload; deserializedOutput.RepeatedMessageResponse.RepeatedResponseMessageBody.MessagePayload = response; + deserializedOutputMessage.MessagePayload = deserializedOutput; } return deserializedOutputMessage; } From ad03a5624b1bf039c54bd708fcdd02bff31c964c Mon Sep 17 00:00:00 2001 From: alexandros Date: Thu, 27 Dec 2018 16:15:26 +0100 Subject: [PATCH 4/5] Improve test Cloud api transaction status response --- Adyen.EcommLibrary.Test/CloudApiPosRequestTest.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Adyen.EcommLibrary.Test/CloudApiPosRequestTest.cs b/Adyen.EcommLibrary.Test/CloudApiPosRequestTest.cs index 3459993ae..b8af97d50 100644 --- a/Adyen.EcommLibrary.Test/CloudApiPosRequestTest.cs +++ b/Adyen.EcommLibrary.Test/CloudApiPosRequestTest.cs @@ -59,7 +59,7 @@ public void TestCloudApiTransactionStatusResponseSuccess() { var transactionStatusResponse = (TransactionStatusResponse)saleToPoiResponse.MessagePayload; var messagePayload = transactionStatusResponse.RepeatedMessageResponse.RepeatedResponseMessageBody.MessagePayload; - var messagePayloadResponse = DynamicCast(messagePayload, messagePayload.GetType()); + var messagePayloadResponse = (dynamic)messagePayload; Assert.IsNotNull(saleToPoiResponse); Assert.AreEqual(saleToPoiResponse.MessageHeader.ServiceID, "35543420"); @@ -74,10 +74,5 @@ public void TestCloudApiTransactionStatusResponseSuccess() Assert.Fail(); } } - - private static dynamic DynamicCast(dynamic obj, Type castTo) - { - return Convert.ChangeType(obj, castTo); - } } } From 9918527ac462b8ecc72c72fe880f4dff83b823a6 Mon Sep 17 00:00:00 2001 From: alexandros Date: Fri, 28 Dec 2018 08:24:31 +0100 Subject: [PATCH 5/5] RepeatedResponseMessageBody payload is dyanamic --- Adyen.EcommLibrary.Test/CloudApiPosRequestTest.cs | 5 ++--- .../CloudApiSerialization/SaleToPoiMessageSerializer.cs | 2 +- Adyen.EcommLibrary/Model/Nexo/RepeatedResponseMessageBody.cs | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Adyen.EcommLibrary.Test/CloudApiPosRequestTest.cs b/Adyen.EcommLibrary.Test/CloudApiPosRequestTest.cs index b8af97d50..fcdd3fd0b 100644 --- a/Adyen.EcommLibrary.Test/CloudApiPosRequestTest.cs +++ b/Adyen.EcommLibrary.Test/CloudApiPosRequestTest.cs @@ -58,9 +58,8 @@ public void TestCloudApiTransactionStatusResponseSuccess() try { var transactionStatusResponse = (TransactionStatusResponse)saleToPoiResponse.MessagePayload; - var messagePayload = transactionStatusResponse.RepeatedMessageResponse.RepeatedResponseMessageBody.MessagePayload; - var messagePayloadResponse = (dynamic)messagePayload; - + var messagePayloadResponse = transactionStatusResponse.RepeatedMessageResponse.RepeatedResponseMessageBody.MessagePayload; + Assert.IsNotNull(saleToPoiResponse); Assert.AreEqual(saleToPoiResponse.MessageHeader.ServiceID, "35543420"); Assert.AreEqual(saleToPoiResponse.MessageHeader.SaleID, "TOSIM_1_1_6"); diff --git a/Adyen.EcommLibrary/CloudApiSerialization/SaleToPoiMessageSerializer.cs b/Adyen.EcommLibrary/CloudApiSerialization/SaleToPoiMessageSerializer.cs index b311770e5..77b7c6bbc 100644 --- a/Adyen.EcommLibrary/CloudApiSerialization/SaleToPoiMessageSerializer.cs +++ b/Adyen.EcommLibrary/CloudApiSerialization/SaleToPoiMessageSerializer.cs @@ -86,7 +86,7 @@ private object GetDeserializedRepeatedResponseMessagePayload(JToken saletoPoiMes var repeatedMessageResponse = saletoPoiMessageJtoken.ToString(); var repeatedMessage = saletoPoiMessageJtoken["TransactionStatusResponse"]["RepeatedMessageResponse"]["RepeatedResponseMessageBody"].ToString(); var objMessage = JObject.Parse(repeatedMessage); - + if (repeatedMessageResponse.Contains("CardAcquisitionResponse")) { return objMessage[repeatedMessageResponse].ToObject(); diff --git a/Adyen.EcommLibrary/Model/Nexo/RepeatedResponseMessageBody.cs b/Adyen.EcommLibrary/Model/Nexo/RepeatedResponseMessageBody.cs index b13ab5d96..2e544818f 100644 --- a/Adyen.EcommLibrary/Model/Nexo/RepeatedResponseMessageBody.cs +++ b/Adyen.EcommLibrary/Model/Nexo/RepeatedResponseMessageBody.cs @@ -19,6 +19,6 @@ public partial class RepeatedResponseMessageBody :IMessagePayload [System.Xml.Serialization.XmlElementAttribute("PaymentResponse", typeof(PaymentResponse), Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] [System.Xml.Serialization.XmlElementAttribute("ReversalResponse", typeof(ReversalResponse), Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] [System.Xml.Serialization.XmlElementAttribute("StoredValueResponse", typeof(StoredValueResponse), Form = System.Xml.Schema.XmlSchemaForm.Unqualified)] - public object MessagePayload; + public dynamic MessagePayload; } } \ No newline at end of file