added route to authorize transactions
This commit is contained in:
parent
b4dcc35a8b
commit
3f559dfd45
@ -249,7 +249,6 @@ namespace Creditcall.ChipDna.Client
|
|||||||
{
|
{
|
||||||
{ ParameterKeys.Errors, errors },
|
{ ParameterKeys.Errors, errors },
|
||||||
{ ParameterKeys.Reference, reference },
|
{ ParameterKeys.Reference, reference },
|
||||||
{ ParameterKeys.TransactionResult, "ERROR" }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if (TransactionCompletionSource != null && !TransactionCompletionSource.Task.IsCompleted)
|
if (TransactionCompletionSource != null && !TransactionCompletionSource.Task.IsCompleted)
|
||||||
|
|||||||
86
ClientApp.cs
86
ClientApp.cs
@ -19,6 +19,7 @@ namespace Creditcall.ChipDna.Client
|
|||||||
private const int DefaultPort = 1869;
|
private const int DefaultPort = 1869;
|
||||||
private const string DefaultIpAddress = "127.0.0.1";
|
private const string DefaultIpAddress = "127.0.0.1";
|
||||||
private const bool DefaultSaveReceipt = false;
|
private const bool DefaultSaveReceipt = false;
|
||||||
|
private const int transactionTimeoutSeconds = 300;
|
||||||
|
|
||||||
private static Client client;
|
private static Client client;
|
||||||
|
|
||||||
@ -72,10 +73,14 @@ namespace Creditcall.ChipDna.Client
|
|||||||
{
|
{
|
||||||
HttpListener listener = new HttpListener();
|
HttpListener listener = new HttpListener();
|
||||||
listener.Prefixes.Add("http://127.0.0.1:18181/start-transaction/");
|
listener.Prefixes.Add("http://127.0.0.1:18181/start-transaction/");
|
||||||
|
listener.Prefixes.Add("http://127.0.0.1:18181/start-and-confirm-transaction/");
|
||||||
|
listener.Prefixes.Add("http://127.0.0.1:18181/void-transaction/");
|
||||||
listener.Start();
|
listener.Start();
|
||||||
|
|
||||||
Console.WriteLine("Listening on:");
|
Console.WriteLine("Listening on:");
|
||||||
Console.WriteLine(" http://127.0.0.1:18181/start-transaction/");
|
Console.WriteLine(" http://127.0.0.1:18181/start-transaction/");
|
||||||
|
Console.WriteLine(" http://127.0.0.1:18181/start-and-confirm-transaction/");
|
||||||
|
//Console.WriteLine(" http://127.0.0.1:18181/void-transaction/");
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
@ -95,6 +100,9 @@ namespace Creditcall.ChipDna.Client
|
|||||||
if (rawUrl.StartsWith("/start-transaction", StringComparison.OrdinalIgnoreCase))
|
if (rawUrl.StartsWith("/start-transaction", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
HandleStartTransaction(context);
|
HandleStartTransaction(context);
|
||||||
|
} else if (rawUrl.StartsWith("/start-and-confirm-transaction", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
HandleStartAndConfirmTransaction(context);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -115,10 +123,8 @@ namespace Creditcall.ChipDna.Client
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void HandleStartTransaction(HttpListenerContext context)
|
private static void HandleStartAndConfirmTransaction(HttpListenerContext context)
|
||||||
{
|
{
|
||||||
const int transactionTimeoutSeconds = 300;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var serializer = new XmlSerializer(typeof(TransactionPayload));
|
var serializer = new XmlSerializer(typeof(TransactionPayload));
|
||||||
@ -214,7 +220,7 @@ namespace Creditcall.ChipDna.Client
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
Console.WriteLine("Error in start-transaction: " + ex.Message);
|
Console.WriteLine("Error in start-and-confirm-transaction: " + ex.Message);
|
||||||
context.Response.StatusCode = 500;
|
context.Response.StatusCode = 500;
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@ -223,6 +229,78 @@ namespace Creditcall.ChipDna.Client
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void HandleStartTransaction(HttpListenerContext context)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var serializer = new XmlSerializer(typeof(TransactionPayload));
|
||||||
|
TransactionPayload payload = (TransactionPayload)serializer.Deserialize(context.Request.InputStream);
|
||||||
|
|
||||||
|
Console.WriteLine($"Received transaction request: Amount={payload.amount}, Type={payload.transactionType}");
|
||||||
|
|
||||||
|
client.TransactionCompletionSource = new TaskCompletionSource<Dictionary<string, string>>();
|
||||||
|
|
||||||
|
// start transaction (non-blocking)
|
||||||
|
client.PerformStartTransaction(payload.amount, payload.transactionType);
|
||||||
|
|
||||||
|
// Wait for completion with timeout
|
||||||
|
var task = client.TransactionCompletionSource.Task;
|
||||||
|
if (!task.Wait(TimeSpan.FromSeconds(transactionTimeoutSeconds)))
|
||||||
|
{
|
||||||
|
// timeout
|
||||||
|
var errorMap = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ ParameterKeys.TransactionResult, "TIMEOUT" },
|
||||||
|
{ ParameterKeys.Errors, "Transaction timed out waiting for device response" }
|
||||||
|
};
|
||||||
|
|
||||||
|
var wrappedTimeout = new SerializableKeyValueList(errorMap);
|
||||||
|
context.Response.ContentType = "application/xml";
|
||||||
|
new XmlSerializer(typeof(SerializableKeyValueList)).Serialize(context.Response.OutputStream, wrappedTimeout);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Task completed — handle possible exception
|
||||||
|
Dictionary<string, string> transactionResult;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
transactionResult = task.Result; // safe now, Wait returned
|
||||||
|
}
|
||||||
|
catch (AggregateException agg)
|
||||||
|
{
|
||||||
|
var first = agg.Flatten().InnerExceptions[0];
|
||||||
|
var errMap = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
{ ParameterKeys.TransactionResult, "ERROR" },
|
||||||
|
{ ParameterKeys.Errors, $"Transaction task faulted: {first.Message}" }
|
||||||
|
};
|
||||||
|
var wrapped = new SerializableKeyValueList(errMap);
|
||||||
|
context.Response.ContentType = "application/xml";
|
||||||
|
new XmlSerializer(typeof(SerializableKeyValueList)).Serialize(context.Response.OutputStream, wrapped);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var responseSerializer = new XmlSerializer(typeof(SerializableKeyValueList));
|
||||||
|
context.Response.ContentType = "application/xml";
|
||||||
|
var wrappedResult = new SerializableKeyValueList(transactionResult);
|
||||||
|
responseSerializer.Serialize(context.Response.OutputStream, wrappedResult);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine("Error in start-transaction: " + ex.Message);
|
||||||
|
context.Response.StatusCode = 500;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
context.Response.OutputStream.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static string GetAbsolutePath(string fileName)
|
private static string GetAbsolutePath(string fileName)
|
||||||
{
|
{
|
||||||
var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user