public CreditCardReceipt(String response)
            : base(response)
        {
            // parse the approval info
            if (this.isApproved()) {
                this.approvalInfo = new ApprovalInfo(
                    this.parseLong("AUTHORIZED_AMOUNT"),
                    (String) this.responseParams["APPROVAL_CODE"],
                    this.parseInteger("TRACE_NUMBER"),
                    (String) this.responseParams["REFERENCE_NUMBER"]);
            } else {
                this.approvalInfo = null;
            }
            // parse the AVS response
            bool avsResponseAvailable = this.parseBoolean("AVS_RESPONSE_AVAILABLE");
            if (avsResponseAvailable) {
                this.avsResponse = new AvsResponse(
                    (String) this.responseParams["AVS_RESPONSE_CODE"],
                    this.parseBoolean("STREET_MATCHED"),
                    this.parseBoolean("ZIP_MATCHED"),
                    (String) this.responseParams["ZIP_TYPE"],
                    (String) this.responseParams["AVS_ERROR_CODE"],
                    (String) this.responseParams["AVS_ERROR_MESSAGE"]);
            } else {
                this.avsResponse = null;
            }
            // parse the CVV2 response
            bool cvv2ResponseAvailable = this
                .parseBoolean("CVV2_RESPONSE_AVAILABLE");
            if (cvv2ResponseAvailable) {
                this.cvv2Response = new Cvv2Response(
                    (String) this.responseParams["CVV2_RESPONSE_CODE"],
                    (String)this.responseParams["CVV2_RESPONSE_MESSAGE"]);
            } else {
                this.cvv2Response = null;
            }

            long periodicPurchaseId = this.parseLong("PERIODIC_TRANSACTION_ID");
            if (periodicPurchaseId >= 0) {
                PeriodicPurchaseInfo.State periodicPurchaseState =
                    PeriodicPurchaseInfo.State.fromCode(this.parseShort("PERIODIC_TRANSACTION_STATE"));
                DateTime nextPaymentDate = this.parseDateTime("PERIODIC_NEXT_PAYMENT_DATE");
                long lastPaymentId = this.parseLong("PERIODIC_LAST_PAYMENT_ID");

                this.periodicPurchaseInfo = new PeriodicPurchaseInfo(periodicPurchaseId, periodicPurchaseState, nextPaymentDate, lastPaymentId);
            }else {
                this.periodicPurchaseInfo = null;
            }

            // Parse newely added fields
            this.sanitizedCardNumber = (String) this.responseParams["CARD_NUMBER"];
            this.storageTokenExpiryDate = this.parseShort("STORAGE_TOKEN_EXPIRY");
            this.responseHash = (String)this.responseParams["RESPONSE_HASH"];
            this.cardBrand = this.parseInteger("CARD_BRAND");
            this.storageTokenId = (String)this.responseParams["STORAGE_TOKEN_ID"];

            this.fraudScore = this.parseInteger("FRAUD_SCORE");
            this.fraudDecision = (String)this.responseParams["FRAUD_DECISION"];
            this.fraudSessionId = (String)this.responseParams["FRAUD_SESSION_ID"];
        }
        public CreditCardReceipt(String response)
            : base(response)
        {
            // parse the approval info
            if (this.isApproved()) {
                this.approvalInfo = new ApprovalInfo(
                    this.parseLong("AUTHORIZED_AMOUNT"),
                    (String) this.responseParams["APPROVAL_CODE"],
                    this.parseInteger("TRACE_NUMBER"),
                    this.parseInteger("REFERENCE_NUMBER"));
            } else {
                this.approvalInfo = null;
            }
            // parse the AVS response
            bool avsResponseAvailable = this.parseBoolean("AVS_RESPONSE_AVAILABLE");
            if (avsResponseAvailable) {
                this.avsResponse = new AvsResponse(
                    (String) this.responseParams["AVS_RESPONSE_CODE"],
                    this.parseBoolean("STREET_MATCHED"),
                    this.parseBoolean("ZIP_MATCHED"),
                    (String) this.responseParams["ZIP_TYPE"],
                    (String) this.responseParams["AVS_ERROR_CODE"],
                    (String) this.responseParams["AVS_ERROR_MESSAGE"]);
            } else {
                this.avsResponse = null;
            }
            // parse the CVV2 response
            bool cvv2ResponseAvailable = this
                .parseBoolean("CVV2_RESPONSE_AVAILABLE");
            if (cvv2ResponseAvailable) {
                this.cvv2Response = new Cvv2Response(
                    (String) this.responseParams["CVV2_RESPONSE_CODE"],
                    (String)this.responseParams["CVV2_RESPONSE_MESSAGE"]);
            } else {
                this.cvv2Response = null;
            }

            // parse periodic purchase info
            long periodicPurchaseId = this.parseLong("PERIODIC_TRANSACTION_ID");
            if (periodicPurchaseId >= 0) {
                PeriodicPurchaseInfo.State periodicPurchaseState =
                    PeriodicPurchaseInfo.State.fromCode(this.parseShort("PERIODIC_TRANSACTION_STATE"));
                DateTime nextPaymentDate = this.parseDateTime("PERIODIC_NEXT_PAYMENT_DATE");
                long lastPaymentId = this.parseLong("PERIODIC_LAST_PAYMENT_ID");

                this.periodicPurchaseInfo = new PeriodicPurchaseInfo(periodicPurchaseId, periodicPurchaseState, nextPaymentDate, lastPaymentId);
            }else {
                this.periodicPurchaseInfo = null;
            }
        }
        // helper method for all update + change state recurring methods
        private CreditCardReceipt updateRecurringPurchaseHelper(PeriodicPurchaseInfo periodicPurchaseInfo, Object creditCardSpecifier, VerificationRequest verificationRequest, bool isActualCreditCard)
        {
            if (periodicPurchaseInfo.getPeriodicTransactionId() < 0) {
                return new CreditCardReceipt(REQ_INVALID_REQUEST, "recurringPurchaseId is required", null);
            }

            // create the request string
            StringBuilder req = new StringBuilder();
            try {
                this.appendHeader(req, "recurringPurchase");
                this.appendOperationType(req, "update");
                this.appendTransactionId(req, periodicPurchaseInfo.getPeriodicTransactionId());
                if (creditCardSpecifier != null) {
                    if (isActualCreditCard) {
                        this.appendCreditCard(req, (CreditCard) creditCardSpecifier);
                    } else {
                        this.appendStorageTokenId(req, creditCardSpecifier.ToString());
                    }
                }
                if (periodicPurchaseInfo.getPerPaymentAmount() > 0) {
                    this.appendAmount(req, periodicPurchaseInfo.getPerPaymentAmount());
                }
                if (verificationRequest != null) {
                    this.appendVerificationRequest(req, verificationRequest);
                }
                if (periodicPurchaseInfo.getState() != PeriodicPurchaseInfo.State.NULL) {
                    this.appendPeriodicPurchaseState(req, periodicPurchaseInfo.getState());
                }
            } catch (Exception e) {
                return new CreditCardReceipt(REQ_INVALID_REQUEST, e.ToString(), null);
            }
            return this.send(req);
        }
 private void appendPeriodicPurchaseState(StringBuilder req, PeriodicPurchaseInfo.State state)
 {
     if (state != PeriodicPurchaseInfo.State.NULL) {
         this.appendParam(req, "periodicPurchaseStateCode", (int)state.toCode());
     }
 }
 private void appendPeriodicPurchaseSchedule(StringBuilder req, PeriodicPurchaseInfo.Schedule schedule)
 {
     if (schedule == null) {
         throw new ArgumentNullException("a non-null schedule is required");
     }
     this.appendParam(req, "periodicPurchaseScheduleTypeCode", (int) schedule.getScheduleType());
     this.appendParam(req, "periodicPurchaseIntervalLength", schedule.getIntervalLength());
 }
 private void appendPeriodicPurchaseInfo(StringBuilder req, PeriodicPurchaseInfo periodicPurchaseInfo)
 {
     if (periodicPurchaseInfo.getPerPaymentAmount() >= 0) {
         this.appendAmount(req,periodicPurchaseInfo.getPerPaymentAmount());
     }
     if (periodicPurchaseInfo.getState() != null) {
         this.appendPeriodicPurchaseState(req, periodicPurchaseInfo.getState());
     }
     if (periodicPurchaseInfo.getSchedule() != null) {
         this.appendPeriodicPurchaseSchedule(req, periodicPurchaseInfo.getSchedule());
     }
     if (periodicPurchaseInfo.getOrderId() != null) {
         this.appendOrderId(req, periodicPurchaseInfo.getOrderId());
     }
     if (periodicPurchaseInfo.getCustomerId() != null) {
         this.appendParam(req, "customerId", periodicPurchaseInfo.getCustomerId());
     }
     if (periodicPurchaseInfo.getStartDate() != DateTime.MinValue) {
         this.appendStartDate(req, periodicPurchaseInfo.getStartDate());
     }
     if (periodicPurchaseInfo.getEndDate() != DateTime.MinValue) {
         this.appendEndDate(req, periodicPurchaseInfo.getEndDate());
     }
     if (periodicPurchaseInfo.getNextPaymentDate() != DateTime.MinValue) {
         this.appendNextPaymentDate(req, periodicPurchaseInfo.getNextPaymentDate());
     }
     if (periodicPurchaseInfo.getExecutionType() != null)
     {
         this.appendParam(req, "periodicPurchaseExecutionType", periodicPurchaseInfo.getExecutionType());
     }
 }
 public CreditCardReceipt updateRecurringPurchase(PeriodicPurchaseInfo periodicPurchaseInfo, CreditCard creditCard, String storageTokenId, VerificationRequest verificationRequest)
 {
     if (storageTokenId == null && creditCard == null){
         return new CreditCardReceipt(REQ_INVALID_REQUEST, "creditCard or storageTokenId is required", null);
     }
     else if (storageTokenId != null)
     {
         return this.updateRecurringPurchaseHelper(periodicPurchaseInfo, storageTokenId, verificationRequest, false);
     }
     else
     {
         return this.updateRecurringPurchaseHelper(periodicPurchaseInfo, creditCard, verificationRequest, true);
     }
 }
        public CreditCardReceipt recurringPurchaseHelper(PeriodicPurchaseInfo periodicPurchaseInfo, Object creditCardSpecifier, VerificationRequest verificationRequest, bool isActualCreditCard)
        {
            if (periodicPurchaseInfo.getOrderId() == null)
            {
                return new CreditCardReceipt(REQ_INVALID_REQUEST, "orderId is required", null);
            }

            // create the request string
            StringBuilder req = new StringBuilder();
            try {
                this.appendHeader(req, "recurringPurchase");
                this.appendOperationType(req, "create");
                if (isActualCreditCard) {
                    this.appendCreditCard(req, (CreditCard) creditCardSpecifier);
                } else {
                    this.appendStorageTokenId(req, creditCardSpecifier.ToString());
                }
                this.appendPeriodicPurchaseInfo(req, periodicPurchaseInfo);
                this.appendVerificationRequest(req, verificationRequest);
            } catch (Exception e) {
                return new CreditCardReceipt(REQ_INVALID_REQUEST, e.ToString(), null);
            }
            return this.send(req);
        }
        // recurring purchase, storage token ID ver
        public CreditCardReceipt recurringPurchase(String orderId, String storageTokenId, long perPaymentAmount, DateTime startDate, DateTime endDate, PeriodicPurchaseInfo.Schedule schedule,  VerificationRequest verificationRequest)
        {
            if (storageTokenId == null)
            {
                return new CreditCardReceipt(REQ_INVALID_REQUEST, "storageTokenId is required", null);
            }

            return this.recurringPurchaseHelper(new PeriodicPurchaseInfo(0L, null, schedule, perPaymentAmount, orderId, null, startDate, endDate, DateTime.MinValue), storageTokenId, verificationRequest, false);
        }
    public static void Main(string [] args)
    {
        int merchantId=0;
        string apiToken="";
        long pan = 0;
        short expiry = 0;
        String cvv2 = null;
        string avsPostal = "";
        string avsAddress = "";
        string purchaseInvoice = "";
        string invoice="";
        long amount=0;
        string url="";
        string method="";
        long transactionId=0;
        string customerId="";
        DateTime startDate = DateTime.Now;
        DateTime endDate = DateTime.Now;
        DateTime nextPaymentDate = DateTime.Now;
        if(args.Length >=6){
            method=args[0];
            url=args[1];
            merchantId=Convert.ToInt32(args[2]);
            apiToken=args[3];
            if(method.Equals("purchase")){
                pan = Convert.ToInt64(args[4]);
                expiry = Convert.ToInt16(args[5]);
                invoice = args[6];
                amount=Convert.ToInt64(args[7]);
            }
            else if(method.Equals("refund")) {
                transactionId=Convert.ToInt64(args[4]);
                purchaseInvoice = args[5];
                invoice = args[6];
                amount = Convert.ToInt64(args[7]);
            }
            else if (method.Equals("void"))
            {
                transactionId = Convert.ToInt64(args[4]);
                invoice = args[5];
            }
            else if (method.Equals("verify"))
            {
                pan = Convert.ToInt64(args[4]);
                expiry = Convert.ToInt16(args[5]);
                cvv2 = args[6];
                avsAddress = args[7];
                avsPostal = args[8];
            }
            else if (method.Equals("recurring"))
            {
                pan = Convert.ToInt64(args[4]);
                expiry = Convert.ToInt16(args[5]);
                invoice = args[6];
                amount=Convert.ToInt64(args[7]);
                startDate = DateTime.ParseExact(args[8], "yyyyMMdd", null);
                endDate = DateTime.ParseExact(args[9], "yyyyMMdd", null);
                customerId = args[10];
            }
            else if (method.Equals("queryRecurring"))
            {
                pan = Convert.ToInt64(args[4]);
                expiry = Convert.ToInt16(args[5]);
                transactionId = Convert.ToInt64(args[6]);
            }
            System.Net.ServicePointManager.ServerCertificateValidationCallback = null;

            // Service
            HttpsCreditCardService ccService = new HttpsCreditCardService(merchantId, apiToken, url);
            CreditCardReceipt resp=null;
            // invoke txn method
            if(method.Equals("purchase")){
                CreditCard creditCard = new CreditCard(pan, expiry);
                resp = ccService.singlePurchase(invoice, creditCard, amount, null);
            } else if (method.Equals("refund")){
                resp = ccService.refund(transactionId, purchaseInvoice, invoice, amount);
            } else if (method.Equals("void")) {
                resp = ccService.voidTransaction(transactionId, invoice);
            } else if (method.Equals("verify")){
                CreditCard creditCard = new CreditCard(pan, expiry, cvv2, avsAddress, avsPostal);
                VerificationRequest vr = new VerificationRequest(AvsRequest.VERIFY_STREET_AND_ZIP, Cvv2Request.CVV2_PRESENT);
                resp = ccService.verifyCreditCard(creditCard, vr);
            } else if (method.Equals("recurring")) {
                CreditCard creditCard = new CreditCard(pan, expiry);
                PeriodicPurchaseInfo.Schedule schedule = new PeriodicPurchaseInfo.Schedule(PeriodicPurchaseInfo.ScheduleType.MONTH, 1);
                PeriodicPurchaseInfo periodicPurchaseInfo = new PeriodicPurchaseInfo(
                    0L, PeriodicPurchaseInfo.State.IN_PROGRESS, schedule, amount, invoice, customerId, startDate, endDate, endDate);
                resp = ccService.recurringPurchase(invoice, creditCard, amount, startDate, endDate, schedule, null);
            } else if (method.Equals("queryRecurring")){
                CreditCard creditCard = new CreditCard (pan, expiry);
                resp = ccService.queryRecurringPurchase(transactionId);
            }
            else  {
                Console.WriteLine("args[0] must be purchase, refund or verify");
            }
            if(resp.isApproved()){
                Console.WriteLine("isApproved: {0}", resp.isApproved());
                Console.WriteLine("getTransactionId: {0}",resp.getTransactionId());
                if (resp.getApprovalInfo() != null && !method.Equals("void"))
                {
                    // void does not have approval, it just cancels a pending txn
                    Console.WriteLine("getApprovalInfo: \n {0}", resp.getApprovalInfo().ToString());
                }
                if (resp.getCvv2Response() != null)
                {
                    Console.WriteLine("getCvv2Response: \n {0}", resp.getCvv2Response().ToString());
                }
                if (resp.getAvsResponse() != null)
                {
                    Console.WriteLine("getAvsResponse: \n {0}", resp.getAvsResponse().ToString());
                }
                if (resp.getPeriodicPurchaseInfo() !=null)
                {
                    Console.WriteLine("getPeriodicPurchaseInfo: \n {0}", resp.getPeriodicPurchaseInfo().ToString());
                }
            } else {
                //display error
                Console.WriteLine("isApproved: {0}", resp.isApproved());
                Console.WriteLine("Error Code: {0} Message: {1}",resp.getErrorCode(),resp.getErrorMessage());
                Console.WriteLine("Debug Mesg: Message: {0}",resp.getDebugMessage());
            }
        } else {
            Console.WriteLine("[Invalid Command]");
            Console.WriteLine("");
            Console.WriteLine("Usage:");
            Console.WriteLine("");
            Console.WriteLine("Purchase: purchase url(string) merchantId(int) apiToken(string) pan(long) expiry(short) invoice(string) amount(long)");
            Console.WriteLine("      CCGatewayTest purchase https://test.admeris.com/ccgateway/cc/processor.do 1 abc 4242424242424242 1212 dotNet2_2BlueElephant1 1200");
            Console.WriteLine("------------------------------------*---------------------------------------");
            Console.WriteLine("Refund: refund url(string) merchantId(int) apiToken(string) purchaseTxnId(long) purchaseInvoice(string), invoice(string) amount(long)");
            Console.WriteLine("      CCGatewayTest refund https://test.admeris.com/ccgateway/cc/processor.do 1 abc 123456789 order-123 refund-456 1200");
            Console.WriteLine("------------------------------------*---------------------------------------");
            Console.WriteLine("Void: void url(string) merchantId(int) apiToken(string) transactionId(long) originalInvoice(string)");
            Console.WriteLine("      CCGatewayTest void https://test.admeris.com/ccgateway/cc/processor.do 1 abc 123456789 order-123");
            Console.WriteLine("------------------------------------*---------------------------------------");
            Console.WriteLine("Verify: verify url(string) merchantId(int) apiToken(string) pan(long) expiry(short) cvv2(string) avsAddress(string) avsPostal(string)");
            Console.WriteLine("      CCGatewayTest verify https://test.admeris.com/ccgateway/cc/processor.do 1 abc 4242424242424242 1212 456 \"100 Easy Street\" A1B2C3");
            Console.WriteLine("------------------------------------*---------------------------------------");
            Console.WriteLine("Recurring: recurring url(string) merchantId(int) apiToken(string) pan(long) expiry(short) invoice(string) amount(long) start(yyyyMMdd) end(yyyyMMdd) customerId(string)");
            Console.WriteLine("      CCGatewayTest recurring https://test.admeris.com/ccgateway/cc/processor.do 1 abc 4242424242424242 1212 rec-123 1000 20090505 20100505 customer");
            Console.WriteLine("------------------------------------*---------------------------------------");
            Console.WriteLine("Query Recurring: queryRecurring url(string) merchantId(int) apiToken(string) pan(long) expiry(short) recurringPurchaseId(long)");
            Console.WriteLine("      CCGatewayTest queryRecurring https://test.admeris.com/ccgateway/cc/processor.do 1 abc 4242424242424242 1212 670");
        }
    }