using Microsoft.AspNet.SignalR.Client; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Security.Cryptography; using System.Text; namespace SignalRClientPOS { class Program { // callback data as received from PayWiser private class Callback { public string Type { get; set; } public string Data { get; set; } public string HMAC { get; set; } } // innser callback data for pos payment as received from PayWiser private class POSPaymentCallback { public string PGReferenceID { get; set; } public string CustomerReferenceID { get; set; } public int TransactionType { get; set; } public int PaymentStatus { get; set; } public string PaymentDescription { get; set; } public string CardScheme { get; set; } public string CardType { get; set; } public string TerminalID { get; set; } public string TerminalIP { get; set; } public string TerminalPort { get; set; } } // innser callback data for pos refund as received from PayWiser private class POSRefundCallback: POSPaymentCallback { } private static HubConnection hubConnection = null; private static IHubProxy hubProxy = null; private static bool isClosing = false; private static string confirmationString = "1234qwertz"; static void Main(string[] args) { InitializeConnection(); Console.Read(); isClosing = true; hubConnection.Stop(); } private static void InitializeConnection() { if (hubConnection != null) hubConnection.Closed -= OnDisconnected; var querystringData = new Dictionary(); // for getting all transactions callbacks, specify just ApiKey querystringData.Add("ApiKey", "TestMerchant-26365011-38a3-40ff-9ecb-57582a28098b"); // for getting just one payment callback, specify PGReferenceID as well querystringData.Add("PGReferenceID", "d7bceab3-b1f9-4d97-af5c-eb18863c1134"); hubConnection = new HubConnection("https://gateway.paywiser.eu:8094/", querystringData); hubConnection.Error += ex => Console.WriteLine("SignalR error: {0}", ex.Message); hubConnection.Closed += OnDisconnected; hubProxy = hubConnection.CreateHubProxy("pOSPaymentsSignal"); hubProxy.On("PGPOSPaymentMessage", (paymentData) => { // deserialize data Callback callback = JsonConvert.DeserializeObject(paymentData); // deserialize inner callback data if (callback.Type.Equals("pos_payment")) { POSPaymentCallback posPayment = JsonConvert.DeserializeObject(callback.Data); // your logic goes here } else if (callback.Type.Equals("pos_refund")) { POSRefundCallback posRefund = JsonConvert.DeserializeObject(callback.Data); // your logic goes here } // calculate HMAC string calculatedHMAC = CalculateHMAC(callback.Data, confirmationString); Console.WriteLine("Message: "+paymentData); Console.WriteLine("HMAC from data: " + callback.HMAC); Console.WriteLine("HMAC calculated: " + calculatedHMAC); Console.WriteLine(""); }); ConnectWithRetry(); } static void OnDisconnected() { Console.WriteLine("Disconnected"); if (!isClosing) InitializeConnection(); } private static void ConnectWithRetry() { hubConnection.Start().ContinueWith(task => { if (task.IsFaulted) { Console.WriteLine("There was an error opening the connection:{0}", task.Exception.GetBaseException()); } else { Console.WriteLine("Connected"); } }).Wait(); } private static string CalculateHMAC(string payload, string confirmationSequence) { if (String.IsNullOrWhiteSpace(payload) || String.IsNullOrWhiteSpace(confirmationSequence)) return ""; var data = Encoding.UTF8.GetBytes(payload); var key = Encoding.UTF8.GetBytes(confirmationSequence); // Create HMAC-MD5 Algorithm; var hmac = new HMACMD5(key); // Compute hash. var hashBytes = hmac.ComputeHash(data); // Convert to HEX string. return System.BitConverter.ToString(hashBytes).Replace("-", "").ToLower(); } } }