@Test
  public void testPreAuthorization() {

    Gateway beanstream = new Gateway("v1", 300200578, "4BaD82D9197b4cc4b70a221911eE9f70");

    CardPaymentRequest paymentRequest = new CardPaymentRequest();
    paymentRequest.setAmount(90.00);
    paymentRequest.setOrderNumber(getRandomOrderId("GAS"));
    paymentRequest
        .getCard()
        .setName("John Doe")
        .setNumber("5100000010001004")
        .setExpiryMonth("12")
        .setExpiryYear("18")
        .setCvd("123");

    try {
      PaymentResponse response = beanstream.payments().preAuth(paymentRequest);
      PaymentResponse authResp = beanstream.payments().preAuthCompletion(response.id, 43.50);
      if (!authResp.isApproved()) {
        Assert.fail(
            "This auth completion should be approved because a greater amount has been pre authorized");
      }
    } catch (BeanstreamApiException ex) {
      System.out.println(BeanstreamResponse.fromException(ex));
      Assert.fail(ex.getMessage());
    }

    // Pre-auth and complete again but supply PaymentRequest details in the complete
    CardPaymentRequest paymentRequest2 = new CardPaymentRequest();
    paymentRequest2.setAmount(30.00);
    paymentRequest2.setOrderNumber(getRandomOrderId("Pumpkins"));
    paymentRequest2
        .getCard()
        .setName("John Doe")
        .setNumber("5100000010001004")
        .setExpiryMonth("12")
        .setExpiryYear("18")
        .setCvd("123");

    try {
      PaymentResponse response = beanstream.payments().preAuth(paymentRequest2);
      paymentRequest2.setAmount(4.00);
      PaymentResponse authResp =
          beanstream.payments().preAuthCompletion(response.id, paymentRequest2);
      if (!authResp.isApproved()) {
        Assert.fail(
            "This auth completion should be approved because a greater amount has been pre authorized");
      }

    } catch (BeanstreamApiException ex) {
      System.out.println(BeanstreamResponse.fromException(ex));
      Assert.fail(ex.getMessage());
    }
  }
  @Test
  public void testPayment() {

    Gateway beanstream = new Gateway("v1", 300200578, "4BaD82D9197b4cc4b70a221911eE9f70");

    /* Test Card Payment */
    CardPaymentRequest req = new CardPaymentRequest();
    req.setAmount(100.00).setOrderNumber(getRandomOrderId("test"));
    req.getCard()
        .setName("John Doe")
        .setNumber("5100000010001004")
        .setExpiryMonth("12")
        .setExpiryYear("18")
        .setCvd("123");

    try {

      PaymentResponse response = beanstream.payments().makePayment(req);
      System.out.println("Card Payment Approved? " + response.isApproved());

    } catch (BeanstreamApiException ex) {
      Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "An error occurred", ex);
      Assert.fail(ex.getMessage());
    }

    /* Test Cash Payment */
    CashPaymentRequest cashReq = new CashPaymentRequest();
    cashReq.setAmount(123.45);
    cashReq.setOrderNumber(getRandomOrderId("cash"));

    try {

      PaymentResponse response = beanstream.payments().makePayment(cashReq);
      System.out.println("Cash Payment Approved? " + response.isApproved());

    } catch (BeanstreamApiException ex) {
      Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "An error occurred", ex);
      Assert.fail(ex.getMessage());
    }

    /* Test Cheque Payment */
    ChequePaymentRequest chequeReq = new ChequePaymentRequest();
    chequeReq.setAmount(668.99);
    chequeReq.setOrderNumber(getRandomOrderId("cheque"));

    try {

      PaymentResponse response = beanstream.payments().makePayment(chequeReq);
      System.out.println("Cheque Payment Approved? " + response.isApproved());

    } catch (BeanstreamApiException ex) {
      Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "An error occurred", ex);
      Assert.fail(ex.getMessage());
    }
  }
  @Test
  public void testMakePaymentsWithProfile() {
    Gateway beanstream =
        new Gateway(
            "v1",
            300200578,
            "4BaD82D9197b4cc4b70a221911eE9f70", // payments API passcode
            "D97D3BE1EE964A6193D17A571D9FBC80", // profiles API passcode
            "4e6Ff318bee64EA391609de89aD4CF5d"); // reporting API passcode

    Address billing = getTestCardValidAddress();
    Card card =
        new Card()
            .setName("JANE DOE")
            .setNumber("5100000010001004")
            .setExpiryMonth("12")
            .setExpiryYear("18")
            .setCvd("123");

    try {
      ProfileResponse profile = beanstream.profiles().createProfile(card, billing);

      ProfilePaymentRequest paymentRequest = new ProfilePaymentRequest();
      paymentRequest.setProfile(
          new ProfilePaymentRequestData().setCardId(1).setCustomerCode(profile.getId()));
      paymentRequest.setAmount(13);
      paymentRequest.setOrderNumber(getRandomOrderId("TEST"));

      // make a regular payment
      PaymentResponse result = beanstream.payments().makePayment(paymentRequest);
      Assert.assertNotNull(result);

      // run a pre-auth
      paymentRequest.setAmount(100).setOrderNumber(getRandomOrderId("TEST"));
      result = beanstream.payments().preAuth(paymentRequest);
      Assert.assertNotNull(result);
      Assert.assertTrue("PA".equals(result.type));

      // complete the pre-auth
      result = beanstream.payments().preAuthCompletion(result.id, 100);
      Assert.assertNotNull(result);
      Assert.assertTrue("PAC".equals(result.type));

    } catch (BeanstreamApiException ex) {
      Logger.getLogger(SampleTransactions.class.getName()).log(Level.SEVERE, null, ex);
      Assert.fail(ex.getMessage());
    }
  }
  @Test
  public void testGetTransaction() {

    Gateway beanstream =
        new Gateway(
            "v1",
            300200578,
            "4BaD82D9197b4cc4b70a221911eE9f70", // payments API passcode
            "D97D3BE1EE964A6193D17A571D9FBC80", // profiles API passcode
            "4e6Ff318bee64EA391609de89aD4CF5d"); // reporting API passcode

    CardPaymentRequest paymentRequest = new CardPaymentRequest();
    paymentRequest.setAmount(30.00).setOrderNumber(getRandomOrderId("get"));
    paymentRequest
        .getCard()
        .setName("John Doe")
        .setNumber("5100000010001004")
        .setExpiryMonth("12")
        .setExpiryYear("18")
        .setCvd("123");

    try {
      PaymentResponse response = beanstream.payments().makePayment(paymentRequest);
      Assert.assertTrue(response.isApproved());

      if (response.isApproved()) {
        Transaction transaction = beanstream.reports().getTransaction(response.id);
        System.out.println(
            "Transaction: " + transaction.getAmount() + " approved? " + transaction.getApproved());
      }
    } catch (BeanstreamApiException ex) {
      Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "An error occurred", ex);
      Assert.fail(ex.getMessage());
    }
  }
  @Test
  public void testReturnPayment() {

    Gateway beanstream = new Gateway("v1", 300200578, "4BaD82D9197b4cc4b70a221911eE9f70");

    CardPaymentRequest paymentRequest = new CardPaymentRequest();
    paymentRequest.setAmount(70.00);
    paymentRequest.setOrderNumber(getRandomOrderId("PEDRO"));
    paymentRequest
        .getCard()
        .setName("John Doe")
        .setNumber("5100000010001004")
        .setExpiryMonth("12")
        .setExpiryYear("18")
        .setCvd("123");

    try {
      PaymentResponse response = beanstream.payments().makePayment(paymentRequest);
      if (response.isApproved()) {
        Gson gsonpp = new GsonBuilder().setPrettyPrinting().create();
        System.out.println("Your Payment has been approved response: \n" + gsonpp.toJson(response));

        response = beanstream.payments().returnPayment(response.id, 70.00);

        if ("R".equals(response.type)) {
          System.out.println("The payment was retuned");

        } else {
          System.out.println("The payment was not returned");
        }
      }
    } catch (BeanstreamApiException ex) {
      Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "An error occurred", ex);
      Assert.fail(ex.getMessage());
    }
  }
  @Test
  public void TestCustomConnectionParameters() {
    RequestConfig reqC =
        RequestConfig.custom()
            .setSocketTimeout(10) // 1/100 of a second in miliseconds
            .setConnectTimeout(10) // 1/100 of a second in miliseconds
            .build();
    HttpClient client = HttpClients.custom().setDefaultRequestConfig(reqC).build();

    Gateway beanstream =
        new Gateway(
            "v1",
            300200578,
            "4BaD82D9197b4cc4b70a221911eE9f70", // payments API passcode
            "D97D3BE1EE964A6193D17A571D9FBC80", // profiles API passcode
            "4e6Ff318bee64EA391609de89aD4CF5d"); // reporting API passcode

    beanstream.setCustomHttpsClient(client);

    // this should time out
    CardPaymentRequest req = new CardPaymentRequest();
    req.setAmount(100.00).setOrderNumber(getRandomOrderId("test"));
    req.getCard()
        .setName("John Doe")
        .setNumber("5100000010001004")
        .setExpiryMonth("12")
        .setExpiryYear("18")
        .setCvd("123");

    boolean timedOut = false;
    try {

      PaymentResponse response = beanstream.payments().makePayment(req);

    } catch (BeanstreamApiException ex) {
      if ("Connection error".equalsIgnoreCase(ex.getMessage())) timedOut = true;
    }
  }
  @Test
  public void testQueryTransactions() {
    System.out.println("############################################################3");
    System.out.println("############################################################3");
    System.out.println("############################################################3");
    System.out.println("############################################################3");
    Gateway beanstream =
        new Gateway(
            "v1",
            300200578,
            "4BaD82D9197b4cc4b70a221911eE9f70", // payments API passcode
            "D97D3BE1EE964A6193D17A571D9FBC80", // profiles API passcode
            "4e6Ff318bee64EA391609de89aD4CF5d"); // reporting API passcode

    String order = getRandomOrderId("q");
    CardPaymentRequest paymentRequest = new CardPaymentRequest();
    paymentRequest.setAmount(20.50).setOrderNumber(order);
    paymentRequest
        .getCard()
        .setName("Bob Doe")
        .setNumber("5100000010001004")
        .setExpiryMonth("12")
        .setExpiryYear("18")
        .setCvd("123");

    try {
      PaymentResponse response = beanstream.payments().makePayment(paymentRequest);
      if (response.isApproved()) {
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_MONTH, -1);
        Date startDate = cal.getTime(); // yesterday
        cal = Calendar.getInstance();
        cal.add(Calendar.DAY_OF_MONTH, 1);
        Date endDate = cal.getTime(); // tomorrow
        Criteria[] searchFilter =
            new Criteria[] {new Criteria(QueryFields.OrderNumber, Operators.Equals, order)};
        List<TransactionRecord> query =
            beanstream.reports().query(startDate, endDate, 1, 2, searchFilter);
        Assert.assertNotNull(query);
        Assert.assertFalse(query.isEmpty());

        System.out.println("Queried " + query.size() + " items.");

        // print out the first 10 records
        int i = 0;
        for (TransactionRecord tr : query) {
          System.out.println(
              tr.getTransactionId() + " from " + tr.getCardOwner() + " -> $" + tr.getAmount());
          i++;
          if (i > 10) {
            break;
          }
        }
      }
    } catch (BeanstreamApiException ex) {
      Logger.getLogger(this.getClass().getName())
          .log(Level.SEVERE, "An error occurred: " + ex.toString(), ex);
      System.out.println("Error Details: " + ex.getCode() + ", " + ex.getCategory());
      Assert.fail(ex.getMessage());
    }
  }
  @Test
  public void testTokenPayment() {

    Gateway beanstream = new Gateway("v1", 300200578, "4BaD82D9197b4cc4b70a221911eE9f70");
    HttpsConnector connector = new HttpsConnector(300200578, "4BaD82D9197b4cc4b70a221911eE9f70");

    /* Test Token Payment */
    // 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
    LegatoTokenRequest legatoTokenRequest = new LegatoTokenRequest();
    legatoTokenRequest.number = "5100000010001004";
    legatoTokenRequest.expiryMonth = 12;
    legatoTokenRequest.expiryYear = 18;
    legatoTokenRequest.cvd = "123";

    String url = "https://www.beanstream.com/scripts/tokenization/tokens";
    String output = "";
    try {
      output = connector.ProcessTransaction(HttpMethod.post, url, legatoTokenRequest);
    } catch (BeanstreamApiException ex) {
      Logger.getLogger(SampleTransactions.class.getName()).log(Level.SEVERE, null, ex);
      Assert.fail(ex.getMessage());
    }

    // Parse the output and return a token response to get the token for the
    // payment request
    Gson gson = new Gson();
    LegatoTokenResponse tokenResponse = gson.fromJson(output, LegatoTokenResponse.class);

    System.out.println("token: " + output);

    TokenPaymentRequest tokenReq = new TokenPaymentRequest();
    tokenReq.setAmount(100.00);
    tokenReq.setOrderNumber(getRandomOrderId("token"));
    tokenReq.getToken().setName("John Doe").setCode(tokenResponse.getToken());

    try {
      PaymentResponse response = beanstream.payments().makePayment(tokenReq);
      System.out.println("Token Payment Approved? " + response.isApproved());

    } catch (BeanstreamApiException ex) {
      Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "An error occurred", ex);
      Assert.fail(ex.getMessage());
    }

    // Pre-Auth and Complete

    try {
      output = connector.ProcessTransaction(HttpMethod.post, url, legatoTokenRequest);
    } catch (BeanstreamApiException ex) {
      Logger.getLogger(SampleTransactions.class.getName()).log(Level.SEVERE, null, ex);
      Assert.fail(ex.getMessage());
    }
    tokenResponse = gson.fromJson(output, LegatoTokenResponse.class);

    System.out.println("Token pre-auth: " + tokenResponse.getToken());

    TokenPaymentRequest req = new TokenPaymentRequest();
    req.setAmount(80.00);
    req.setOrderNumber(getRandomOrderId("token"));
    req.getToken().setName("John Doe").setCode(tokenResponse.getToken());

    try {
      PaymentResponse response = beanstream.payments().preAuth(req);
      System.out.println("Token Payment Approved? " + response.isApproved());
      response = beanstream.payments().preAuthCompletion(response.id, 55.30);
      Assert.assertTrue(response.isApproved());
      Assert.assertEquals("PAC", response.type);
    } catch (BeanstreamApiException ex) {
      Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "An error occurred", ex);
      Assert.fail(ex.getMessage());
    }
  }