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)
        {
            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)
                        MessageBox.Show("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)
                        MessageBox.Show("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())
                        _BCDifferenceData.Addendum = CredentialsRequired(_serviceId, _credUserName, _credPassword);
                    _Response = Cwsbc.CaptureAll(_sessionToken, _CaptureDifferenceData, _BatchIds, _applicationProfileId,
                                                 _merchantProfileId, _serviceId);
                }
                if (_TT == TransactionType.CaptureAllAsync)
                {
                    if (CredentialRequired())
                        _BCDifferenceData.Addendum = CredentialsRequired(_serviceId, _credUserName, _credPassword);
                    _Response.Add(Cwsbc.CaptureAllAsync(_sessionToken, _CaptureDifferenceData, _BatchIds,
                                                        _applicationProfileId, _merchantProfileId, _serviceId));
                }
                if (_TT == TransactionType.CaptureSelective)
                {
                    if (CredentialRequired())
                        _BCDifferenceData.Addendum = CredentialsRequired(_serviceId, _credUserName, _credPassword);
                    _Response = Cwsbc.CaptureSelective(_sessionToken, _TransactionIds, _CaptureDifferenceData,
                                                       _applicationProfileId, _serviceId);
                }
                if (_TT == TransactionType.CaptureSelectiveAsync)
                {
                    if (CredentialRequired())
                        _BCDifferenceData.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, "");
                        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(_BCtransaction != 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(_BCtransaction.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;
        }
 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 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 = SetBankCardTxnData(BCPO);
                        response = Helper.ProcessBCPTransaction(TransactionType.AuthorizeAndCapture, BCtransaction, null, null, null, null, null, null, null, ChkAcknowledge.Checked, ChkUserWorkflowId.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 = SetBankCardTxnData(BCPO);

                        response = Helper.ProcessBCPTransaction(TransactionType.Authorize, BCtransaction, null, null, null, null, null, null, null, ChkAcknowledge.Checked, ChkUserWorkflowId.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 = 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(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);
                            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; }
            }
        }
        private BankcardTransactionPro SetBankCardTxnData(BankCardProProcessingOptions _BCPPO)
        {
            //Note : the following values apply to the BankcardTransaction
            BankcardTransactionPro BCtransaction = new BankcardTransactionPro();
            BankcardTransactionDataPro TxnData = new BankcardTransactionDataPro();//The following is necessary due to inheritance
            
            //The following are typical settings please ask your solution consultant if you have any questions
            TxnData.Amount = Convert.ToDecimal(TxtAmount.Text);
            #region Ways to Convert to a decimal with two decimals
            //Note : Decimal Example please remember that the amount must always be two decimals "0.00"
            //decimal dAmount = 10;
            //TxnData.Amount = Convert.ToDecimal(dAmount);
            //TxnData.Amount = Decimal.Parse(TxnData.Amount.ToString("0.00"));
            //Or Simply
            //TxnData.Amount = Decimal.Parse(TxnData.Amount.ToString("0.00"));

            //Note : String Example please remember that the amount must always be two decimals "0.00"
            //string strAmount = "10";
            //TxnData.Amount = Convert.ToDecimal(strAmount);
            //TxnData.Amount = Decimal.Parse(TxnData.Amount.ToString("0.00"));

            //Note : Int Example please remember that the amount must always be two decimals "0.00"
            //int intAmount = 10;
            //TxnData.Amount = Convert.ToDecimal(intAmount);
            //TxnData.Amount = Decimal.Parse(TxnData.Amount.ToString("0.00"));
            //Or
            //((int)(100 * amount)) * 0.01m;

            #endregion Ways to Convert to a decimal with two decimals
            TxnData.CurrencyCode = TypeISOCurrencyCodeA3.USD;
            try { TxnData.EntryMode = (EntryMode)Enum.Parse(typeof(EntryMode), ConfigurationSettings.AppSettings["TxnData_EntryMode"]); }catch { }
            try { TxnData.CustomerPresent = (CustomerPresent)Enum.Parse(typeof(CustomerPresent), ConfigurationSettings.AppSettings["TxnData_CustomerPresent"]); }catch { }
            try { TxnData.SignatureCaptured = Convert.ToBoolean(ConfigurationSettings.AppSettings["TxnData_SignatureCaptured"]); }catch { }
            
			//Used for Vantiv
            TxnData.TransactionDateTime = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss.fffzzz");
			
            //In the case of Retail or Restaurant
            //TxnData.TipAmount = 3.00M;

            // Used for QuasiCash transactions
            TxnData.IsQuasiCash = false;

			TxnData.LaneId = "1";//Used for Vantiv Tandem
			
            //Used for Retail/Restaurant/MOTO
            TxnData.EmployeeId = "123456";
            
            //Used for Ecommerce/MOTO
            TxnData.OrderNumber = "123543"; //This values must be unique for each transaction. OrderNum should never be zero
            //TxnData.GoodsType = GoodsType.PhysicalGoods;

            TxnData.TransactionDateTime = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss.fffzzz");

            // The below value is to support partial authorizations as mandated by Visa and Mastercard
            // First check to see if the service supports partial approvals, if it does then set the flag
            // that this transaction will support that partial approval.  Remember to parse your Response.Amount to verify 
            // the amount that was approved.  Card Not Present applications do not need to abide by the partial approval mandate
            if (_bcs.Tenders.PartialApprovalSupportType == schemas.ipcommerce.com.Ipc.General.WCF.Contracts.Common.External.SvcInfo.PartialApprovalSupportType.Enabled)
                TxnData.PartialApprovalCapable = PartialApprovalSupportType.Capable;

            BCtransaction.CustomerData = new TransactionCustomerData();
            BCtransaction.CustomerData.CustomerId = TxnData.OrderNumber;


            BCtransaction.CustomerData.BillingData = new CustomerInfo();
            BCtransaction.CustomerData.BillingData.Address = new AddressInfo();
            BCtransaction.CustomerData.BillingData.Address.Street1 = "123 Fake Pl";
            BCtransaction.CustomerData.BillingData.Address.City = "Beverly Hills";
            BCtransaction.CustomerData.BillingData.Address.PostalCode = "90120";
            BCtransaction.CustomerData.BillingData.Address.CountryCode = TypeISOCountryCodeA3.USA;

            BCtransaction.CustomerData.ShippingData = new CustomerInfo();
            BCtransaction.CustomerData.ShippingData.Address = new AddressInfo();
            BCtransaction.CustomerData.ShippingData.Address.Street1 = "456 Face St";
            BCtransaction.CustomerData.ShippingData.Address.City = "Westminster";
            BCtransaction.CustomerData.ShippingData.Address.PostalCode = "80031";
            BCtransaction.CustomerData.ShippingData.Address.CountryCode = TypeISOCountryCodeA3.USA;


            BCtransaction.TenderData = new BankcardTenderData();
            BCtransaction.TenderData.CardData = new CardData();

            //Process as a Swipe or as a Keyed Transaction
            if (Convert.ToBoolean(ConfigurationSettings.AppSettings["TxnData_ProcessAsKeyed"]))
            {//Keyed Transaction
                BCtransaction.TenderData.CardData.CardType = TypeCardType.MasterCard;
                BCtransaction.TenderData.CardData.Expire = "1213"; // Note : that in a swipe track data the format is "YYMM" however here it's "MMYY"
                BCtransaction.TenderData.CardData.PAN = "5454545454545454";
                BCtransaction.TenderData.CardData.CardholderName = "Dirk Pit";
            }
            else
            {//Swiped Transaction
                #region Card Validation Samples (Optional however good reference for sending valid card swipes)

                //NOTE Example : In the case of processing a card swipe string use the following.
                //NOTE Example : The following will remove starting and ending sentenals
                BCtransaction.TenderData.CardData.CardType = TypeCardType.MasterCard;
                string SwipeToSeperateTracks = "%B5454545454545454^IPCOMMERCE/TESTCARD^1312101013490000000001000880000?;5454545454545454=13121010134988000010?";
                TrackFromMSRSwipe TFMSRS = Helper.seperateTrackData(SwipeToSeperateTracks);

                string[] TrackProcessingOrder = ConfigurationSettings.AppSettings["TxnData_OrderOfProcessingTracks"].Split('|');
                foreach (string track in TrackProcessingOrder)
                {
                    if (track == "Track1")
                        if (Helper.validateTrackData(ref BCtransaction, TFMSRS.Track1Data)) break;
                    if (track == "Track2")
                        if (Helper.validateTrackData(ref BCtransaction, TFMSRS.Track2Data)) break;
                    if (track == "Keyed")
                    {
                        DialogResult Result;
                        Result = MessageBox.Show("Neither Track 1 nor Track 2 match. Process as a Keyed transaction instead?",
                                    "Process as Keyed", MessageBoxButtons.OKCancel);
                        if (Result == DialogResult.Cancel){Exception e = new Exception("Neither Track 1 or Track 2 is valid. Plesae swipe again"); throw e;}
                        TxnData.EntryMode = EntryMode.Keyed;
                        BCtransaction.TenderData.CardData.CardType = TypeCardType.MasterCard;
                        BCtransaction.TenderData.CardData.Expire = "1213"; // Note : that in a swipe track data the format is "YYMM" however here it's "MMYY"
                        BCtransaction.TenderData.CardData.PAN = "5454545454545454";
                        break;
                    }
                }
               
                //Note : Other Track Examples (includes track 1 track 2 and an example of track 3)
                //MasterCard : %B5454545454545454^IPCOMMERCE/TESTCARD^1312101013490000000001000880000?;5454545454545454=13121010134988000010?
                //MasterCardPurchase : %B5480020605154711^IPCOMMERCE/TESTCARD^1312101100000001000000218000000?;5480020605154711=13121011000017026218?
                //MasterCardSigDebit : %B9999989900007723^IPCOMMERCE/TESTCARD^13121015432112345678?;9999989900007723=13121015432112345678?
                //Visa : %B4111111111111111^IPCOMMERCE/TESTCARD^13121010454500415000010?;4111111111111111=13121010454541500010?
                //Visa Purchasecard : %B4005765777003^IPCOMMERCE/TESTCARD^13121015432112345678?;4005765777003=13121015432112345678?
                //AmericanExpress : %B371449635398456^IPCOMMERCE/TESTCARD^1312060523319?;371449635398456=1312060523319?
                //Discover : %B6011000995504101^IPCOMMERCE/TESTCARD^13121011000627210201?;6011000995504101=13121011000627210201?
                //The following track includes a track 3 which is possible in Costco American Express cards %B371449635398456^IPCOMMERCE/TESTCARD^1312060523319?;371449635398456=1312060523319?+823156444000?

                #endregion Card Validation Samples (Optional however good reference for sending valid card swipes)
            }

            #region Simulating a flag used to set either AVS CV or PINDebit data
            //Simulating a flag used to set either AVS, CV data or PINDebit
            bool blnAVS = false;
            bool blnCVV = false;

            try { blnAVS = Convert.ToBoolean(ConfigurationSettings.AppSettings["TxnData_IncludeAVS"]); }catch { };
            try { blnCVV = Convert.ToBoolean(ConfigurationSettings.AppSettings["TxnData_IncludeCV"]); }catch { };

            if (blnAVS | blnCVV | chkProcessAsPINDebitTxn.Checked)
            {
                BCtransaction.TenderData.CardSecurityData = new CardSecurityData(); //Required if AVS or CV is used
                if (blnAVS)
                {
                    //AVSData
                    BCtransaction.TenderData.CardSecurityData.AVSData = new AVSData();
                    //Required AVS Elements
                    BCtransaction.TenderData.CardSecurityData.AVSData.PostalCode = "80023";
                    //Optional AVS Elements
                    BCtransaction.TenderData.CardSecurityData.AVSData.CardholderName = "John Smith";
                    BCtransaction.TenderData.CardSecurityData.AVSData.City = "Mason";
                    BCtransaction.TenderData.CardSecurityData.AVSData.Country = TypeISOCountryCodeA3.USA;
                    BCtransaction.TenderData.CardSecurityData.AVSData.Phone = "513 5456699"; //Must be of format "NNN NNNNNNN"
                    BCtransaction.TenderData.CardSecurityData.AVSData.StateProvince = "OH";
                    BCtransaction.TenderData.CardSecurityData.AVSData.Street = "1234 IrwinSimpaon";
                }
                if (blnCVV)
                {
                    //CVData
                    string strCVData = "111"; //Please note that this would typically be an input field in the application.
                    if (strCVData.Length > 0)
                    {
                        BCtransaction.TenderData.CardSecurityData.CVDataProvided = CVDataProvided.Provided;
                        BCtransaction.TenderData.CardSecurityData.CVData = strCVData;
                    }
                    else
                    {
                        //In this case the card was present (Retail or Restaurant) however the CV code was not readable or available
                        BCtransaction.TenderData.CardSecurityData.CVDataProvided = CVDataProvided.DeliberatelyBypass;
                    }
                }
                //Check to see if the transaction is a PINDebit Transaction
                if (chkProcessAsPINDebitTxn.Checked)
                {
                    BCtransaction.TenderData.CardSecurityData.KeySerialNumber = "1234567890123456";
                    BCtransaction.TenderData.CardSecurityData.PIN = "1234567890";
                    TxnData.AccountType = AccountType.CheckingAccount;
                }
            }
            #endregion END Simulating a flag used to set either AVS CV or PINDebit data

            #region Check to see if PINLessDebit selected

            if(ChkProcessAsPINLessDebit.Checked)
            {
                TxnData.PINlessDebitData = new PINlessDebitData();
                TxnData.PINlessDebitData.PayeeData = new PayeeData();
                TxnData.PINlessDebitData.PayeeData.AccountNumber = "000056";
                TxnData.PINlessDebitData.PayeeData.CompanyName = "ABC Company";
                TxnData.PINlessDebitData.PayeeData.Phone = "555 1238888";
            }

            #endregion END Check to see if PINLessDebit selected

            //#region Simulating a flag used to set Magensa data
            ////Simulating a flag used to set either AVS, CV data or PINDebit
            //bool blnMagensa = false;

            //try { blnMagensa = Convert.ToBoolean(ConfigurationSettings.AppSettings["TxnData_ProcessMagensaTxn"]); }
            //catch { };

            //if (blnMagensa)
            //{ //*** ToDo : the following are generic values which will only work against Sandbox.***
            //    //First set the CardData to null
            //    BCtransaction.TenderData.CardData = null;

            //    if (BCtransaction.TenderData.CardSecurityData == null) { BCtransaction.TenderData.CardSecurityData = new CardSecurityData(); }
            //    BCtransaction.TenderData.CardSecurityData.CVData = null;
            //    BCtransaction.TenderData.CardSecurityData.CVDataProvided = CVDataProvided.NotSet;
            //    BCtransaction.TenderData.CardSecurityData.IdentificationInformation = "A52AFB9FB5B283A6C8C38377A6CB1D2C63CC59D3B0B29D2A0DF1C9A54F123D37536756C77B4A9B75E51BF028B51971E81C8B221533A3AFF4";

            //    BCtransaction.TenderData.SecurePaymentAccountData = "13A7783BD91D0A05712606644778CF8F34397EAC2AB26676A52A380350CAA07E";

            //    BCtransaction.TenderData.EncryptionKeyId = "9011400B042692000398";
            //    BCtransaction.TenderData.SwipeStatus = "1065057";

            //    TxnData.ScoreThreshold = ".5";
            //    TxnData.EntryMode = EntryMode.Track2DataFromMSR;
            //    TxnData.Reference = "11";

            //}
            //#endregion Simulating a flag used to set Magensa data

            #region Pro specific functionality
            //Note : BankcardTransactionPro
            //The following sections are specific to the Pro object
            //Applications that will support Level 2, Level 3, and Managed Billing (recurring/installment payments) data may be
            //required to provide the following data elements in addition to the Base Transaction and Bankcard
            //Transaction data elements described above.
            if (Convert.ToBoolean(ConfigurationSettings.AppSettings["ProcessAsBankcardTransaction_Pro"]) | _BCPPO != null)//Determines if additional Pro objects should be used.
            {
                PurchaseCardLevel PCL;
                bool InterchangeData;
                bool L2L3;
                if(_BCPPO != null)
                {//In this case an override was passed in
                    PCL = _BCPPO.PurchaseCardLevel;
                    InterchangeData = _BCPPO.InterchangeData;
                    L2L3 = _BCPPO.IncludeLevel2OrLevel3Data;
                }
                else
                {//Use the default values in the app.config
                    PCL = (PurchaseCardLevel)Enum.Parse(typeof(PurchaseCardLevel), ConfigurationSettings.AppSettings["Pro_PurchaseCardLevel"]);
                    InterchangeData = Convert.ToBoolean(ConfigurationSettings.AppSettings["Pro_InterchangeData"]);
                    L2L3 = Convert.ToBoolean(ConfigurationSettings.AppSettings["Pro_IncludeLevel2OrLevel3Data"]);
                }

                #region Purchase Card Level 2 or Level 3
                if (PCL == PurchaseCardLevel.Level2 | PCL == PurchaseCardLevel.Level3)
                {
                    /*
                        For AuthorizeAndCapture the level2/3 goes in immediately as there is no follow up transaction.
                        For Authorize followed by Capture the level 2/3 goes in the Capture, never in the Authorize.  
                        The schema requires BaseAmt and OrderNum for level 2.  Amt, Quantity, SeqNum, TaxIncludedInd, and UnitPrice are all required for level 3.
                        • Of course you must have level 2 in order to have level 3.
                        Set TxnData.CmrclCardReq to “Enable” since some providers get that value and will return the card type in the response in CmrclCardResp.  Not all providers do this but they should always set it.  
                        The value is returned in the response and can be used to determine whether or not to submit level 2.

                        Level 2 requirements for Ecomm/Moto:
                        • TaxExempt
                        • DestinationPostal
                        • ShipFromPostalCode
                        Level 2 requirements for Retail:
                        • DestinationPostal
                        • TaxExempt                   
                        Level 3 requirements for Ecomm/Moto:
                        • Desc
                        • ProductCode
                        • UnitOfMeasure
                        • only 98 items allowed
                    */

                    //Send with the original Authorize with the "RequestCommerciaCard" flag set. In the response you will reference
                    //"CommercialCardResponse" as the indicator that the card is a valid Level 2 or Level 3 card.
                    BCtransaction.InterchangeData = new BankcardInterchangeData();
                    BCtransaction.InterchangeData.RequestCommercialCard = RequestCommercialCard.Enable;

                    if (L2L3 & PCL == PurchaseCardLevel.Level2)
                    {//Level 2 data
                        TxnData.Level2Data = SetLevel2Data();

                        if (BCtransaction.TenderData.CardData.CardType == TypeCardType.AmericanExpress)
                        {
                            BCtransaction.CustomerData = new TransactionCustomerData();
                            BCtransaction.CustomerData.ShippingData = new CustomerInfo();
                            BCtransaction.CustomerData.ShippingData.Name = new NameInfo();
                            BCtransaction.CustomerData.ShippingData.Address = new AddressInfo();

                            //For Amex only cards. Amex only supports Purchase Card Level 2
                            BCtransaction.CustomerData.ShippingData.Name.First = "Dan"; //Full name or parameterized name.
                            BCtransaction.CustomerData.ShippingData.Name.Middle = "Joe";
                            BCtransaction.CustomerData.ShippingData.Name.Last = "Billings";

                            BCtransaction.CustomerData.ShippingData.Address.Street1 = "123 HappyWay";
                            //BCtransaction.CustomerData.ShippingData.Address.Street2 = "";
                            BCtransaction.CustomerData.ShippingData.Address.City = "Mason";
                            BCtransaction.CustomerData.ShippingData.Address.StateProvince = "OH";
                            BCtransaction.CustomerData.ShippingData.Address.PostalCode = "45040";
                            BCtransaction.CustomerData.ShippingData.Address.CountryCode = TypeISOCountryCodeA3.USA;
                        }
                    }
                    if (L2L3 & PCL == PurchaseCardLevel.Level3)
                    {//Level 3 data
                        TxnData.Level2Data = SetLevel2Data();

                        //Level 3 data includes Level 2 data plus line items details. in this case your application should handle calling the following
                        // for each line item
                        List<LineItemDetail> LIDs = new List<LineItemDetail>();
                        LineItemDetail LID = new LineItemDetail();
                        LID = SetLevel3Data();
                        LIDs.Add(LID);
                        TxnData.LineItemDetails = LIDs;
                    }
                }

                #endregion Purchase Card Level 2 or Level 3

                #region Recurring/Bill Payments

                if (InterchangeData)
                {
                    BCtransaction.InterchangeData = new BankcardInterchangeData();

                    //Single Payment
                    BCtransaction.InterchangeData.BillPayment = BillPayment.SinglePayment;
                    BCtransaction.InterchangeData.ExistingDebt = ExistingDebt.IsExistingDebt;

                    /*
                    //Deferred Billing
                    BCtransaction.InterchangeData.BillPayment = BillPayment.DeferredBilling;
                    BCtransaction.InterchangeData.ExistingDebt = ExistingDebt.IsExistingDebt;
        
                    //Installment
                    BCtransaction.InterchangeData.BillPayment = BillPayment.Installment;
                    BCtransaction.InterchangeData.ExistingDebt = ExistingDebt.IsExistingDebt;
                    BCtransaction.InterchangeData.CurrentInstallmentNumber = 1;
                    BCtransaction.InterchangeData.TotalNumberOfInstallments = 3;
                    */
                    //Recurring
                    //Note: Any time recurring payments are used for any BCP service MultiClearSeqNum should be 1 for the first payment and any number 
                    //greater than 1 for the additional recurring payments.  The software company doesn’t have to count payments.  
                    //They can always send 2 for the additional transactions if they want. Sending the 1 sends a code to the service provider that this 
					//is the first payment and CVData and AVSData are expected.  Sending greater than 1 means that the lack of CVData and AVSData is OK 
					//since they don’t have to store or submit that data with the additional payments.
                    BCtransaction.InterchangeData.BillPayment = BillPayment.Recurring;
                    BCtransaction.InterchangeData.ExistingDebt = ExistingDebt.IsExistingDebt;
                    BCtransaction.InterchangeData.CurrentInstallmentNumber = 1; //If this is a follow-up recuring payment the value needs to be greater than 1. 

                    //Any time BillPayInd is set to either “Deferred_Billing”, “Installment” or “Recurring”, CustPresentFlag should be set to “Bill_Payment"
                    if( BCtransaction.InterchangeData.BillPayment == BillPayment.DeferredBilling | BCtransaction.InterchangeData.BillPayment == BillPayment.Installment | BCtransaction.InterchangeData.BillPayment == BillPayment.Recurring)
                        TxnData.CustomerPresent = CustomerPresent.BillPayment;
                }

                #endregion Recurring/Bill Payments

            }
            #endregion END-Pro specific functionality

            #region Verified By Visa (VbV/VPAS)
            bool blnVPAS = false;
            try { blnVPAS = Convert.ToBoolean(ConfigurationSettings.AppSettings["TxnData_IncludeVPAS"]); }catch { };
            /* IF supported
                If a token is obtained:
                    TenderData/EcommerceSecurityData/TokenData is required and contains the token provided by the service.
                    TenderData/EcommerceSecurityData/TokenInd is required and must be set to VPAS_3D_Secure_V100 or VPAS_3D_Secure_V102.  Even if the merchant has a newer version, either setting will work for any version.
                    TxnData/EcommerceData/PayTypeInd is required and must be set to Secure_Ecom.
                    TenderData/EcommerceSecurityData/XID is optional and may contain the Visa XID value.
                If VbV is supported but the token could not be obtained:
                    TenderData/EcommerceSecurityData/TokenData will not be populated.
                    TenderData/EcommerceSecurityData/TokenInd is required and must be set to Attempted_Card_Unsupported or Attempted_Service_Unavailable.
                    TxnData/EcommerceData/PayTypeInd is required and must be set to Non_authenticated_Security_Without_SSL or Non_authenticated_Security_With_SSL.
             */
            if (blnVPAS && BCtransaction.TenderData.CardData.CardType == TypeCardType.Visa)
            {
                //Token Obtained
                BCtransaction.TenderData.EcommerceSecurityData.TokenData = "";
                BCtransaction.TenderData.EcommerceSecurityData.TokenIndicator = TokenIndicator.VPAS;
                //TODO :TxnData.
                BCtransaction.TenderData.EcommerceSecurityData.XID = "";

                //No Token Obtained
                BCtransaction.TenderData.EcommerceSecurityData.TokenIndicator = TokenIndicator.AttemptedCardUnsupported;
                //TODO :TxnData.
            }
            #endregion Verified By Visa (VbV/VPAS)

            #region MasterCard Secure Code (MCSC/UCAF)
            bool blnUCAF = false;
            try { blnUCAF = Convert.ToBoolean(ConfigurationSettings.AppSettings["TxnData_IncludeUCAF"]); }catch { };
            /*
             * If a token is obtained:
                    TenderData/EcommerceSecurityData/TokenData is required and contains the token provided by the service.
                    TenderData/EcommerceSecurityData/TokenInd is required and must be set to UCAF or UCAF_With_Data.
                    TxnData/EcommerceData/PayTypeInd is required and must be set to Secure_Ecom.
               If MCSC is supported but the token could not be obtained or will not be sent with the transaction:
                    TenderData/EcommerceSecurityData/TokenData will not be populated.
                    TenderData/EcommerceSecurityData/TokenInd is required and must be set to Attempted_Card_Unsupported, Attempted_Service_Unavailable, or UCAF_Without_Data.
                    TxnData/EcommerceData/PayTypeInd is required and must be set to either Non_authenticated_Security_Without_SSL or Non_authenticated_Security_With_SSL.
             */
            if (blnUCAF && BCtransaction.TenderData.CardData.CardType == TypeCardType.MasterCard)
            {
                //Token Obtained
                BCtransaction.TenderData.EcommerceSecurityData.TokenData = "";
                BCtransaction.TenderData.EcommerceSecurityData.TokenIndicator = TokenIndicator.UCAFWithData;
                //TODO :TxnData.
                BCtransaction.TenderData.EcommerceSecurityData.XID = "";

                //No Token Obtained
                BCtransaction.TenderData.EcommerceSecurityData.TokenIndicator = TokenIndicator.AttemptedCardUnsupported;
                //TODO :TxnData.
            }
            #endregion MasterCard Secure Code (MCSC/UCAF)

            # region Convenience Fees

            //Simulating a flag used to include Convenience Fees
            bool cFees = false;

            try { cFees = Convert.ToBoolean(ConfigurationSettings.AppSettings["TxnData_IncludeCFees"]); }catch { };

            if (cFees)
            {
                //TxnData.FeeAmount = 5.00M;
            }

            # endregion Convenience Fees

            #region Soft Descriptors

            //Simulating setting soft descriptors
            try
            {
                if (Convert.ToBoolean(ConfigurationSettings.AppSettings["TxnData_SoftDescriptors"]))
                {
                    TxnData.AlternativeMerchantData = Helper.SetSoftDescriptors();
                }
            }
            catch { };

            #endregion Soft Descriptors
            
            BCtransaction.TransactionData = TxnData;
            return BCtransaction;
        }
        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 = SetBankCardTxnData(BCPO);
                        response = Helper.ProcessBCPTransaction(TransactionType.AuthorizeAndCapture, BCtransaction, null, null, null, null, null, null, null, ChkAcknowledge.Checked, ChkUserWorkflowId.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 = SetBankCardTxnData(BCPO);

                        response = Helper.ProcessBCPTransaction(TransactionType.Authorize, BCtransaction, null, null, null, null, null, null, null, ChkAcknowledge.Checked, ChkUserWorkflowId.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 = 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);
                            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; }
            }
        }