added route to authorize transactions

This commit is contained in:
yurii 2025-12-15 16:54:00 +00:00
parent b4dcc35a8b
commit 3f559dfd45
2 changed files with 82 additions and 5 deletions

View File

@ -249,7 +249,6 @@ namespace Creditcall.ChipDna.Client
{
{ ParameterKeys.Errors, errors },
{ ParameterKeys.Reference, reference },
{ ParameterKeys.TransactionResult, "ERROR" }
};
if (TransactionCompletionSource != null && !TransactionCompletionSource.Task.IsCompleted)

View File

@ -19,6 +19,7 @@ namespace Creditcall.ChipDna.Client
private const int DefaultPort = 1869;
private const string DefaultIpAddress = "127.0.0.1";
private const bool DefaultSaveReceipt = false;
private const int transactionTimeoutSeconds = 300;
private static Client client;
@ -72,10 +73,14 @@ namespace Creditcall.ChipDna.Client
{
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-and-confirm-transaction/");
listener.Prefixes.Add("http://127.0.0.1:18181/void-transaction/");
listener.Start();
Console.WriteLine("Listening on:");
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)
{
@ -95,6 +100,9 @@ namespace Creditcall.ChipDna.Client
if (rawUrl.StartsWith("/start-transaction", StringComparison.OrdinalIgnoreCase))
{
HandleStartTransaction(context);
} else if (rawUrl.StartsWith("/start-and-confirm-transaction", StringComparison.OrdinalIgnoreCase))
{
HandleStartAndConfirmTransaction(context);
}
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
{
var serializer = new XmlSerializer(typeof(TransactionPayload));
@ -214,7 +220,7 @@ namespace Creditcall.ChipDna.Client
}
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;
}
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)
{
var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);