added confirm transaction endpoint
This commit is contained in:
parent
c053868dd3
commit
35a2870179
18
Client.cs
18
Client.cs
@ -318,7 +318,7 @@ namespace Creditcall.ChipDna.Client
|
||||
PerformStartTransaction("250", "");
|
||||
break;
|
||||
case "C":
|
||||
PerformConfirmTransaction("", out TransactionConfirmation confirmation);
|
||||
PerformConfirmTransaction("", "");
|
||||
break;
|
||||
case "V":
|
||||
PerformVoidTransaction("");
|
||||
@ -642,19 +642,23 @@ namespace Creditcall.ChipDna.Client
|
||||
}
|
||||
}
|
||||
|
||||
public void PerformConfirmTransaction(string reference, out TransactionConfirmation confirmation)
|
||||
public Dictionary<string, string> PerformConfirmTransaction(string reference, string amount)
|
||||
{
|
||||
confirmation = new TransactionConfirmation();
|
||||
|
||||
var confirmationResult = new Dictionary<string, string>();
|
||||
var parameters = new ParameterSet();
|
||||
parameters.Add(ParameterKeys.Reference, reference);
|
||||
parameters.Add(ParameterKeys.Amount, amount);
|
||||
parameters.Add(GetExtraParams("ConfirmTransaction"));
|
||||
var response = chipDnaClientLib.ConfirmTransaction(parameters);
|
||||
var responseParameter = response.ToList();
|
||||
responseParameter.ForEach(parameter =>
|
||||
{
|
||||
confirmationResult.Add(parameter.Key, parameter.Value);
|
||||
});
|
||||
string receipt, result;
|
||||
if (response.GetValue(ParameterKeys.TransactionResult, out result))
|
||||
{
|
||||
Console.WriteLine("Confirmed Transaction Result: {0}", result);
|
||||
confirmation.Result = result;
|
||||
}
|
||||
if (response.GetValue(ParameterKeys.ReceiptDataMerchant, out receipt))
|
||||
{
|
||||
@ -663,21 +667,19 @@ namespace Creditcall.ChipDna.Client
|
||||
if (response.GetValue(ParameterKeys.ReceiptDataCardholder, out receipt))
|
||||
{
|
||||
PrintReceiptData(ReceiptData.GetReceiptDataFromXml(receipt));
|
||||
confirmation.ReceiptDataCardholder = receipt;
|
||||
}
|
||||
string errors;
|
||||
if (response.GetValue(ParameterKeys.Errors, out errors))
|
||||
{
|
||||
Console.WriteLine(ErrorsString("ConfirmTransaction Errors", errors));
|
||||
confirmation.Errors = errors;
|
||||
}
|
||||
|
||||
string errorDescription;
|
||||
if (response.GetValue(ParameterKeys.ErrorDescription, out errorDescription))
|
||||
{
|
||||
Console.WriteLine("ErrorDescription: {0}", errorDescription);
|
||||
confirmation.ErrorDescription = errorDescription;
|
||||
}
|
||||
return confirmationResult;
|
||||
}
|
||||
|
||||
private void DoUpdateTransaction()
|
||||
|
||||
121
ClientApp.cs
121
ClientApp.cs
@ -73,7 +73,7 @@ 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/confirm-transaction/");
|
||||
listener.Prefixes.Add("http://127.0.0.1:18181/transaction-information/");
|
||||
listener.Prefixes.Add("http://127.0.0.1:18181/void-transaction/");
|
||||
listener.Prefixes.Add("http://127.0.0.1:18181/chipdna-status/");
|
||||
@ -81,7 +81,7 @@ namespace Creditcall.ChipDna.Client
|
||||
|
||||
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/confirm-transaction/");
|
||||
Console.WriteLine(" http://127.0.0.1:18181/transaction-information/");
|
||||
Console.WriteLine(" http://127.0.0.1:18181/void-transaction/");
|
||||
Console.WriteLine(" http://127.0.0.1:18181/chipdna-status/");
|
||||
@ -105,9 +105,9 @@ namespace Creditcall.ChipDna.Client
|
||||
{
|
||||
HandleStartTransaction(context);
|
||||
|
||||
} else if (rawUrl.StartsWith("/start-and-confirm-transaction", StringComparison.OrdinalIgnoreCase))
|
||||
} else if (rawUrl.StartsWith("/confirm-transaction", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
HandleStartAndConfirmTransaction(context);
|
||||
HandleConfirmTransaction(context);
|
||||
}
|
||||
else if (rawUrl.StartsWith("/transaction-information", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
@ -120,7 +120,8 @@ namespace Creditcall.ChipDna.Client
|
||||
else if (rawUrl.StartsWith("/chipdna-status", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
HandleGetStatus(context);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
context.Response.StatusCode = 404;
|
||||
context.Response.Close();
|
||||
@ -212,105 +213,34 @@ namespace Creditcall.ChipDna.Client
|
||||
}
|
||||
}
|
||||
|
||||
private static void HandleStartAndConfirmTransaction(HttpListenerContext context)
|
||||
private static void HandleConfirmTransaction(HttpListenerContext context)
|
||||
{
|
||||
try
|
||||
{
|
||||
var serializer = new XmlSerializer(typeof(TransactionPayload));
|
||||
TransactionPayload payload = (TransactionPayload)serializer.Deserialize(context.Request.InputStream);
|
||||
var serializer = new XmlSerializer(typeof(ConfirmTransactionRequest));
|
||||
ConfirmTransactionRequest payload = (ConfirmTransactionRequest)serializer.Deserialize(context.Request.InputStream);
|
||||
|
||||
Console.WriteLine($"Received start transaction: Amount={payload.Amount}, Type={payload.TransactionType}");
|
||||
Console.WriteLine($"Received confirm transaction: Amount={payload.Amount}, TransactionReference={payload.TransactionReference}");
|
||||
|
||||
client.TransactionCompletionSource = new TaskCompletionSource<Dictionary<string, string>>();
|
||||
var confirmationResult = client.PerformConfirmTransaction(payload.TransactionReference, payload.Amount);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// If it's a SALE and approved, call ConfirmTransaction and attach its XML
|
||||
transactionResult.TryGetValue(ParameterKeys.TransactionType, out string txType);
|
||||
transactionResult.TryGetValue(ParameterKeys.TransactionResult, out string txResult);
|
||||
transactionResult.TryGetValue(ParameterKeys.Reference, out string txReference);
|
||||
|
||||
if (!string.IsNullOrEmpty(txType) && txType.Equals("SALE", StringComparison.OrdinalIgnoreCase) &&
|
||||
!string.IsNullOrEmpty(txResult) && txResult.Equals("APPROVED", StringComparison.OrdinalIgnoreCase) &&
|
||||
!string.IsNullOrEmpty(txReference))
|
||||
{
|
||||
try
|
||||
{
|
||||
TransactionConfirmation confirmation;
|
||||
client.PerformConfirmTransaction(txReference, out confirmation);
|
||||
|
||||
// Keep original fields, but also add confirmation-prefixed fields
|
||||
transactionResult["CONFIRM_RESULT"] = confirmation?.Result ?? "";
|
||||
transactionResult["CONFIRM_ERRORS"] = confirmation?.Errors ?? "";
|
||||
if (!string.IsNullOrEmpty(confirmation.ErrorDescription))
|
||||
{
|
||||
transactionResult["CONFIRM_ERRORS"] = $"{confirmation.Errors} {confirmation.ErrorDescription}";
|
||||
}
|
||||
if (!string.IsNullOrEmpty(confirmation?.ReceiptDataCardholder))
|
||||
{
|
||||
transactionResult[ParameterKeys.ReceiptDataCardholder] = confirmation.ReceiptDataCardholder;
|
||||
}
|
||||
|
||||
// XML (omit declaration so it can be embedded)
|
||||
var xml = SerializeToXml(confirmation, omitXmlDeclaration: true);
|
||||
transactionResult["TRANSACTION_CONFIRMATION"] = xml;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// preserve original transaction result but add an error key
|
||||
transactionResult["CONFIRM_RESULT"] = "ERROR";
|
||||
transactionResult["CONFIRM_ERRORS"] = $"ConfirmTransaction failed: {ex.Message}";
|
||||
}
|
||||
}
|
||||
|
||||
// Return the final key/value list as before
|
||||
var responseSerializer = new XmlSerializer(typeof(SerializableKeyValueList));
|
||||
context.Response.ContentType = "application/xml";
|
||||
var wrappedResult = new SerializableKeyValueList(transactionResult);
|
||||
var wrappedResult = new SerializableKeyValueList(confirmationResult);
|
||||
responseSerializer.Serialize(context.Response.OutputStream, wrappedResult);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Error in start-and-confirm-transaction: " + ex.Message);
|
||||
context.Response.StatusCode = 500;
|
||||
var errorMap = new Dictionary<string, string>
|
||||
{
|
||||
{ ParameterKeys.TransactionResult, "ERROR" },
|
||||
{ ParameterKeys.Errors, $"ConfirmTransaction failed: {ex.Message}" }
|
||||
};
|
||||
|
||||
var responseSerializer = new XmlSerializer(typeof(SerializableKeyValueList));
|
||||
context.Response.ContentType = "application/xml";
|
||||
var wrappedResult = new SerializableKeyValueList(errorMap);
|
||||
responseSerializer.Serialize(context.Response.OutputStream, wrappedResult);
|
||||
}
|
||||
finally
|
||||
{
|
||||
@ -491,4 +421,11 @@ namespace Creditcall.ChipDna.Client
|
||||
public string TransactionReference { get; set; }
|
||||
}
|
||||
|
||||
[XmlRoot("ConfirmTransactionRequest")]
|
||||
public class ConfirmTransactionRequest
|
||||
{
|
||||
public string Amount { get; set; }
|
||||
public string TransactionReference { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user