public void ItShouldHaveATransactionIdForASuccessfulVoid()
        {
            // Arrange
            var webresult = new WebCommandResult<string> { Response = @"{""id"":""10000000""}" };

            _executer.Setup(e => e.ExecuteCommand(It.IsAny<ExecuteWebRequest>())).Returns(webresult);

            Gateway beanstream = new Gateway () {
                MerchantId = 300200578,
                PaymentsApiKey = "4BaD82D9197b4cc4b70a221911eE9f70",
                ApiVersion = "1"
            };
            beanstream.WebCommandExecuter = _executer.Object;

            // Act
            dynamic result = beanstream.Payments.Void("10000000", 10);
            // Assert
            Assert.AreEqual(result.TransactionId, "10000000");
        }
        public void ItShouldThrowArgumentExceptionForInvalidReturn()
        {
            // Arrange
            Gateway beanstream = new Gateway () {
                MerchantId = 300200578,
                PaymentsApiKey = "4BaD82D9197b4cc4b70a221911eE9f70",
                ApiVersion = "1"
            };
            beanstream.WebCommandExecuter = _executer.Object;

            _returnRequest = null;

            // Act
            var ex = (ArgumentNullException)Assert.Throws(typeof(ArgumentNullException),
                () =>beanstream.Payments.UnreferencedReturn(_returnRequest));

            // Assert
            Assert.That(ex.ParamName, Is.EqualTo("returnRequest"));
        }
        public static void GetTransaction()
        {
            Console.WriteLine ("Getting Transaction... ");

            Gateway beanstream = new Gateway () {
                MerchantId = 300200578,
                PaymentsApiKey = "4BaD82D9197b4cc4b70a221911eE9f70",
                ReportingApiKey = "4e6Ff318bee64EA391609de89aD4CF5d",
                ApiVersion = "1"
            };

            PaymentResponse response = beanstream.Payments.MakePayment (
                new CardPaymentRequest {
                    Amount = 100.00M,
                    OrderNumber = getRandomOrderId("test"),
                    Card = new Card {
                        Name = "John Doe",
                        Number = "5100000010001004",
                        ExpiryMonth = "12",
                        ExpiryYear = "18",
                        Cvd = "123"
                    }
                }
            );

            beanstream.Payments.Void (response.TransactionId, 100);
            Transaction trans = beanstream.Reporting.GetTransaction (response.TransactionId);

            Console.WriteLine ("Payment id: " + response.TransactionId + ", " + response.Message+"\n");

            Assert.IsNotEmpty (response.TransactionId);
            Assert.AreEqual ("Approved", response.Message);
            Assert.AreEqual ("P", response.TransType);
            Assert.NotNull (trans.Adjustments);
            Assert.AreEqual (1, trans.Adjustments.Count);

            // look for the void payment, there should only be one adjustment
            foreach (Adjustment adj in trans.Adjustments) {
                Assert.AreEqual ("VP", adj.Type);
            }
        }
        public void ItShouldHaveATransactionIdForASuccessfulPreAuth()
        {
            // Arrange
            var webresult = new WebCommandResult<string>{Response = @"{""id"":""10000000""}"};

            _executer.Setup(e => e.ExecuteCommand(It.IsAny<ExecuteWebRequest>())).Returns(webresult);

            Gateway beanstream = new Gateway () {
                MerchantId = 300200578,
                PaymentsApiKey = "4BaD82D9197b4cc4b70a221911eE9f70",
                ProfilesApiKey = "D97D3BE1EE964A6193D17A571D9FBC80",
                ApiVersion = "1"
            };
            beanstream.WebCommandExecuter = _executer.Object;

            // Act
            PaymentResponse response = beanstream.Payments.PreAuth (_cardPaymentRequest);

            // Assert
            Assert.AreEqual(response.TransactionId, "10000000");
        }
        public void ItShouldThrowRuleExceptionForBusinessRuleViolation()
        {
            // Arrange
            _executer.Setup(e => e.ExecuteCommand(It.IsAny<ExecuteWebRequest>()))
                .Throws(new BusinessRuleException(HttpStatusCode.PaymentRequired, "", 1, 0));

            Gateway beanstream = new Gateway () {
                MerchantId = 300200578,
                PaymentsApiKey = "4BaD82D9197b4cc4b70a221911eE9f70",
                ProfilesApiKey = "D97D3BE1EE964A6193D17A571D9FBC80",
                ApiVersion = "1"
            };
            beanstream.WebCommandExecuter = _executer.Object;

            // Act
            var ex = (BusinessRuleException)Assert.Throws(typeof(BusinessRuleException),
                () => beanstream.Payments.PreAuth(_cardPaymentRequest));

            // Assert
            Assert.That(ex.StatusCode, Is.EqualTo((int)HttpStatusCode.PaymentRequired));
        }
        private static void UpdateCardInProfile()
        {
            Console.WriteLine ("Update a Card in a Profile... ");

            Gateway beanstream = new Gateway () {
                MerchantId = 300200578,
                PaymentsApiKey = "4BaD82D9197b4cc4b70a221911eE9f70",
                ReportingApiKey = "4e6Ff318bee64EA391609de89aD4CF5d",
                ProfilesApiKey = "D97D3BE1EE964A6193D17A571D9FBC80",
                ApiVersion = "1"
            };

            ProfileResponse response = beanstream.Profiles.CreateProfile (
                new Card() {
                    Name = "Jane Doe",
                    Number = "5100000010001004",
                    ExpiryMonth = "12",
                    ExpiryYear = "18",
                    Cvd = "123"
                },
                new Address() {
                    Name = "Jane Doe",
                    AddressLine1 = "123 Fake St.",
                    City = "victoria",
                    Province = "bc",
                    Country = "ca",
                    PostalCode = "v9t2g6",
                    PhoneNumber = "12501234567",
                    EmailAddress = "*****@*****.**"
                });
            Console.WriteLine ("Created profile with ID: " + response.Id);
            Assert.IsNotNull (response);
            Assert.AreEqual ("Operation Successful", response.Message);

            PaymentProfile profile = beanstream.Profiles.GetProfile (response.Id);
            Assert.IsNotNull (profile);

            // get card
            Card card = profile.getCard (beanstream.Profiles, 1);
            Console.WriteLine ("Retrieved card with expiry year: " + card.ExpiryYear);
            Assert.IsNotNull (card);
            Assert.AreEqual ("18", card.ExpiryYear);
            card.ExpiryYear = "20";
            profile.UpdateCard (beanstream.Profiles, card);
            Console.WriteLine ("Updated card expiry");
            card = profile.getCard (beanstream.Profiles, 1);
            Assert.IsNotNull (card);
            Assert.AreEqual ("20", card.ExpiryYear);
            Console.WriteLine ("Retrieved updated card with expiry year: " + card.ExpiryYear);

            // delete it so when we create a profile again with the same card we won't get an error
            beanstream.Profiles.DeleteProfile (response.Id);
        }
        private static void QueryTransactions()
        {
            Console.WriteLine ("Query Transaction... ");

            // create a payment so we have something to query for
            string transId = ProcessPayment ();

            Gateway beanstream = new Gateway () {
                MerchantId = 300200578,
                PaymentsApiKey = "4BaD82D9197b4cc4b70a221911eE9f70",
                ReportingApiKey = "4e6Ff318bee64EA391609de89aD4CF5d",
                ApiVersion = "1"
            };

            List<TransactionRecord> records = beanstream.Reporting.Query (
                DateTime.Now.Subtract(TimeSpan.FromMinutes(1)),
                DateTime.Now.Add(TimeSpan.FromMinutes(5)),
                1,
                100,
                new Criteria[]{
                    new Criteria() {
                        Field = QueryFields.TransactionId,
                        Operator = Operators.GreaterThanEqual,
                        Value = "1"
                    },
                    new Criteria() {
                        Field = QueryFields.TransactionId,
                        Operator = Operators.LessThanEqual,
                        Value = "99999999"
                    }
                }
            );

            Console.WriteLine ("Num records: " + records.Count);

            Assert.IsNotEmpty (records);
            Assert.NotNull (transId);

            bool found = false;
            foreach (TransactionRecord record in records) {
                if (record.TransactionId.ToString().Equals (transId))
                    found = true;
            }
            Assert.True (found); // we need to make sure we found our transaction

            // Test 2
            // search and find NO records, get a 404
            Boolean got404 = false;
            try {
                records = beanstream.Reporting.Query (
                    DateTime.Now.Subtract(TimeSpan.FromMinutes(1)),
                    DateTime.Now.Add(TimeSpan.FromMinutes(5)),
                    1,
                    1000,
                    new Criteria[]{
                        new Criteria() {
                            Field = QueryFields.TransactionId,
                            Operator = Operators.LessThan,
                            Value = "1"
                        }
                    }
                );
            } catch(BaseApiException ex) {
                if (ex.StatusCode == 404)
                    got404 = true;
            }
            Assert.True (got404);
        }
        public void ItShouldThrowServerExceptionForServerError()
        {
            // Arrange
            _executer.Setup(e => e.ExecuteCommand(It.IsAny<ExecuteWebRequest>()))
                .Throws(new InternalServerException(HttpStatusCode.InternalServerError, "", 1, 0));

            Gateway beanstream = new Gateway () {
                MerchantId = 300200578,
                PaymentsApiKey = "4BaD82D9197b4cc4b70a221911eE9f70",
                ProfilesApiKey = "D97D3BE1EE964A6193D17A571D9FBC80",
                ApiVersion = "1"
            };
            beanstream.WebCommandExecuter = _executer.Object;

            // Act
            var ex = (InternalServerException)Assert.Throws(typeof(InternalServerException),
                () => beanstream.Payments.PreAuthCompletion ("0001", 100));

            // Assert
            Assert.That(ex.StatusCode, Is.EqualTo((int)HttpStatusCode.InternalServerError));
        }
        public void ItShouldThrowCommunicationExceptionForCommunicationError()
        {
            // Arrange
            _executer.Setup(e => e.ExecuteCommand(It.IsAny<ExecuteWebRequest>()))
                .Throws(new CommunicationException("API exception occured", null));

            Gateway beanstream = new Gateway () {
                MerchantId = 300200578,
                PaymentsApiKey = "4BaD82D9197b4cc4b70a221911eE9f70",
                ApiVersion = "1"
            };
            beanstream.WebCommandExecuter = _executer.Object;

            // Act
            var ex = (CommunicationException)Assert.Throws(typeof(CommunicationException),
                () => beanstream.Payments.Void(TrnId, 10));

            // Assert
            Assert.That(ex.Message, Is.EqualTo("API exception occured"));
        }
        public void ItShouldThrowServerExceptionForServerError()
        {
            // Arrange
            _executer.Setup(e => e.ExecuteCommand(It.IsAny<ExecuteWebRequest>()))
                .Throws(new InternalServerException(HttpStatusCode.InternalServerError, "", "", 1, 0));

            Gateway beanstream = new Gateway () {
                MerchantId = 300200578,
                PaymentsApiKey = "4BaD82D9197b4cc4b70a221911eE9f70",
                ApiVersion = "1"
            };
            beanstream.WebCommandExecuter = _executer.Object;

            // Act
            var ex = (InternalServerException)Assert.Throws(typeof(InternalServerException),
                () => beanstream.Payments.UnreferencedReturn(_returnRequest));

            // Assert
            Assert.That(ex.StatusCode, Is.EqualTo((int)HttpStatusCode.InternalServerError));
        }
        /// <summary>
        /// Process Cash and Cheque payments. This is a useful way to record a payment that
        /// you physically took.
        /// NOTE: You will need to have these payment options ACTIVATED by calling Beanstream 
        /// support at 1-888-472-0811
        /// 
        /// </summary>
        static void ProcessPhysicalPayments()
        {
            Console.WriteLine ("Processing Cash Payment... ");

            Gateway beanstream = new Gateway () {
                MerchantId = 300200578,
                PaymentsApiKey = "4BaD82D9197b4cc4b70a221911eE9f70",
                ApiVersion = "1"
            };

            // process cash payment
            PaymentResponse response = beanstream.Payments.MakePayment (
                new CashPaymentRequest () {
                    Amount = 50.00M,
                    OrderNumber = getRandomOrderId("test")
                }
            );
            Console.WriteLine ("Cash Payment id: " + response.TransactionId + ", " + response.Message+"\n");

            Assert.IsNotEmpty (response.TransactionId);
            Assert.AreEqual ("Approved", response.Message);
            Assert.AreEqual ("P", response.TransType);

            Console.WriteLine ("Processing Cheque Payment... ");
            // process cheque payment
            response = beanstream.Payments.MakePayment (
                new ChequePaymentRequest () {
                    Amount = 30.00M,
                    OrderNumber = getRandomOrderId("test")
                }
            );
            Console.WriteLine ("Cheque Payment id: " + response.TransactionId + ", " + response.Message+"\n");

            Assert.IsNotEmpty (response.TransactionId);
            Assert.AreEqual ("Approved", response.Message);
            Assert.AreEqual ("P", response.TransType);
        }
        static string ProcessPayment()
        {
            Console.WriteLine ("Processing Payment... ");

            Gateway beanstream = new Gateway () {
                MerchantId = 300200578,
                PaymentsApiKey = "4BaD82D9197b4cc4b70a221911eE9f70",
                ApiVersion = "1"
            };

            PaymentResponse response = beanstream.Payments.MakePayment (
                new CardPaymentRequest {
                    Amount = 100.00M,
                    OrderNumber = getRandomOrderId("test"),
                    Card = new Card {
                        Name = "John Doe",
                        Number = "5100000010001004",
                        ExpiryMonth = "12",
                        ExpiryYear = "18",
                        Cvd = "123"
                    }
                }
            );

            Console.WriteLine ("Payment id: " + response.TransactionId + ", " + response.Message+"\n");

            Assert.IsNotEmpty (response.TransactionId);
            Assert.AreEqual ("Approved", response.Message);
            Assert.AreEqual ("P", response.TransType);

            return response.TransactionId;
        }
        static void ProcessDeclinedPayment()
        {
            Console.WriteLine ("Processing Payment... ");

            Gateway beanstream = new Gateway () {
                MerchantId = 300200578,
                PaymentsApiKey = "4BaD82D9197b4cc4b70a221911eE9f70",
                ApiVersion = "1"
            };

            try {
                PaymentResponse response = beanstream.Payments.MakePayment (
                    new CardPaymentRequest {
                        Amount = 100.00M,
                        OrderNumber = getRandomOrderId("test"),
                        Card = new Card {
                            Name = "John Doe",
                            Number = "4003050500040005", // a test card that will decline
                            ExpiryMonth = "12",
                            ExpiryYear = "18",
                            Cvd = "123"
                        }
                    }
                );

            } catch (RedirectionException ex) {
                // Redirect the user to the URL returned in the exception.
                // This is used for Interac and 3d Secure
            } catch (InvalidRequestException ex) {
                // something was wrong with the card info or it was declined. Send a message
                // to the card holder.
                Console.WriteLine(ex.ResponseMessage);
            } catch (BaseApiException ex) {
                // all other errors are caught here.
                // Be careful not to return very detailed error messages to the users. This info
                // can be used maliciously for "carding" (testing a lot of stolen card numbers to see
                // what ones are valid).
                Console.WriteLine(ex.ResponseMessage);
            }
        }
        private static void GetAllCardsFromProfile()
        {
            Console.WriteLine ("Get all Cards from Profile... ");

            Gateway beanstream = new Gateway () {
                MerchantId = 300200578,
                PaymentsApiKey = "4BaD82D9197b4cc4b70a221911eE9f70",
                ReportingApiKey = "4e6Ff318bee64EA391609de89aD4CF5d",
                ProfilesApiKey = "D97D3BE1EE964A6193D17A571D9FBC80",
                ApiVersion = "1"
            };

            ProfileResponse response = beanstream.Profiles.CreateProfile (
                new Card() {
                    Name = "Jane Doe",
                    Number = "5100000010001004",
                    ExpiryMonth = "12",
                    ExpiryYear = "18",
                    Cvd = "123"
                },
                new Address() {
                    Name = "Jane Doe",
                    AddressLine1 = "123 Fake St.",
                    City = "victoria",
                    Province = "bc",
                    Country = "ca",
                    PostalCode = "v9t2g6",
                    PhoneNumber = "12501234567",
                    EmailAddress = "*****@*****.**"
                });
            Console.WriteLine ("Created profile with ID: " + response.Id);
            Assert.IsNotNull (response);
            Assert.AreEqual ("Operation Successful", response.Message);

            PaymentProfile profile = beanstream.Profiles.GetProfile (response.Id);

            response = profile.AddCard (beanstream.Profiles, new Card {
                Name = "Jane Doe",
                Number = "4030000010001234",
                ExpiryMonth = "03",
                ExpiryYear = "22",
                Cvd = "123"
            });
            Console.WriteLine ("Added card to profile");
            Assert.IsNotNull (response);
            Assert.AreEqual ("Operation Successful", response.Message);

            // get all cards
            IList<Card> cards = profile.getCards (beanstream.Profiles);
            Assert.NotNull (cards);
            Assert.AreEqual (2, cards.Count);
            Assert.AreEqual (1, cards[0].Id);
            Assert.AreEqual (2, cards[1].Id);
            Console.WriteLine ("Retrieved " + cards.Count + " cards from profile.");
            Console.WriteLine ("Card 1 expiry year: " + cards[0].ExpiryYear);
            Console.WriteLine ("Card 2 expiry year: " + cards[1].ExpiryYear);

            // delete it so when we create a profile again with the same card we won't get an error
            beanstream.Profiles.DeleteProfile (response.Id);
        }
        private static void CreateProfileWithToken()
        {
            Console.WriteLine ("Creating Payment Profile with a Legato Token... ");

            Gateway beanstream = new Gateway () {
                MerchantId = 300200578,
                PaymentsApiKey = "4BaD82D9197b4cc4b70a221911eE9f70",
                ReportingApiKey = "4e6Ff318bee64EA391609de89aD4CF5d",
                ProfilesApiKey = "D97D3BE1EE964A6193D17A571D9FBC80",
                ApiVersion = "1"
            };

            string url = "https://www.beanstream.com/scripts/tokenization/tokens";
            var data = new {
                number = "5100000010001004",
                expiry_month = "12",
                expiry_year = "18",
                cvd = "123"
            };

            var requestInfo = new RequestObject(HttpMethod.Post, url, null, data);
            var command = new ExecuteWebRequest (requestInfo);
            WebCommandExecuter executer = new WebCommandExecuter ();
            var result = executer.ExecuteCommand (command);

            LegatoTokenResponse token = JsonConvert.DeserializeObject<LegatoTokenResponse>(result.Response);
            Console.WriteLine ("Retrieved Legato Token: "+token.Token);

            // You can create a profile with a token instead of a card.
            // It will save the billing information, but the token is still single-use
            ProfileResponse response = beanstream.Profiles.CreateProfile (
                new Token() {
                    Name = "Jane Doe",
                    Code = token.Token
                },
                new Address() {
                    Name = "Jane Doe",
                    AddressLine1 = "123 Fake St.",
                    City = "victoria",
                    Province = "bc",
                    Country = "ca",
                    PostalCode = "v9t2g6",
                    PhoneNumber = "12501234567",
                    EmailAddress = "*****@*****.**"
                });
            Console.WriteLine ("Created profile with ID: " + response.Id);

            Assert.IsNotNull (response);
            Assert.AreEqual ("Operation Successful", response.Message);

            // delete it so when we create a profile again with the same card we won't get an error
            beanstream.Profiles.DeleteProfile (response.Id);
        }
        private static void AddTokenizedCardToProfileAndMakePayment()
        {
            Console.WriteLine ("Adding Tokenized Card to Profile... ");

            Gateway beanstream = new Gateway () {
                MerchantId = 300200578,
                PaymentsApiKey = "4BaD82D9197b4cc4b70a221911eE9f70",
                ReportingApiKey = "4e6Ff318bee64EA391609de89aD4CF5d",
                ProfilesApiKey = "D97D3BE1EE964A6193D17A571D9FBC80",
                ApiVersion = "1"
            };

            ProfileResponse response = beanstream.Profiles.CreateProfile (
                new Card() {
                    Name = "Jane Doe",
                    Number = "5100000010001004",
                    ExpiryMonth = "12",
                    ExpiryYear = "18",
                    Cvd = "123"
                },
                new Address() {
                    Name = "Jane Doe",
                    AddressLine1 = "123 Fake St.",
                    City = "victoria",
                    Province = "bc",
                    Country = "ca",
                    PostalCode = "v9t2g6",
                    PhoneNumber = "12501234567",
                    EmailAddress = "*****@*****.**"
                });
            Console.WriteLine ("Created profile with ID: " + response.Id);
            Assert.IsNotNull (response);
            Assert.AreEqual ("Operation Successful", response.Message);

            PaymentProfile profile = beanstream.Profiles.GetProfile (response.Id);

            // get a legato token representing the credit card
            string url = "https://www.beanstream.com/scripts/tokenization/tokens";
            var data = new {
                number = "4030000010001234",
                expiry_month = "12",
                expiry_year = "18",
                cvd = "123"
            };

            var requestInfo = new RequestObject(HttpMethod.Post, url, null, data);
            var command = new ExecuteWebRequest (requestInfo);
            WebCommandExecuter executer = new WebCommandExecuter ();
            var result = executer.ExecuteCommand (command);

            LegatoTokenResponse token = JsonConvert.DeserializeObject<LegatoTokenResponse>(result.Response);

            response = profile.AddCard (beanstream.Profiles, new Token {
                Name = "Jane Doe",
                Code = token.Token
            });
            Console.WriteLine ("Added tokenized card to profile");
            Assert.IsNotNull (response);
            Assert.AreEqual ("Operation Successful", response.Message);

            PaymentResponse pResp = beanstream.Payments.MakePayment (new ProfilePaymentRequest {
                Amount = 7.91M,
                OrderNumber = getRandomOrderId("profile"),
                PaymentProfile = new PaymentProfileField() {
                    CardId = 2,
                    CustomerCode = response.Id
                }
            });
            Assert.IsNotNull (pResp);

            // delete it so when we create a profile again with the same card we won't get an error
            beanstream.Profiles.DeleteProfile (response.Id);
        }
        public void ItShouldThrowArgumentExceptionForInvalidPreAuth()
        {
            // Arrange
            _executer.Setup(e => e.ExecuteCommand(It.IsAny<ExecuteWebRequest>()))
                .Throws(new ArgumentNullException());

            Gateway beanstream = new Gateway () {
                MerchantId = 300200578,
                PaymentsApiKey = "4BaD82D9197b4cc4b70a221911eE9f70",
                ProfilesApiKey = "D97D3BE1EE964A6193D17A571D9FBC80",
                ApiVersion = "1"
            };
            beanstream.WebCommandExecuter = _executer.Object;

            // Act
            var ex = (ArgumentNullException)Assert.Throws(typeof(ArgumentNullException),
                () => beanstream.Payments.PreAuth( (CardPaymentRequest)null));

            // Assert
            Assert.That(ex.ParamName, Is.EqualTo("paymentRequest"));
        }
        static void ProcessPreauthorization()
        {
            Console.WriteLine ("Processing Pre-auth payments... ");

            Gateway beanstream = new Gateway () {
                MerchantId = 300200578,
                PaymentsApiKey = "4BaD82D9197b4cc4b70a221911eE9f70",
                ApiVersion = "1"
            };

            CardPaymentRequest paymentRequest = new CardPaymentRequest {
                Amount = 100.00M,
                OrderNumber = getRandomOrderId("test"),
                Card = new Card {
                    Name = "John Doe",
                    Number = "5100000010001004",
                    ExpiryMonth = "12",
                    ExpiryYear = "18",
                    Cvd = "123"
                }
            };

            // pre-authorize the payment for $100
            PaymentResponse response = beanstream.Payments.PreAuth (paymentRequest);

            // In order for Pre-authorizations to work, you must enable them on your account:
            // http://support.beanstream.com/#docs/pre-authorizations-process-transaction-api.htm%3FTocPath%3DDeveloper%2520Resources%7CThe%2520Process%2520Transaction%2520API%7C_____8
            //
            // 1. Log in to the Online Member Area.
            // 2. Navigate to administration > account admin > order settings in the left menu.
            // 3. Under the heading Restrict Internet Transaction Processing Types, select either of the last two options:
            // 3.a. Select Purchases or Pre-Authorization Only: allows you to process both types of transaction through your web interface
            // 3.b. De-select Restrict Internet Transaction Processing Types: allows you to process all types of transactions including returns, voids and pre-auth completions

            Console.WriteLine ("Pre-auth Payment id: " + response.TransactionId + ", " + response.Message);

            Assert.IsNotEmpty (response.TransactionId);
            Assert.AreEqual ("Approved", response.Message);
            Assert.AreEqual ("PA", response.TransType);

            // complete the pre-auth and get the money from the customer
            response = beanstream.Payments.PreAuthCompletion ( response.TransactionId, 60.00M );

            Console.WriteLine ("Pre-auth result: " + response.TransactionId + ", " + response.Message+"\n" );

            Assert.IsNotEmpty (response.TransactionId);
            Assert.AreEqual ("Approved", response.Message);
            Assert.AreEqual ("PAC", response.TransType);
        }
        //TODO this is being implemented
        /*static void ProcessInterac() {

            Console.WriteLine ("Processing Interac Payment... ");

            Beanstream beanstream = new Beanstream () {
                MerchantId = 300200578,
                ApiKey = "4BaD82D9197b4cc4b70a221911eE9f70",
                ApiVersion = "1"
            };

            // STEP 1:
            // The first step is to tell Beanstream you are making an Interac payment
            // and to get the Transaction ID for the next step
            PaymentResponse response = beanstream.Payments.MakePayment (
                new InteracPaymentRequest {
                    amount = "100.00",
                    order_number = getRandomOrderId("test")
                }
            );
            Console.WriteLine ("Interac Payment id: " + response.id + ", " + response.message+"\n");

            // STEP 2:
            // Next you redirect the user to the bank's website for the actual interac processing
        }*/
        static void ProcessTokenPayment()
        {
            // The first step is to call the Legato service to get a token.
            // This is normally performed on the client machine, and not on the server.
            // The goal with tokens is to not have credit card information move through your server,
            // thus lowering your scope for PCI compliance

            string url = "https://www.beanstream.com/scripts/tokenization/tokens";
            var data = new {
                number = "5100000010001004",
                expiry_month = "12",
                expiry_year = "18",
                cvd = "123"
            };

            var requestInfo = new RequestObject(HttpMethod.Post, url, null, data);
            var command = new ExecuteWebRequest (requestInfo);
            WebCommandExecuter executer = new WebCommandExecuter ();
            var result = executer.ExecuteCommand (command);

            LegatoTokenResponse token = JsonConvert.DeserializeObject<LegatoTokenResponse>(result.Response);
            Console.WriteLine ("legato token: " + token.Token);

            // Now that we have a token that represents our credit card info, we can process
            // the payment with that token

            Gateway beanstream = new Gateway () {
                MerchantId = 300200578,
                PaymentsApiKey = "4BaD82D9197b4cc4b70a221911eE9f70",
                ApiVersion = "1"
            };

            PaymentResponse response = beanstream.Payments.MakePayment (
                new TokenPaymentRequest ()
                {
                    Amount = 30,
                    OrderNumber = getRandomOrderId("test"),
                    Token = new Token {
                        Code = token.Token,
                        Name = "John Doe"
                    }
                }
            );

            Console.WriteLine ("Token payment result: " + response.TransactionId + ", " + response.Message+"\n");

            Assert.IsNotEmpty (response.TransactionId);
            Assert.AreEqual ("Approved", response.Message);
            Assert.AreEqual ("P", response.TransType);
        }
        static void ProcessVoids()
        {
            Console.WriteLine ("Processing Voids... ");

            Gateway beanstream = new Gateway () {
                MerchantId = 300200578,
                PaymentsApiKey = "4BaD82D9197b4cc4b70a221911eE9f70",
                ApiVersion = "1"
            };

            // we make a payment first so we can void it
            PaymentResponse response = beanstream.Payments.MakePayment (
                new CardPaymentRequest {
                    Amount = 30.00M,
                    OrderNumber = getRandomOrderId("test"),
                    Card = new Card {
                        Name = "John Doe",
                        Number = "5100000010001004",
                        ExpiryMonth = "12",
                        ExpiryYear = "18",
                        Cvd = "123"
                    }
                }
            );
            Console.WriteLine ("Void Payment id: " + response.TransactionId);

            Assert.IsNotEmpty (response.TransactionId);
            Assert.AreEqual ("Approved", response.Message);
            Assert.AreEqual ("P", response.TransType);

            // void the purchase
            response = beanstream.Payments.Void (response.TransactionId, 30); // void the $30 amount

            Console.WriteLine ("Void result: " + response.TransactionId + ", " + response.Message+"\n");

            Assert.IsNotEmpty (response.TransactionId);
            Assert.AreEqual ("Approved", response.Message);
            Assert.AreEqual ("VP", response.TransType);
        }
        public void ItShouldThrowUnauthorizedExceptionForInvalidPermissions()
        {
            // Arrange
            _executer.Setup(e => e.ExecuteCommand(It.IsAny<ExecuteWebRequest>()))
                .Throws(new UnauthorizedException(HttpStatusCode.Unauthorized, "", 1, 0));

            Gateway beanstream = new Gateway () {
                MerchantId = 300200578,
                PaymentsApiKey = "4BaD82D9197b4cc4b70a221911eE9f70",
                ApiVersion = "1"
            };
            beanstream.WebCommandExecuter = _executer.Object;

            // Act
            var ex = (UnauthorizedException)Assert.Throws(typeof(UnauthorizedException),
                () => beanstream.Payments.Void(TrnId, 10));

            // Assert
            Assert.That(ex.StatusCode, Is.EqualTo((int)HttpStatusCode.Unauthorized));
        }
        private static void ProfileTakePayment()
        {
            Console.WriteLine ("Take Payment with Profile... ");

            Gateway beanstream = new Gateway () {
                MerchantId = 300200578,
                PaymentsApiKey = "4BaD82D9197b4cc4b70a221911eE9f70",
                ReportingApiKey = "4e6Ff318bee64EA391609de89aD4CF5d",
                ProfilesApiKey = "D97D3BE1EE964A6193D17A571D9FBC80",
                ApiVersion = "1"
            };

            ProfileResponse response = beanstream.Profiles.CreateProfile (
                new Card() {
                    Name = "Jane Doe",
                    Number = "5100000010001004",
                    ExpiryMonth = "12",
                    ExpiryYear = "18",
                    Cvd = "123"
                },
                new Address() {
                    Name = "Jane Doe",
                    AddressLine1 = "123 Fake St.",
                    City = "victoria",
                    Province = "bc",
                    Country = "ca",
                    PostalCode = "v9t2g6",
                    PhoneNumber = "12501234567",
                    EmailAddress = "*****@*****.**"
                });
            Console.WriteLine ("Created profile with ID: " + response.Id);

            // add a 2nd card
            response = beanstream.Profiles.AddCard (response.Id, new Card () {
                Name = "Jane Doe",
                Number = "4030000010001234",
                ExpiryMonth = "04",
                ExpiryYear = "19",
                Cvd = "123"
            });

            Assert.IsNotNull (response);
            Assert.AreEqual ("Operation Successful", response.Message);

            PaymentResponse payment = beanstream.Payments.MakePayment (new ProfilePaymentRequest() {
                Amount = 40.95M,
                OrderNumber = getRandomOrderId("profile"),
                PaymentProfile = new PaymentProfileField() {
                    CardId = 2,
                    CustomerCode = response.Id
                }
            });
            Console.WriteLine (payment.Message);
            Assert.IsNotNull (payment);
            Assert.AreEqual ("Approved", payment.Message);
            Assert.AreEqual ("P", payment.TransType);
            Assert.AreEqual ("VI", payment.Card.CardType);

            // delete it so when we create a profile again with the same card we won't get an error
            beanstream.Profiles.DeleteProfile (response.Id);
        }
        public void ItShouldThrowArgumentExceptionForInvalidTransactionId()
        {
            // Arrange
            _executer.Setup(e => e.ExecuteCommand(It.IsAny<ExecuteWebRequest>()))
                .Throws(new ArgumentNullException());

            Gateway beanstream = new Gateway () {
                MerchantId = 300200578,
                PaymentsApiKey = "4BaD82D9197b4cc4b70a221911eE9f70",
                ApiVersion = "1"
            };
            beanstream.WebCommandExecuter = _executer.Object;

            // Act
            var ex = (ArgumentNullException)Assert.Throws(typeof(ArgumentNullException),
                () => beanstream.Payments.Void(null, 10));

            // Assert
            Assert.That(ex.ParamName, Is.EqualTo("paymentId"));
        }
        public void ItShouldThrowForbiddenExceptionForInvalidCredentials()
        {
            // Arrange

            _executer.Setup(e => e.ExecuteCommand(It.IsAny<ExecuteWebRequest>()))
                            .Throws(new ForbiddenException(HttpStatusCode.Forbidden, "", "", 1, 0));

            Gateway beanstream = new Gateway () {
                MerchantId = 300200578,
                PaymentsApiKey = "4BaD82D9197b4cc4b70a221911eE9f70",
                ApiVersion = "1"
            };
            beanstream.WebCommandExecuter = _executer.Object;

            // Act
            var ex = (ForbiddenException)Assert.Throws(typeof(ForbiddenException),
                () => beanstream.Payments.Return(TrnId,_returnRequest));

            // Assert
            Assert.That(ex.StatusCode, Is.EqualTo((int)HttpStatusCode.Forbidden));
        }