public List<ResponseDetails> ProcessECKTransaction(
                        TransactionType _TT //Required
                        , ElectronicCheckingTransaction _ECKtransaction
                        , List<String> _BatchIds //Conditional : A list of one or more batch Ids to capture.
                        , List<Capture> _CaptureDifferenceData
                        , 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)
                {
                    if (CredentialRequired())
                        _ECKtransaction.Addendum = CredentialsRequired(_serviceId, _credUserName, _credPassword);
                    _Response.Add(Cwsbc.Authorize(_sessionToken, _ECKtransaction, _applicationProfileId, _merchantProfileId, _serviceId));
                    //Always Verify that the requested amount and approved amount are the same.

                    ElectronicCheckingTransactionResponse ECKR = new ElectronicCheckingTransactionResponse();
                    ECKR = (ElectronicCheckingTransactionResponse)_Response[0];
                    if (_ECKtransaction.TransactionData.Amount != ECKR.Amount)
                        MessageBox.Show("The transaction was approved for " + ECKR.Amount
                            + " which is an amount not equal to than the requested amount of " + _ECKtransaction.TransactionData.Amount
                            + ". Please provide alternate payment to complete transaction");
                }
                //if (_TT == TransactionType.Capture)
                if (_TT == TransactionType.CaptureAll)
                {
                    _CaptureDifferenceData = new List<Capture>();
                    Capture cap = new Capture();
                    if (CredentialRequired())
                        cap.Addendum = CredentialsRequired(_serviceId, _credUserName, _credPassword);
                    cap.TransactionId = "-1";
                    _CaptureDifferenceData.Add(cap);
                    _Response = Cwsbc.CaptureAll(_sessionToken, _CaptureDifferenceData, _BatchIds, _applicationProfileId,
                                                 _merchantProfileId, _serviceId);
                }
                if (_TT == TransactionType.CaptureAllAsync)
                {
                    _CaptureDifferenceData = new List<Capture>();
                    Capture cap = new Capture();
                    if (CredentialRequired())
                        cap.Addendum = CredentialsRequired(_serviceId, _credUserName, _credPassword);
                    cap.TransactionId = "-1";
                    _CaptureDifferenceData.Add(cap);
                    _Response.Add(Cwsbc.CaptureAllAsync(_sessionToken, _CaptureDifferenceData, _BatchIds, _applicationProfileId, _merchantProfileId, _serviceId));
                }

                //if (_TT == TransactionType.CaptureSelective)
                //if (_TT == TransactionType.CaptureSelectiveAsync)
                //if (_TT == TransactionType.ReturnById)
                //if (_TT == TransactionType.Return)
                //if (_TT == TransactionType.Adjust)
                if (_TT == TransactionType.Undo)
                {
                    if (CredentialRequired())
                        _UDifferenceData.Addendum = CredentialsRequired(_serviceId, _credUserName, _credPassword);
                    _Response.Add(Cwsbc.Undo(_sessionToken, _UDifferenceData, _applicationProfileId, _serviceId));
                }
                if (_TT == TransactionType.QueryAccount)
                {
                    if (CredentialRequired())
                        _ECKtransaction.Addendum = CredentialsRequired(_serviceId, _credUserName, _credPassword);
                    _Response.Add(Cwsbc.QueryAccount(_sessionToken, _ECKtransaction, _applicationProfileId, _merchantProfileId, _serviceId));
                }

                //if (_TT == TransactionType.Verify)

                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 (_ECKtransaction != 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(_ECKtransaction.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 string ProcessElectronicCheckingTransactionResponse(ref ResponseDetails _Response)
        {
            ElectronicCheckingTransactionResponse _ECKResponse = new ElectronicCheckingTransactionResponse();
            _ECKResponse = (ElectronicCheckingTransactionResponse)_Response.Response;

            //Set the amount reference
            _Response.TxnAmount = _ECKResponse.Amount;

            string strResponseMessage = "";

            if (_ECKResponse.Status == Status.Successful)//The transaction was approved
            {//NOTE : Please reference the developers guide for a more complete explination of the return fields
                //Note Highly recommended to save
                if (_ECKResponse.TransactionId != null) strResponseMessage = strResponseMessage + "\r\nTransactionId : " + _ECKResponse.TransactionId;
                strResponseMessage = strResponseMessage + "\r\nMerchant Profile Id : " + _Response.MerchantProfileId;
                //Note Optional but recommended to save
                if (_ECKResponse.StatusCode != null) strResponseMessage = strResponseMessage + "\r\nStatus Code : " + _ECKResponse.StatusCode;
                if (_ECKResponse.StatusMessage != null) strResponseMessage = strResponseMessage + "\r\nStatus Message : " + _ECKResponse.StatusMessage;
                //Note Optional data about the batch
                if (_ECKResponse.ACHCapable != null) strResponseMessage = strResponseMessage + "\r\nACHCapable : " + _ECKResponse.ACHCapable;//Indicates if the customer's account will accept ACH transactions. Returned only on QueryAccount() transactions.
                if (_ECKResponse.Amount != null) strResponseMessage = strResponseMessage + "\r\nAmount : " + _ECKResponse.Amount;
                if (_ECKResponse.ApprovalCode != null) strResponseMessage = strResponseMessage + "\r\nApprovalCode : " + _ECKResponse.ApprovalCode; //A code provided when a transaction is approved.
                if (_ECKResponse.ModifiedAccountNumber != null) strResponseMessage = strResponseMessage + "\r\nModifiedAccountNumber : " + _ECKResponse.ModifiedAccountNumber; //Indicates the corrected account number that should be used for electronic check processing
                if (_ECKResponse.ModifiedRoutingNumber != null) strResponseMessage = strResponseMessage + "\r\nModifiedRoutingNumber : " + _ECKResponse.ModifiedRoutingNumber; //Indicates the corrected 9-digit bank routing number that should be used for electronic check processing.
                if (_ECKResponse.ReturnInformation != null)
                {
                    if (_ECKResponse.ReturnInformation.ReturnCode != null) strResponseMessage = strResponseMessage + "\r\nReturnCode : " + _ECKResponse.ReturnInformation.ReturnCode;//Code that indicates why the transaction was returned.
                    if (_ECKResponse.ReturnInformation.ReturnDate != null) strResponseMessage = strResponseMessage + "\r\nReturnDate : " + _ECKResponse.ReturnInformation.ReturnDate; //The date the transaction was returned by the bank.
                    if (_ECKResponse.ReturnInformation.ReturnReason != null) strResponseMessage = strResponseMessage + "\r\nReturnReason : " + _ECKResponse.ReturnInformation.ReturnReason; //Reason that indicates why the transaction was returned.
                }
                if (_ECKResponse.SubmitDate != null) strResponseMessage = strResponseMessage + "\r\nSubmitDate : " + _ECKResponse.SubmitDate; //The date the transaction was submitted to the bank.

                strResponseMessage = "Your transaction was APPROVED\r\n" + strResponseMessage;
            }
            if (_ECKResponse.Status == Status.Failure)//The transaction was declined
            {//NOTE : Please reference the developers guide for a more complete explination of the return fields
                //Note Highly recommended to save
                if (_ECKResponse.TransactionId != null) strResponseMessage = strResponseMessage + "\r\nTransactionId : " + _ECKResponse.TransactionId;
                strResponseMessage = strResponseMessage + "\r\nMerchant Profile Id : " + _Response.MerchantProfileId;
                //Note Optional but recommended to save
                if (_ECKResponse.StatusCode != null) strResponseMessage = strResponseMessage + "\r\nStatus Code : " + _ECKResponse.StatusCode;
                if (_ECKResponse.StatusMessage != null) strResponseMessage = strResponseMessage + "\r\nStatus Message : " + _ECKResponse.StatusMessage;
                //Note Optional
                if (_ECKResponse.ACHCapable != null) strResponseMessage = strResponseMessage + "\r\nACHCapable : " + _ECKResponse.ACHCapable;//Indicates if the customer's account will accept ACH transactions. Returned only on QueryAccount() transactions.
                if (_ECKResponse.Amount != null) strResponseMessage = strResponseMessage + "\r\nAmount : " + _ECKResponse.Amount;
                if (_ECKResponse.ApprovalCode != null) strResponseMessage = strResponseMessage + "\r\nApprovalCode : " + _ECKResponse.ApprovalCode; //A code provided when a transaction is approved.
                if (_ECKResponse.ModifiedAccountNumber != null) strResponseMessage = strResponseMessage + "\r\nModifiedAccountNumber : " + _ECKResponse.ModifiedAccountNumber; //Indicates the corrected account number that should be used for electronic check processing
                if (_ECKResponse.ModifiedRoutingNumber != null) strResponseMessage = strResponseMessage + "\r\nModifiedRoutingNumber : " + _ECKResponse.ModifiedRoutingNumber; //Indicates the corrected 9-digit bank routing number that should be used for electronic check processing.
                if (_ECKResponse.ReturnInformation != null)
                {
                    if (_ECKResponse.ReturnInformation.ReturnCode != null) strResponseMessage = strResponseMessage + "\r\nReturnCode : " + _ECKResponse.ReturnInformation.ReturnCode;//Code that indicates why the transaction was returned.
                    if (_ECKResponse.ReturnInformation.ReturnDate != null) strResponseMessage = strResponseMessage + "\r\nReturnDate : " + _ECKResponse.ReturnInformation.ReturnDate; //The date the transaction was returned by the bank.
                    if (_ECKResponse.ReturnInformation.ReturnReason != null) strResponseMessage = strResponseMessage + "\r\nReturnReason : " + _ECKResponse.ReturnInformation.ReturnReason; //Reason that indicates why the transaction was returned.
                }
                if (_ECKResponse.SubmitDate != null) strResponseMessage = strResponseMessage + "\r\nSubmitDate : " + _ECKResponse.SubmitDate; //The date the transaction was submitted to the bank.

                strResponseMessage = "Your transaction was DECLINED\r\n" + strResponseMessage;
            }
            if (_ECKResponse.Status == Status.NotSet)//The transaction was declined
            {
                strResponseMessage = "No Transactions found for settlement";
            }
            return strResponseMessage;
        }