public List<ResponseDetails> ProcessBCPTransactionPro(
            TransactionType _TT //Required
            , BankcardTransactionPro _BCtransaction //Conditional : Only used for an AuthorizeAndCapture, Authorize and ReturnUnlinked. Otherwise null
            , BankcardCapturePro _BCDifferenceData //Conditional : Only used for a Capture. Otherwise null
            , List<String> _BatchIds //Conditional : A list of one or more batch Ids to capture.
            , BankcardReturn _RDifferenceData //Conditional : Only used for a ReturnById. Otherwise null
            , Adjust _ADifferenceData //Conditional : Only used for an Adjust. Otherwise null
            , BankcardUndo _UDifferenceData //Conditional : Only used for an Undo. Otherwise null
            , List<string> _TransactionIds //Conditional : Only used for a CaptureSelective. Otherwise null
            , List<Capture> _CaptureDifferenceData //Conditional : Only used for CaptureAll and CaptureSelective. Otherwise null
            , bool _SendAcknowledge
            , bool _UseWorkflowId
            , bool _ForceClose)
        {
            List<Response> _Response = new List<Response>();
            try
            {
                CheckTokenExpire();//Make sure the current token is valid

                string _serviceIdOrWorkflowId = _serviceId;
                if (_UseWorkflowId)
                    _serviceIdOrWorkflowId = _workflowId;

                if (_TT == TransactionType.AuthorizeAndCapture)
                {
                    if (CredentialRequired())
                        _BCtransaction.Addendum = CredentialsRequired(_serviceId, _credUserName, _credPassword);
                    _Response.Add(Cwsbc.AuthorizeAndCapture(_sessionToken, _BCtransaction, _applicationProfileId, _merchantProfileId, _serviceIdOrWorkflowId));
                    //Always Verify that the requested amount and approved amount are the same.
                    BankcardTransactionResponsePro BCR = new BankcardTransactionResponsePro();
                    BCR = (BankcardTransactionResponsePro)_Response[0];
                    if (_BCtransaction.TransactionData.Amount != BCR.Amount)
                        _message += "The transaction was approved for " + BCR.Amount
                            + " which is an amount not equal to the requested amount of " + _BCtransaction.TransactionData.Amount
                            + ". Please provide alternate payment to complete transaction";
                }

                if (_TT == TransactionType.Authorize)
                {
                    if (CredentialRequired())
                        _BCtransaction.Addendum = CredentialsRequired(_serviceId, _credUserName, _credPassword);
                    _Response.Add(Cwsbc.Authorize(_sessionToken, _BCtransaction, _applicationProfileId, _merchantProfileId, _serviceIdOrWorkflowId));
                    //Always Verify that the requested amount and approved amount are the same.
                    BankcardTransactionResponsePro BCR = new BankcardTransactionResponsePro();
                    BCR = (BankcardTransactionResponsePro)_Response[0];
                    if (_BCtransaction.TransactionData.Amount != BCR.Amount)
                        _message +="The transaction was approved for " + BCR.Amount
                            + " which is an amount not equal to than the requested amount of " + _BCtransaction.TransactionData.Amount
                            + ". Please provide alternate payment to complete transaction";
                }
                if (_TT == TransactionType.Capture)
                {
                    if (CredentialRequired())
                        _BCDifferenceData.Addendum = CredentialsRequired(_serviceId, _credUserName, _credPassword);
                    _Response.Add(Cwsbc.Capture(_sessionToken, _BCDifferenceData, _applicationProfileId, _serviceId));
                }
                if (_TT == TransactionType.CaptureAll)
                {
                    if (CredentialRequired())
                        _CaptureDifferenceData[0].Addendum = CredentialsRequired(_serviceId, _credUserName, _credPassword);
                    _Response = Cwsbc.CaptureAll(_sessionToken, _CaptureDifferenceData, _BatchIds, _applicationProfileId,
                                                 _merchantProfileId, _serviceId, _ForceClose);
                }
                if (_TT == TransactionType.CaptureAllAsync)
                {
                    if (CredentialRequired())
                        _CaptureDifferenceData[0].Addendum = CredentialsRequired(_serviceId, _credUserName, _credPassword);
                    _Response.Add(Cwsbc.CaptureAllAsync(_sessionToken, _CaptureDifferenceData, _BatchIds,
                                                        _applicationProfileId, _merchantProfileId, _serviceId, _ForceClose));
                }
                if (_TT == TransactionType.CaptureSelective)
                {
                    if (CredentialRequired())
                        _CaptureDifferenceData[0].Addendum = CredentialsRequired(_serviceId, _credUserName, _credPassword);
                    _Response = Cwsbc.CaptureSelective(_sessionToken, _TransactionIds, _CaptureDifferenceData,
                                                       _applicationProfileId, _serviceId);
                }
                if (_TT == TransactionType.CaptureSelectiveAsync)
                {
                    if (CredentialRequired())
                        _CaptureDifferenceData[0].Addendum = CredentialsRequired(_serviceId, _credUserName, _credPassword);
                    _Response.Add(Cwsbc.CaptureSelectiveAsync(_sessionToken, _TransactionIds, _CaptureDifferenceData,
                                                              _applicationProfileId, _serviceId));
                }
                if (_TT == TransactionType.ReturnById)
                {
                    if (CredentialRequired())
                        _RDifferenceData.Addendum = CredentialsRequired(_serviceId, _credUserName, _credPassword);
                    _Response.Add(Cwsbc.ReturnById(_sessionToken, _RDifferenceData, _applicationProfileId, _serviceId));
                }
                if (_TT == TransactionType.Return)
                {
                    if (CredentialRequired())
                        _BCtransaction.Addendum = CredentialsRequired(_serviceId, _credUserName, _credPassword);
                    _Response.Add(Cwsbc.ReturnUnlinked(_sessionToken, _BCtransaction, _applicationProfileId, _merchantProfileId, _serviceId));
                }
                if (_TT == TransactionType.Adjust)
                {
                    if (CredentialRequired())
                        _ADifferenceData.Addendum = CredentialsRequired(_serviceId, _credUserName, _credPassword);
                    _Response.Add(Cwsbc.Adjust(_sessionToken, _ADifferenceData, _applicationProfileId, _serviceId));
                }
                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())
                        _BCtransaction.Addendum = CredentialsRequired(_serviceId, _credUserName, _credPassword);
                    _Response.Add(Cwsbc.QueryAccount(_sessionToken, _BCtransaction, _applicationProfileId,
                                                     _merchantProfileId, _serviceId));
                }
                if (_TT == TransactionType.Verify)
                    _Response.Add(Cwsbc.Verify(_sessionToken, _BCtransaction, _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(), _serviceIdOrWorkflowId, _merchantProfileId, true, TypeCardType.NotSet, "");
                        _message += 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)
                {
                    _message +="Neither the primary or secondary endpoints are available. Unable to process.";
                }
                catch (Exception ex)
                {
                    _message +="Unable to AuthorizeAndCapture\r\nError Message : " + ex.Message;
                }
            }
            catch (System.TimeoutException te)
            {
                //A timeout has occured. Prompt the user if they'd like to query for the last transaction submitted
                if(_BCtransaction != null)
                {
                    _message += "A timeout has occured. A call to 'RequestTransaction' was made to obtain the transactions that should have been returned. Your code will need to reconcile transactions.";
                    RequestTransaction(_BCtransaction.TenderData);
                }
                else{throw te;}
            }
            catch (Exception ex)
            {
                string strErrorId;
                string strErrorMessage;
                if (_FaultHandler.handleTxnFault(ex, out strErrorId, out strErrorMessage))
                { _message +=strErrorId + " : " + strErrorMessage; }
                else { _message +=ex.Message; }
            }

            return null;
        }
        private void cmdPurchaseCardL3_Click(object sender, EventArgs e)
        {
            Cursor = Cursors.WaitCursor;
            //NOTE: The first step with purchase card level 2 is to submit a Authorize to verify that the card is a valid purchase card
            //Check to see if this transaction type is supported
            if (!SupportedTxnTypes.Authorize | !SupportedTxnTypes.Capture) { MessageBox.Show("Purchase card requires support for Authorize as well as Capture"); Cursor = Cursors.Default; return; }

            List<ResponseDetails> response = new List<ResponseDetails>();
            if (_bcs != null) //Process a BankCard Transaction
            {
                try
                {
                    BankcardTransactionPro BCtransaction = new BankcardTransactionPro();

                    //First Check to see if this work flow is an "AuthorizeAndCapture" or an "Authorize" followed by a "Capture".
                    if (chkL3AuthAndCapture.Checked)
                    {//In this case the work flow is a "AuthorizeAndCapture"
                        BankCardProProcessingOptions BCPO = new BankCardProProcessingOptions(PurchaseCardLevel.Level3, false, true);
                        BCtransaction = dg.SetBankCardTxnData(BCPO);
                        response = Helper.ProcessBCPTransaction(TransactionType.AuthorizeAndCapture, BCtransaction, null, null, null, null, null, null, null, ChkAcknowledge.Checked, ChkUserWorkflowId.Checked, ChkForceCloseBatch.Checked);
                        if (response.Count < 1) { return; }
                        ChkLstTransactionsProcessed.Items.Add(response[0]);
                    }
                    else
                    {//In this case the work flow is an "Authorize" followed by a "Capture"
                        BankCardProProcessingOptions BCPO = new BankCardProProcessingOptions(PurchaseCardLevel.Level3, false, false);
                        BCtransaction = dg.SetBankCardTxnData(BCPO);

                        response = Helper.ProcessBCPTransaction(TransactionType.Authorize, BCtransaction, null, null, null, null, null, null, null, ChkAcknowledge.Checked, ChkUserWorkflowId.Checked, ChkForceCloseBatch.Checked);
                        if (response.Count < 1) { return; }
                        ChkLstTransactionsProcessed.Items.Add(response[0]);
                        BankcardTransactionResponsePro BCR = (BankcardTransactionResponsePro)response[0].Response;

                        //Note : Now let's send the capture for the level 3 transaction.
                        //First verify that the card is a valid Purchase Card.
                        if (BCR.CommercialCardResponse == CommercialCardResponse.BusinessCard | BCR.CommercialCardResponse == CommercialCardResponse.CorporateCard | BCR.CommercialCardResponse == CommercialCardResponse.PurchaseCard)
                        {
                            BankcardCapturePro BCP = new BankcardCapturePro();
                            BCP.Level2Data = dg.SetLevel2Data(); //Level 3 purchase card is always inclusive of Level 1 and Level 2 data.

                            List<LineItemDetail> LIDS = new List<LineItemDetail>();
                            //For each line on the receipt the following needs to be called.
                            for (int i = 0; i < 3; i++)//Add three line items
                            {
                                LIDS.Add(dg.SetLevel3Data());
                            }
                            BCP.LineItemDetails = LIDS;
                            BCP.TransactionId = BCR.TransactionId;//Set the transactionId to the original Authorize
                            response = Helper.ProcessBCPTransaction(TransactionType.Capture, null, BCP, null, null, null, null, null, null, ChkAcknowledge.Checked, false, ChkForceCloseBatch.Checked);
                            if (response.Count < 1) { return; }
                            ChkLstTransactionsProcessed.Items.Add(response[0]);
                        }
                        else
                        {
                            MessageBox.Show("Capture failed as Card PAN was not a valid Level 2 or Level 3 purchase Card");
                        }
                    }
                }
                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; }
            }
        }
 public bool validateTrackData(ref BankcardTransactionPro _BCtransaction, string _SwipedTrackData)
 {
     //NOTE: The following assumes that you have already seperated track 1 from track 2 and selected which one to use
     Regex regTrackData1 = new Regex(@"^([B|b][\d ]{12,19}\^[ \S-[%\?]]{1,29}\^\d{2}((1[0-2])|(0\d))[ \S-[%\?]]{1,60})$");
     Regex regTrackData2 = new Regex(@"^([\d]{12,19}=\d{2}((1[0-2])|(0\d))[ \S-[;\?]]{1,22})$");
     if (regTrackData2.IsMatch(_SwipedTrackData))
     {//Track 2 Match - You'll have to remove the starting and ending sentinal
         _BCtransaction.TenderData.CardData.Track2Data = _SwipedTrackData;
     }
     else if (regTrackData1.IsMatch(_SwipedTrackData))
     {//Track 1 Match
         _BCtransaction.TenderData.CardData.Track1Data = _SwipedTrackData;
     }
     else
     {
         return false;
     }
     return true;
 }
        private void cmdPurchaseCardL2_Click(object sender, EventArgs e)
        {
            Cursor = Cursors.WaitCursor;

            if (_bcs != null) //Process a BankCard Transaction
            {
                //NOTE: The first step with purchase card level 2 is to submit a Authorize to verify that the card is a valid purchase card
                //Check to see if this the service is a host capture or terminal capture solution. This will drive logice in terms of useing an AuthorizeAndCapture Versus Authorize to Capture
                if (_bcs.Tenders.CreditAuthorizeSupport == CreditAuthorizeSupportType.AuthorizeOnly)//In this case it's a Host capture so either an Authorize followed by capture or AuthorizeAndCapture should be used.
                    if (!SupportedTxnTypes.Authorize && !SupportedTxnTypes.AuthAndCapture) { MessageBox.Show("Purchase card requires support for Authorize or AuthorizeAndCapture"); Cursor = Cursors.Default; return; }
                    else//In this case its a terminal capture service which requires an Authorize followed by a captureall or capture selective
                        if (!SupportedTxnTypes.Authorize | !SupportedTxnTypes.CaptureAll) { MessageBox.Show("Purchase card requires support for Authorize as well as CaptureAll or CaptureSelective"); Cursor = Cursors.Default; return; }

                List<ResponseDetails> response = new List<ResponseDetails>();
                try
                {
                    BankcardTransactionPro BCtransaction = new BankcardTransactionPro();
                    //First Check to see if this work flow is an "AuthorizeAndCapture" or an "Authorize" followed by a "Capture".
                    if (chkL2AuthAndCapture.Checked && _bcs.Tenders.CreditAuthorizeSupport == CreditAuthorizeSupportType.AuthorizeOnly)
                    {//In this case the work flow is a "AuthorizeAndCapture"
                        BankCardProProcessingOptions BCPO = new BankCardProProcessingOptions(PurchaseCardLevel.Level2, false, true);
                        BCtransaction = dg.SetBankCardTxnData(BCPO);
                        response = Helper.ProcessBCPTransaction(TransactionType.AuthorizeAndCapture, BCtransaction, null, null, null, null, null, null, null, ChkAcknowledge.Checked, ChkUserWorkflowId.Checked, ChkForceCloseBatch.Checked);
                        if (response.Count < 1) { return; }
                        ChkLstTransactionsProcessed.Items.Add(response[0]);
                    }
                    else if (!chkL2AuthAndCapture.Checked)
                    {//In this case the work flow is an "Authorize" followed by a "Capture"
                        BankCardProProcessingOptions BCPO = new BankCardProProcessingOptions(PurchaseCardLevel.Level2, false, false);
                        BCtransaction = dg.SetBankCardTxnData(BCPO);

                        response = Helper.ProcessBCPTransaction(TransactionType.Authorize, BCtransaction, null, null, null, null, null, null, null, ChkAcknowledge.Checked, ChkUserWorkflowId.Checked, ChkForceCloseBatch.Checked);
                        if (response.Count < 1) { return; }
                        ChkLstTransactionsProcessed.Items.Add(response[0]);
                        BankcardTransactionResponsePro BCR = (BankcardTransactionResponsePro)response[0].Response;

                        //Note : Now let's send the capture for the level 2 transaction.
                        //First verify that the card is a valid Purchase Card.
                        if (BCR.CommercialCardResponse == CommercialCardResponse.BusinessCard | BCR.CommercialCardResponse == CommercialCardResponse.CorporateCard | BCR.CommercialCardResponse == CommercialCardResponse.PurchaseCard)
                        {
                            BankcardCapturePro BCP = new BankcardCapturePro();
                            BCP.Level2Data = dg.SetLevel2Data();
                            BCP.TransactionId = BCR.TransactionId;//Set the transactionId to the original Authorize

                            response = Helper.ProcessBCPTransaction(TransactionType.Capture, null, BCP, null, null, null, null, null, null, ChkAcknowledge.Checked, false, ChkForceCloseBatch.Checked);
                            if (response.Count < 1) { return; }
                            ChkLstTransactionsProcessed.Items.Add(response[0]);
                        }
                        else
                        {
                            MessageBox.Show("Capture failed as Card PAN was not a valid Level 2 or Level 3 purchase Card");
                        }
                    }
                    else
                    {
                        MessageBox.Show("Unable to process purchase Card as the transaction types requested are not supported. Specifically AuthorizeAndCapture");
                    }
                }
                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; }
            }
        }