예제 #1
0
        public BitPayTest2()
        {
            try
            {
                // If this test has never been run before then this test must be run twice in order to pass.
                // The first time this test runs it will create an identity and emit a client pairing code.
                // The pairing code must then be authorized in a BitPay account.  Running the test a second
                // time should result in the authorized client (this test) running to completion.
                bitpay = new BitPay(clientName);

                if (!bitpay.clientIsAuthorized(BitPay.FACADE_POS))
                {
                    // Get POS facade authorization code.
                    // Obtain a pairingCode from the BitPay server.  The pairingCode must be emitted from
                    // this device and input into and approved by the desired merchant account.  To
                    // generate invoices a POS facade is required.
                    String pairingCode = bitpay.requestClientAuthorization(BitPay.FACADE_POS);

                    // Signal the device operator that this client needs to be paired with a merchant account.
                    System.Diagnostics.Debug.WriteLine("Info: Pair this client with your merchant account using the pairing code: " + pairingCode);
                    throw new BitPayException("Error: client is not yet authorized, pair this client with your BitPay merchant account using the pairing code: " + pairingCode);
                }
            }
            catch (Exception ex)
            {
                Assert.Fail(ex.Message);
            }
        }
예제 #2
0
        private static bool TestTokenSuccess(string facade)
        {
            try
            {
                var bitpay = new BitPay(confFilePath);
                if (facade == Facade.Merchant)
                {
                    var response = bitpay.GetInvoice("1", facade).Result;
                }
                else if (facade == Facade.Payroll)
                {
                    var response = bitpay.GetPayoutBatch("1").Result;
                }

                return(true);
            }
            catch (Exception e)
            {
                if (e.InnerException.Message.ToLower().Contains("object not found"))
                {
                    return(true);
                }

                return(false);
            }
        }
예제 #3
0
        public BitPayTest3()
        {
            try
            {
                bitpay = new BitPay(clientName);

                if (!bitpay.clientIsAuthorized(BitPay.FACADE_PAYROLL))
                {
                    // Get PAYROLL facade authorization.
                    // Obtain a pairingCode from your BitPay account administrator.  When the pairingCode
                    // is created by your administrator it is assigned a facade.  To generate payout batches a
                    // PAYROLL facade is required.

                    // As an alternative to this client outputting a pairing code, the BitPay account owner
                    // may interactively generate a pairing code via the BitPay merchant dashboard at
                    // https://[test].bitpay.com/dashboard/merchant/api-tokens.  This client can subsequently
                    // accept the pairing code using the following call.

                    // bitpay.authorizeClient(pairingCode);

                    String pairingCode = bitpay.requestClientAuthorization(BitPay.FACADE_PAYROLL);

                    // Signal the device operator that this client needs to be paired with a merchant account.
                    System.Diagnostics.Debug.WriteLine("Info: Pair this client with your merchant account using the pairing code: " + pairingCode);
                    System.Console.WriteLine("Info: Pair this client with your merchant account using the pairing code: " + pairingCode);
                    throw new BitPayException("Error: client is not yet authorized, pair this client with your BitPay merchant account using the pairing code: " + pairingCode);
                }
            }
            catch (Exception ex)
            {
                Assert.Fail(ex.Message);
            }
        }
예제 #4
0
        public BitPayTest()
        {
            decimal price = 100.0m;

            this.bitpay  = new BitPay(API_KEY);
            basicInvoice = this.bitpay.createInvoice(price, "USD");
        }
예제 #5
0
        // Will store one of the generated invoices during the test
        // so it can be paid manually in order to pass the ledger tests

        public Tests()
        {
            // JSON minified with the BitPay configuration as in the required configuration file
            // and parsed into a IConfiguration object
            var json               = "{\"BitPayConfiguration\":{\"Environment\":\"Test\",\"EnvConfig\":{\"Test\":{\"PrivateKeyPath\":\"bitpay_private_test.key\",\"ApiTokens\":{\"merchant\":\"CE2WRSEEt9FgXvXboxNFA4YdQyyDJmgVAo752TGA7eUj\",\"payroll\":\"9pJ7fzW1GGeuDQfj32aNATCDnyY6YAacVMcDrs7HHUNo\"}},\"Prod\":{\"PrivateKeyPath\":\"\",\"ApiTokens\":{\"merchant\":\"\",\"payroll\":\"\"}}}}}";
            var memoryJsonFile     = new MemoryFileInfo("config.json", Encoding.UTF8.GetBytes(json), DateTimeOffset.Now);
            var memoryFileProvider = new MockFileProvider(memoryJsonFile);

            var configuration = new ConfigurationBuilder()
                                .AddJsonFile(memoryFileProvider, "config.json", false, false)
                                .Build();

            // Initialize the BitPay object to be used in the following tests
            // Initialize with IConfiguration object
            _bitpay = new BitPay(configuration);

            // Initialize with separate variables
            _bitpay = new BitPay(
                Env.Test,
                "bitpay_private_test.key",
                new Env.Tokens()
            {
                Merchant = "CE2WRSEEt9FgXvXboxNFA4YdQyyDJmgVAo752TGA7eUj",
                Payout   = "9pJ7fzW1GGeuDQfj32aNATCDnyY6YAacVMcDrs7HHUNo"
            }
                );

            // ledgers require the Merchant Facade
            if (!_bitpay.tokenExist(Facade.Merchant))
            {
                // get a pairing code for the merchant facade for this client
                var pcode = _bitpay.RequestClientAuthorization(Facade.Merchant).Result;

                /* We can't continue. Please make sure you write down this pairing code, then goto
                 *  your BitPay account in the API Tokens section
                 *  https://test.bitpay.com/dashboard/merchant/api-tokens
                 *  and paste it into the search field.
                 *  It should get you to a page to approve it. After you approve it, run the tests
                 *  again and they should pass.
                 */
                throw new BitPayException("Please approve the pairing code " + pcode + " in your account.");
            }

            // ledgers require the Payroll Facade
            if (!_bitpay.tokenExist(Facade.Payroll))
            {
                // get a pairing code for the merchant facade for this client
                var pcode = _bitpay.RequestClientAuthorization(Facade.Payroll).Result;

                /* We can't continue. Please make sure you write down this pairing code, then goto
                 *  your BitPay account in the API Tokens section
                 *  https://test.bitpay.com/dashboard/merchant/api-tokens
                 *  and paste it into the search field.
                 *  It should get you to a page to approve it. After you approve it, run the tests
                 *  again and they should pass.
                 */
                throw new BitPayException("Please approve the pairing code " + pcode + " in your account.");
            }
        }
예제 #6
0
 public async Task GrantAccessAsync()
 {
     await RegisterAsync();
     await CreateStoreAsync();
     var store = this.GetController<StoresController>();
     var pairingCode = BitPay.RequestClientAuthorization("test", Facade.Merchant);
     Assert.IsType<ViewResult>(await store.RequestPairing(pairingCode.ToString()));
     await store.Pair(pairingCode.ToString(), StoreId);
 }
예제 #7
0
        public void Init()
        {
            // JSON minified with the BitPay configuration as in the required configuration file
            // and parsed into a IConfiguration object
            var json               = "{\"BitPayConfiguration\":{\"Environment\":\"Test\",\"EnvConfig\":{\"Test\":{\"ClientDescription\":\"" + ClientName + "\",\"ApiUrl\":\"https://test.bitpay.com/\",\"ApiVersion\":\"2.0.0\",\"PrivateKeyPath\":\"sec/bitpay_test_private.key\",\"ApiTokens\":{\"pos\":\"FrbBsxHFkoTbzJPDe6vzBghJzMvDe1nbGUJ3M6n5MHQd\",\"merchant\":\"EZYmyjSaUXh6NcF7Ej9g7dizhhsW2eRvWT29W6CG1omT\",\"payroll\":\"DjyLfN2JDeFoHgUV9Xpx3kvLpA5G2emiyFxUv1q9CREt\"}},\"Prod\":{\"ClientDescription\":\"\",\"ApiUrl\":\"https://bitpay.com/\",\"ApiVersion\":\"2.0.0\",\"PrivateKeyPath\":\"\",\"ApiTokens\":{\"pos\":\"\",\"merchant\":\"\",\"payroll\":\"\"}}}}}";
            var memoryJsonFile     = new MemoryFileInfo("config.json", Encoding.UTF8.GetBytes(json), DateTimeOffset.Now);
            var memoryFileProvider = new MockFileProvider(memoryJsonFile);

            var configuration = new ConfigurationBuilder()
                                .AddJsonFile(memoryFileProvider, "config.json", false, false)
                                .Build();

            // Initialize the BitPay object to be used in the following tests
            _bitpay = new BitPay(configuration);

            // If the client doesn't have a POS token yet, fetch one.
            // For the Merchant and Payroll Facades, see below, in their corresponding tests
            if (!_bitpay.tokenExist(Facade.PointOfSale))
            {
                _bitpay.AuthorizeClient(PairingCode);
            }

            // ledgers require the Merchant Facade
            if (!_bitpay.tokenExist(Facade.Merchant))
            {
                // get a pairing code for the merchant facade for this client
                var pcode = _bitpay.RequestClientAuthorization(Facade.Merchant).Result;

                /* We can't continue. Please make sure you write down this pairing code, then goto
                 *  your BitPay account in the API Tokens section
                 *  https://test.bitpay.com/dashboard/merchant/api-tokens
                 *  and paste it into the search field.
                 *  It should get you to a page to approve it. After you approve it, run the tests
                 *  again and they should pass.
                 */
                throw new BitPayException("Please approve the pairing code " + pcode + " in your account.");
            }

            // ledgers require the Payroll Facade
            if (!_bitpay.tokenExist(Facade.Payroll))
            {
                // get a pairing code for the merchant facade for this client
                var pcode = _bitpay.RequestClientAuthorization(Facade.Payroll).Result;

                /* We can't continue. Please make sure you write down this pairing code, then goto
                 *  your BitPay account in the API Tokens section
                 *  https://test.bitpay.com/dashboard/merchant/api-tokens
                 *  and paste it into the search field.
                 *  It should get you to a page to approve it. After you approve it, run the tests
                 *  again and they should pass.
                 */
                throw new BitPayException("Please approve the pairing code " + pcode + " in your account.");
            }
        }
예제 #8
0
        public void testShouldGetCNYExchangeRate()
        {
            // Arrange

            // Act
            this.bitpay = new BitPay(API_KEY);
            Rates rates = this.bitpay.getRates();

            // Assert
            decimal rate = rates.getRate("CNY");

            Assert.IsTrue(rate != 0, "Exchange rate not retrieved: CNY");
        }
예제 #9
0
        public void testShouldUpdateExchangeRates()
        {
            // Arrange

            // Act
            this.bitpay = new BitPay(API_KEY);
            Rates rates = this.bitpay.getRates();

            rates.update();

            // Assert
            List <Rate> listRates = rates.getRates();

            Assert.IsNotNull(listRates, "Exchange rates not retrieved after update");
        }
예제 #10
0
        public void Init()
        {
            // Initialize the BitPay object to be used in the following tests
            _bitpay = new BitPay(ClientName, BitpayTestUrl);

            // If the client doesn't have a POS token yet, fetch one.
            // For the Merchant and Payroll Facades, see below, in their corresponding tests
            if (!_bitpay.ClientIsAuthorized(BitPay.FacadePos))
            {
                _bitpay.AuthorizeClient(PairingCode).Wait();
            }

            // ledgers require the Merchant Facade
            if (!_bitpay.ClientIsAuthorized(BitPay.FacadeMerchant))
            {
                // get a pairing code for the merchant facade for this client
                var pcode = _bitpay.RequestClientAuthorization(BitPay.FacadeMerchant).Result;

                /* We can't continue. Please make sure you write down this pairing code, then goto
                 *  your BitPay account in the API Tokens section
                 *  https://test.bitpay.com/dashboard/merchant/api-tokens
                 *  and paste it into the search field.
                 *  It should get you to a page to approve it. After you approve it, run the tests
                 *  again and they should pass.
                 */
                throw new BitPayException("Please approve the pairing code " + pcode + " in your account.");
            }

            // ledgers require the Payroll Facade
            if (!_bitpay.ClientIsAuthorized(BitPay.FacadePayroll))
            {
                // get a pairing code for the merchant facade for this client
                var pcode = _bitpay.RequestClientAuthorization(BitPay.FacadePayroll).Result;

                /* We can't continue. Please make sure you write down this pairing code, then goto
                 *  your BitPay account in the API Tokens section
                 *  https://test.bitpay.com/dashboard/merchant/api-tokens
                 *  and paste it into the search field.
                 *  It should get you to a page to approve it. After you approve it, run the tests
                 *  again and they should pass.
                 */
                throw new BitPayException("Please approve the pairing code " + pcode + " in your account.");
            }
        }
예제 #11
0
        public void testShouldGetExchangeRates()
        {
            try
            {
                // Arrange

                // Act
                this.bitpay = new BitPay(API_KEY);
                Rates rates = this.bitpay.getRates();

                // Assert
                List <Rate> listRates = rates.getRates();
                Assert.IsNotNull(listRates, "Exchange rates not retrieved");
            }
            catch (BitPayException ex)
            {
                Assert.Fail(ex.getMessage());
            }
        }
예제 #12
0
        public BitPayTest()
        {
            try
            {
                // This scenario qualifies that this (test) client does not have merchant facade access.
                bitpay = new BitPay(clientName);

                if (!bitpay.clientIsAuthorized(BitPay.FACADE_POS))
                {
                    // Get POS facade authorization.
                    // Obtain a pairingCode from your BitPay account administrator.  When the pairingCode
                    // is created by your administrator it is assigned a facade.  To generate invoices a
                    // POS facade is required.
                    bitpay.authorizeClient(pairingCode);
                }
            }
            catch (Exception ex)
            {
                Assert.Fail(ex.Message);
            }
        }
예제 #13
0
        public void testShouldCreateInvoice100USD()
        {
            try
            {
                // Arrange
                decimal price    = 100.0m;
                decimal expected = 100.0m;

                // Act
                this.bitpay = new BitPay(API_KEY);
                Invoice invoice = this.bitpay.createInvoice(price, "USD");

                // Assert
                decimal actual = invoice.price;
                Assert.AreEqual(expected, actual, "Invoice not created correctly: 100USD");
            }
            catch (BitPayException ex)
            {
                Assert.Fail(ex.getMessage());
            }
        }
예제 #14
0
        public void testShouldCreateInvoiceOneTenthBTC()
        {
            try
            {
                // Arrange
                decimal price    = 0.1m;
                decimal expected = 0.1m;

                // Act
                this.bitpay = new BitPay(API_KEY);
                Invoice invoice = this.bitpay.createInvoice(price, "BTC");

                // Assert
                decimal actual = invoice.btcPrice;
                Assert.AreEqual(expected, actual, "Invoice not created correctly: 0.1BTC");
            }
            catch (BitPayException ex)
            {
                Assert.Fail(ex.getMessage());
            }
        }
예제 #15
0
        public void testShouldGetInvoice()
        {
            try
            {
                // Arrange
                decimal price = 100.0m;

                // Act
                this.bitpay = new BitPay(API_KEY);
                Invoice invoice          = this.bitpay.createInvoice(price, "EUR");
                Invoice retreivedInvoice = this.bitpay.getInvoice(invoice.id);

                // Assert
                string expected = invoice.id;
                string actual   = retreivedInvoice.id;
                Assert.AreEqual(expected, actual, "Expected invoice not retreived");
            }
            catch (BitPayException ex)
            {
                Assert.Fail(ex.getMessage());
            }
        }
예제 #16
0
        public void testShouldCreateInvoiceWithAdditionalParams()
        {
            try
            {
                // Arrange
                decimal       price      = 100.0m;
                InvoiceParams parameters = new InvoiceParams();
                parameters.buyerName         = "Satoshi";
                parameters.buyerEmail        = "*****@*****.**";
                parameters.fullNotifications = true;
                parameters.notificationEmail = "*****@*****.**";

                // Act
                this.bitpay = new BitPay(API_KEY);
                Invoice invoice = this.bitpay.createInvoice(price, "USD", parameters);

                // Assert
                Assert.IsNotNull(invoice, "Invoice not created");
            }
            catch (BitPayException ex)
            {
                Assert.Fail(ex.getMessage());
            }
        }
예제 #17
0
 public Rates(List <Rate> rates, BitPay bp)
 {
     _bp    = bp;
     _rates = rates;
 }
예제 #18
0
        private static void GetPairingCodeAndToken()
        {
            string newToken;

            SetFacade();
            var apiTokens = new ApiTokens();

            if (env == Env.Test)
            {
                apiTokens = appConfig.BitPayConfiguration.EnvConfig.Test.ApiTokens;
            }
            if (env == Env.Prod)
            {
                apiTokens = appConfig.BitPayConfiguration.EnvConfig.Prod.ApiTokens;
            }

            if (TokenCurrentlyExists(facade, apiTokens))
            {
                SetNotification(" A token for this Facade (" + facade + ") on this Environment (" + env +
                                ") already exists.");
                Console.Clear();
                DrawTitle();
                Console.WriteLine(" Would you want to replace it for a new one? [yes|no] (default: no)");
                Console.WriteLine();
                Console.Write(" > ");
                var answer = Console.ReadLine();
                while (answer.ToLower() != "yes" && answer.ToLower() != "no" && answer.ToLower() != "")
                {
                    answer = Console.ReadLine();
                }

                if (answer.ToLower() == "no")
                {
                    return;
                }
            }

            try
            {
                var bitpay = new BitPay(confFilePath);

                var pairingCodeObj = bitpay.RequestClientAuthorization(facade);

                pairingCode = pairingCodeObj.Result;

                newToken = bitpay.GetTokenByFacade(facade);
            }
            catch (Exception e)
            {
                SetNotification(
                    " An error occurred while generating a new token pair.\n Make sure you have created a/o selected a private key.\n Error Details: " +
                    e.Message);

                return;
            }

            switch (facade)
            {
            case Facade.PointOfSale:
                apiTokens.pos = newToken;
                break;

            case Facade.Merchant:
                apiTokens.merchant = newToken;
                break;

            case Facade.Payroll:
                apiTokens.payroll = newToken;
                break;
            }

            var envUrl = "";

            if (env == Env.Test)
            {
                appConfig.BitPayConfiguration.EnvConfig.Test.ApiTokens = apiTokens;
                envUrl = appConfig.BitPayConfiguration.EnvConfig.Test.ApiUrl;
            }

            if (env == Env.Prod)
            {
                appConfig.BitPayConfiguration.EnvConfig.Prod.ApiTokens = apiTokens;
                envUrl = appConfig.BitPayConfiguration.EnvConfig.Prod.ApiUrl;
            }

            GenerateConfFile(confFilePath);

            SetNotification(" New pairing code for " + facade + " facade: " + pairingCode + "\n Please, copy the above pairing code and approve on your BitPay Account at the following link:\n \"" +
                            envUrl + "dashboard/merchant/api-tokens\".\n Once this Pairing Code is approved, your .Net Client will be ready to work with the API.\n A new token for this pairing code has been added to the configuration file.");
        }
 public Tests()
 {
     // Initialize the BitPay object to be used in the following tests
     _bitpay = new BitPay(token, environment);
 }
예제 #20
0
        private static void GetPairingCodeAndToken()
        {
            string newToken = "";

            SetFacade();
            if (String.IsNullOrEmpty(facade))
            {
                return;
            }

            Console.Clear();
            DrawTitle();
            Console.WriteLine(" Would you like to request a token for the " + facade.ToUpperInvariant() +
                              " facade? [yes|no] (default: yes)");
            Console.WriteLine();
            Console.Write(" > ");
            var answer = Console.ReadLine();

            while (answer.ToLower() != "yes" && answer.ToLower() != "no" && answer.ToLower() != "")
            {
                answer = Console.ReadLine();
            }

            if (answer.ToLower() == "no")
            {
                GetPairingCodeAndToken();
                return;
            }

            if (facade == Facade.Payroll)
            {
                SetNotification(
                    " In order to get access to the Payroll facade, you need to contact Support at [email protected]",
                    3);
                Console.Clear();
                DrawTitle();
                Console.WriteLine(" Did you contact and receive confirmation yet? [yes|no] (default: yes)");
                Console.WriteLine(
                    " If 'no', a new file will be generated in the entered location with the given name.");
                Console.WriteLine();
                Console.Write(" > ");
                answer = Console.ReadLine();
                while (answer.ToLower() != "yes" && answer.ToLower() != "no" && answer.ToLower() != "")
                {
                    answer = Console.ReadLine();
                }

                if (answer.ToLower() == "no")
                {
                    GetPairingCodeAndToken();
                    return;
                }
            }

            var apiTokens = new ApiTokens();

            if (env == Env.Test)
            {
                apiTokens = appConfig.BitPayConfiguration.EnvConfig.Test.ApiTokens;
            }
            if (env == Env.Prod)
            {
                apiTokens = appConfig.BitPayConfiguration.EnvConfig.Prod.ApiTokens;
            }

            if (TokenCurrentlyExists(facade, apiTokens))
            {
                SetNotification(" A token for this Facade (" + facade + ") on this Environment (" + env +
                                ") already exists.", 3);
                Console.Clear();
                DrawTitle();
                Console.WriteLine(" Would you like to replace it for a new one? [yes|no] (default: no)");
                Console.WriteLine();
                Console.Write(" > ");
                answer = Console.ReadLine();
                while (answer.ToLower() != "yes" && answer.ToLower() != "no")
                {
                    answer = Console.ReadLine();
                }

                if (answer.ToLower() == "no" || answer.ToLower() == "")
                {
                    return;
                }
            }

            var retry = true;

            while (retry)
            {
                try
                {
                    var bitpay = new BitPay(confFilePath);

                    pairingCode = bitpay.RequestClientAuthorization(facade).Result;

                    newToken = bitpay.GetTokenByFacade(facade);
                }
                catch (Exception e)
                {
                    SetNotification(
                        " An error occurred while generating a new token pair.\n Make sure you have created a/o selected a private key.\n Error Details: " +
                        e.Message, 2);

                    GetPairingCodeAndToken();
                    return;
                }

                switch (facade)
                {
                case Facade.Merchant:
                    apiTokens.merchant = newToken;
                    break;

                case Facade.Payroll:
                    apiTokens.payroll = newToken;
                    break;
                }

                if (env == Env.Test)
                {
                    appConfig.BitPayConfiguration.EnvConfig.Test.ApiTokens = apiTokens;
                    envUrl = "https://test.bitpay.com/";
                }

                if (env == Env.Prod)
                {
                    appConfig.BitPayConfiguration.EnvConfig.Prod.ApiTokens = apiTokens;
                    envUrl = "https://bitpay.com/";
                }

                GenerateConfFile(confFilePath);

                SetNotification(" New pairing code for " + facade + " facade: " + pairingCode +
                                "\n Please, copy the above pairing code and approve on your BitPay Account at the following link:\n \"" +
                                envUrl +
                                "dashboard/merchant/api-tokens\".\n Once this Pairing Code is approved, press Enter to run some tests.\n",
                                1);

                Console.Clear();
                DrawTitle();
                Console.Write(" If you approved the pairing code on your Dashboard, press Enter to continue: ");
                var input = Console.ReadKey();
                while (input.Key != ConsoleKey.Enter)
                {
                    input = Console.ReadKey();
                }

                while (retry = !TestTokenSuccess(facade))
                {
                    SetNotification(" Something went wrong\n Please, make sure you approved the pairing code: " +
                                    pairingCode + " for " + facade +
                                    " facade\n Copy the above pairing code and approve on your BitPay Account at the following link:\n \"" +
                                    envUrl +
                                    "dashboard/merchant/api-tokens\".\n Once this Pairing Code is approved, press Enter to run some tests again.\n\n" +
                                    "* NOTE: If you approved the pairing code and a token has been stored in the configuration file, you can\n" +
                                    "then ignore this message and close this application.\n" +
                                    "If your integration does not work with the generated files, please contact support at [email protected]\n" +
                                    "or report it as an issue on the GitHub repository for this tool.\n",
                                    2);

                    Console.Clear();
                    DrawTitle();
                    Console.Write(
                        " If you approved the pairing code on your Dashboard, press Enter to try again, N to generate a new one or X to cancel: ");
                    input = Console.ReadKey();
                    while (input.Key != ConsoleKey.Enter && input.Key != ConsoleKey.N && input.Key != ConsoleKey.X)
                    {
                        input = Console.ReadKey();
                    }

                    if (input.Key == ConsoleKey.X)
                    {
                        GetPairingCodeAndToken();

                        return;
                    }

                    if (input.Key == ConsoleKey.N)
                    {
                        retry = true;
                        break;
                    }
                }
            }

            SetNotification(
                " Token tested successfully!\n A new token for the " + facade +
                " facade has been added to the configuration file.", 1);

            Console.Clear();
            DrawTitle();
            Console.WriteLine(" Would you like to generate a token for a different facade? [yes|no] (default: no)");
            Console.WriteLine();
            Console.Write(" > ");
            var redo = Console.ReadLine();

            while (redo.ToLower() != "yes" && redo.ToLower() != "no" && redo.ToLower() != "")
            {
                redo = Console.ReadLine();
            }

            if (redo.ToLower() == "no" || redo.ToLower() == "")
            {
                return;
            }

            GetPairingCodeAndToken();
        }