public List<ResponseDetails> ProcessSVATransaction(
                         TransactionType _TT //Required
            , StoredValueTransaction _SVAtransaction //Conditional : Only used for an AuthorizeAndCapture, Authorize and ReturnUnlinked. Otherwise null
            , StoredValueManage _SVManage // Conditional : Only used to manage. Otherwise null
            , StoredValueCapture _SVDifferenceData //Conditional : Only used for a Capture. Otherwise null
            , StoredValueReturn _SVRDifferenceData //Conditional : Only used for a ReturnById. Otherwise null
            , Undo _UDifferenceData //Conditional : Only used for an Undo. Otherwise null
            , bool _SendAcknowledge)
        {
            List<Response> _Response = new List<Response>();
            try
            {
                CheckTokenExpire();//Make sure the current token is valid

                //if (_TT == TransactionType.AuthorizeAndCapture)
                if (_TT == TransactionType.Authorize)
                {
                    _Response.Add(Cwsbc.Authorize(_sessionToken, _SVAtransaction, _applicationProfileId, _merchantProfileId, _serviceId));
                    //Always Verify that the requested amount and approved amount are the same.
                    StoredValueTransactionResponse SVR = new StoredValueTransactionResponse();
                    SVR = (StoredValueTransactionResponse)_Response[0];
                    if (_SVAtransaction.TransactionData.Amount != SVR.Amount)
                        MessageBox.Show("The transaction was approved for " + SVR.Amount
                            + " which is an amount not equal to than the requested amount of " + _SVAtransaction.TransactionData.Amount
                            + ". Please provide alternate payment to complete transaction");
                }
                if (_TT == TransactionType.ManageAccountById)
                    _Response.Add(Cwsbc.ManageAccountById(_sessionToken, _SVManage, _applicationProfileId, _serviceId));
                if (_TT == TransactionType.ManageAccount)
                    _Response.Add(Cwsbc.ManageAccount(_sessionToken, _SVAtransaction, _applicationProfileId, _merchantProfileId, _serviceId));
                if (_TT == TransactionType.Capture)
                    _Response.Add(Cwsbc.Capture(_sessionToken, _SVDifferenceData, _applicationProfileId, _serviceId));
                if (_TT == TransactionType.ReturnById)
                    _Response.Add(Cwsbc.ReturnById(_sessionToken, _SVRDifferenceData, _applicationProfileId, _serviceId));
                if (_TT == TransactionType.Return)
                    _Response.Add(Cwsbc.ReturnUnlinked(_sessionToken, _SVAtransaction, _applicationProfileId, _merchantProfileId, _serviceId));
                if (_TT == TransactionType.Undo)
                    _Response.Add(Cwsbc.Undo(_sessionToken, _UDifferenceData, _applicationProfileId, _serviceId));
                if (_TT == TransactionType.QueryAccount)
                    _Response.Add(Cwsbc.QueryAccount(_sessionToken, _SVAtransaction, _applicationProfileId, _merchantProfileId, _serviceId));

                List<ResponseDetails> RD = new List<ResponseDetails>();//Convert the response to response details so that we can report on the UI
                if (_Response != null)
                {
                    foreach (Response r in _Response)
                    {
                        if (_SendAcknowledge && r.TransactionId.Length > 0)
                            Cwsbc.Acknowledge(_sessionToken, r.TransactionId, _applicationProfileId, _serviceId);

                        ResponseDetails RDN = new ResponseDetails(0.00M, r, _TT.ToString(), _serviceId, _merchantProfileId, true, TypeCardType.NotSet, "");
                        MessageBox.Show(ProcessResponse(ref RDN));//Pass as reference so we can extract more values from the response
                        RD.Add(RDN);
                    }
                }

                return RD;
            }
            catch (EndpointNotFoundException)
            {
                //In this case the SvcEndpoint was not available. Try the same logic again with the alternate Endpoint
                try
                {
                    SetTxnEndpoint();//Change the endpoint to use the backup.

                    //TODO : Add a copy of the code above once fully tested out.

                    return null;

                }
                catch (EndpointNotFoundException)
                {
                    MessageBox.Show("Neither the primary or secondary endpoints are available. Unable to process.");
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Unable to AuthorizeAndCapture\r\nError Message : " + ex.Message, "AuthorizeAndCapture Failed", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }
            catch (System.TimeoutException te)
            {
                //A timeout has occured. Prompt the user if they'd like to query for the last transaction submitted
                if (_SVAtransaction != null)
                {
                    DialogResult Result;
                    Result = MessageBox.Show("A timeout has occured. Would you like to query 'RequestTransaction' to obtain transactions with the exact same TenderData? To avoid duplicate charges your code will need to reconcile transactions.",
                                "Request Transaction", MessageBoxButtons.YesNo);
                    if (Result == DialogResult.Yes)
                    {
                        RequestTransaction(_SVAtransaction.TenderData);
                    }
                    else { throw te; }
                }
                else { throw te; }
            }
            catch (Exception ex)
            {
                string strErrorId;
                string strErrorMessage;
                if (_FaultHandler.handleTxnFault(ex, out strErrorId, out strErrorMessage))
                { MessageBox.Show(strErrorId + " : " + strErrorMessage); }
                else { MessageBox.Show(ex.Message); }
            }

            return null;
        }
        private void cmdReturnById_Click(object sender, EventArgs e)
        {//The ReturnById() operation is used to return a transaction that has been previously captured.
            if (ChkLstTransactionsProcessed.CheckedItems.Count == 0) { MessageBox.Show("Please Select (Check) transactions for ReturnById"); return; }
            //Check to see if this transaction type is supported
            if (!SupportedTxnTypes.ReturnById) { MessageBox.Show("ReturnById Not Supported");return; }

            Cursor = Cursors.WaitCursor;

            if (_bcs != null) //Process a BankCard Transaction
            {
                try
                {
                    BankcardReturn BCRDifferenceData = new BankcardReturn();

                    List<ResponseDetails> txnsToProcess = new List<ResponseDetails>();
                    if (_bcs.Tenders.CreditAuthorizeSupport == CreditAuthorizeSupportType.AuthorizeOnly)
                    {//NOTE : Please note that in the case of some Service Providers AuthorizeAndCapture is not supported for ReturnById. Use Authorize Instead
                        //In this case it's a terminal capture service that supports PINDebit

                        //First verify if all transactions selected are "Authorize" transactions
                        foreach (object itemChecked in ChkLstTransactionsProcessed.CheckedItems)
                        {
                            if (((ResponseDetails)(itemChecked)).TransactionType != TransactionType.Authorize.ToString())
                            {
                                MessageBox.Show("All selected messages must be of type Authorize");
                                Cursor = Cursors.Default;
                                return;
                            }
                            txnsToProcess.Add(((ResponseDetails)(itemChecked)));
                        }
                       
                        //Now in ordert to process a ReturnById we must first Capture the transaction. This can be done with CaptureAll or CaptureSelective.
                        MessageBox.Show("All transctions must be processed via a CaptureAll or CaptureSelective first. Running CaptureAll");
                        processResponse(Helper.ProcessBCPTransaction(TransactionType.CaptureAll, null, null, null, null, null, null, null, null, ChkAcknowledge.Checked, false));

                        //Now process each message selected
                        foreach (ResponseDetails _RD in txnsToProcess)
                        {
                            BCRDifferenceData.TransactionId = _RD.Response.TransactionId;
                            BCRDifferenceData.Amount = 8.00M;
                            processResponse(Helper.ProcessBCPTransaction(TransactionType.ReturnById, null, null, null, BCRDifferenceData, null, null, null, null, ChkAcknowledge.Checked, false));
                        }
                    }
                    else
                    {
                        //In this case it's a host capture solution. So only AuthorizeAndCapture and Capture transactions are permitted. 

                        //First verify if all transactions selected are "AuthorizeAndCapture" or "Capture" transactions
                        foreach (object itemChecked in ChkLstTransactionsProcessed.CheckedItems)
                        {
                            if (((ResponseDetails)(itemChecked)).TransactionType != TransactionType.AuthorizeAndCapture.ToString()
                                && ((ResponseDetails)(itemChecked)).TransactionType != TransactionType.Capture.ToString())
                            {
                                MessageBox.Show("All selected messages must be of type AuthorizeAndCapture or Capture");
                                Cursor = Cursors.Default;
                                return;
                            }
                            txnsToProcess.Add(((ResponseDetails)(itemChecked)));
                        }
                        //Now process each  message selected
                        foreach (ResponseDetails _RD in txnsToProcess)
                        {
                            //Let's return the transaction
                            BCRDifferenceData.TransactionId = _RD.Response.TransactionId;
                            BCRDifferenceData.Amount = 8.00M;
                            processResponse(Helper.ProcessBCPTransaction(TransactionType.ReturnById, null, null, null, BCRDifferenceData, null, null, null, null, ChkAcknowledge.Checked, false));
                        }
                    }
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                finally { Cursor = Cursors.Default; }

            }
            else if (_svas != null) //Process a Stored Value Transaction
            {
                //Check to see if this transaction type is supported
                if (!SupportedTxnTypes.ReturnById) { MessageBox.Show("ReturnById Not Supported"); Cursor = Cursors.Default; return; }

                try
                {
                    StoredValueTransaction SVtransaction = SetStoredValueTxnData();
                    List<ResponseDetails> response = new List<ResponseDetails>();
                    StoredValueReturn SVRDifferenceData = new StoredValueReturn();
                    string strTransactionId = "";
                    SVtransaction.TransactionData.Amount = 84.00M;

                    if (_svas.Tenders.CreditAuthorizeSupport == CreditAuthorizeSupportType.AuthorizeAndCaptureOnly)
                    {
                        response = Helper.ProcessSVATransaction(TransactionType.AuthorizeAndCapture, SVtransaction, null, null, null, null, ChkAcknowledge.Checked);
                        if (response.Count < 1) { return; }
                        ChkLstTransactionsProcessed.Items.Add(response[0]); 
                        StoredValueTransactionResponse SVR = (StoredValueTransactionResponse)response[0].Response;
                        strTransactionId = SVR.TransactionId;
                        //Now in ordert to process a ReturnById we must first Capture the transaction. This can be done with CaptureAll or CaptureSelective.
                        response = Helper.ProcessBCPTransaction(TransactionType.CaptureAll, null, null, null, null, null, null, null, null, ChkAcknowledge.Checked, false);
                        if (response.Count < 1) { return; }
                        ChkLstTransactionsProcessed.Items.Add(response[0]);

                        //Now Let's return the transaction
                        SVRDifferenceData.TransactionId = strTransactionId;
                        SVRDifferenceData.Amount = 36.00M;
                        response = Helper.ProcessSVATransaction(TransactionType.ReturnById, null, null, null, SVRDifferenceData, null, ChkAcknowledge.Checked);
                        if (response.Count < 1) { return; }
                        ChkLstTransactionsProcessed.Items.Add(response[0]);
                    }
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                finally { Cursor = Cursors.Default; }

            }
            else if (_ecks != null) //Process as a Check transaction
            {
                try
                {
                    MessageBox.Show(@"Placeholder for ECK code. Please ask your solution consultant for an example");
                }
                catch (Exception ex) { MessageBox.Show(ex.Message); }
                finally { Cursor = Cursors.Default; }
            }
        }