@Test
  public void createTransactionFromTransparentRedirectSpecifyingLevel2Attributes() {
    TransactionRequest request =
        new TransactionRequest()
            .amount(TransactionAmount.AUTHORIZE.amount)
            .creditCard()
            .number(CreditCardNumber.VISA.number)
            .expirationDate("05/2009")
            .done();

    TransactionRequest trParams =
        new TransactionRequest()
            .type(Transaction.Type.SALE)
            .taxAmount(new BigDecimal("10.00"))
            .taxExempt(true)
            .purchaseOrderNumber("12345");

    String queryString =
        TestHelper.simulateFormPostForTR(
            gateway, trParams, request, gateway.transparentRedirect().url());
    Result<Transaction> result = gateway.transparentRedirect().confirmTransaction(queryString);

    assertTrue(result.isSuccess());
    Transaction transaction = result.getTarget();
    assertEquals(new BigDecimal("10.00"), transaction.getTaxAmount());
    assertTrue(transaction.isTaxExempt());
    assertEquals("12345", transaction.getPurchaseOrderNumber());
  }
  @Test
  public void updateCreditCardFromTransparentRedirect() {
    Customer customer = gateway.customer().create(new CustomerRequest()).getTarget();
    CreditCardRequest request =
        new CreditCardRequest()
            .customerId(customer.getId())
            .number("5105105105105100")
            .expirationDate("05/12");
    CreditCard card = gateway.creditCard().create(request).getTarget();

    CreditCardRequest updateRequest = new CreditCardRequest();
    CreditCardRequest trParams =
        new CreditCardRequest()
            .paymentMethodToken(card.getToken())
            .number("4111111111111111")
            .expirationDate("10/10");
    String queryString =
        TestHelper.simulateFormPostForTR(
            gateway, trParams, updateRequest, gateway.transparentRedirect().url());

    Result<CreditCard> result = gateway.transparentRedirect().confirmCreditCard(queryString);

    assertTrue(result.isSuccess());
    CreditCard updatedCreditCard = gateway.creditCard().find(card.getToken());
    assertEquals("411111", updatedCreditCard.getBin());
    assertEquals("1111", updatedCreditCard.getLast4());
    assertEquals("10/2010", updatedCreditCard.getExpirationDate());
  }
  @Test
  public void createTransactionFromTransparentRedirectSpecifyingDescriptor() {
    TransactionRequest request =
        new TransactionRequest()
            .amount(TransactionAmount.AUTHORIZE.amount)
            .creditCard()
            .number(CreditCardNumber.VISA.number)
            .expirationDate("05/2009")
            .done();

    TransactionRequest trParams =
        new TransactionRequest()
            .type(Transaction.Type.SALE)
            .descriptor()
            .name("123*123456789012345678")
            .phone("3334445555")
            .done();

    String queryString =
        TestHelper.simulateFormPostForTR(
            gateway, trParams, request, gateway.transparentRedirect().url());
    Result<Transaction> result = gateway.transparentRedirect().confirmTransaction(queryString);

    assertTrue(result.isSuccess());
    Transaction transaction = result.getTarget();
    assertEquals("123*123456789012345678", transaction.getDescriptor().getName());
    assertEquals("3334445555", transaction.getDescriptor().getPhone());
  }
  @Test
  public void onCustomer() {
    Result<Customer> customerResult =
        gateway.customer().create(new CustomerRequest().paymentMethodNonce(Nonce.Coinbase));
    assertTrue(customerResult.isSuccess());
    Customer customer = customerResult.getTarget();

    List<CoinbaseAccount> accounts =
        gateway.customer().find(customer.getId()).getCoinbaseAccounts();
    assertEquals(1, accounts.size());

    CoinbaseAccount account = accounts.get(0);
    assertNotNull(account);
    assertNotNull(account.getToken());
    assertNotNull(account.getUserId());
    assertThat(account.getUserId(), not(equalTo("")));
    assertNotNull(account.getUserName());
    assertThat(account.getUserName(), not(equalTo("")));
    assertNotNull(account.getUserEmail());
    assertThat(account.getUserEmail(), not(equalTo("")));

    String token = account.getToken();

    gateway.paymentMethod().delete(token);

    exception.expect(NotFoundException.class);
    gateway.paymentMethod().find(token);
  }
  @Test
  public void canVaultOnTransactionCreate() {
    TransactionRequest request =
        new TransactionRequest()
            .amount(TransactionAmount.AUTHORIZE.amount)
            .paymentMethodNonce(Nonce.Coinbase)
            .options()
            .submitForSettlement(true)
            .storeInVaultOnSuccess(true)
            .done();

    Result<Transaction> authResult = gateway.transaction().sale(request);
    assertTrue(authResult.isSuccess());

    Transaction transaction = authResult.getTarget();
    assertNotNull(transaction);
    CoinbaseDetails details = transaction.getCoinbaseDetails();
    assertNotNull(details);
    String token = details.getToken();
    assertNotNull(token);

    PaymentMethod account = gateway.paymentMethod().find(token);
    assertTrue(account instanceof CoinbaseAccount);
    assertNotNull(account);
  }
 @Test
 public void errorNotRaisedWhenReceivingApiErrorResponse() {
   TransactionRequest invalidRequest = new TransactionRequest();
   TransactionRequest trParams = new TransactionRequest().type(Transaction.Type.SALE);
   String queryString =
       TestHelper.simulateFormPostForTR(
           gateway, trParams, invalidRequest, gateway.transparentRedirect().url());
   Result<Transaction> result = gateway.transparentRedirect().confirmTransaction(queryString);
   assertFalse(result.isSuccess());
   assertTrue(result.getErrors().deepSize() > 0);
 }
  @Test
  public void createCustomerFromTransparentRedirect() {
    CustomerRequest request = new CustomerRequest().firstName("John");
    CustomerRequest trParams = new CustomerRequest().lastName("Doe");
    String queryString =
        TestHelper.simulateFormPostForTR(
            gateway, trParams, request, gateway.transparentRedirect().url());

    Result<Customer> result = gateway.transparentRedirect().confirmCustomer(queryString);

    assertTrue(result.isSuccess());
    assertEquals("John", result.getTarget().getFirstName());
    assertEquals("Doe", result.getTarget().getLastName());
  }
  @Test
  public void canCreateTransaction() {
    TransactionRequest request =
        new TransactionRequest()
            .amount(TransactionAmount.AUTHORIZE.amount)
            .paymentMethodNonce(Nonce.Coinbase);

    Result<Transaction> authResult = gateway.transaction().sale(request);
    assertTrue(authResult.isSuccess());

    CoinbaseDetails details = authResult.getTarget().getCoinbaseDetails();
    assertNotNull(details);
    assertNull(details.getToken());
    assertNotNull(details.getUserId());
    assertThat(details.getUserId(), not(equalTo("")));
    assertNotNull(details.getUserName());
    assertThat(details.getUserName(), not(equalTo("")));
    assertNotNull(details.getUserEmail());
    assertThat(details.getUserEmail(), not(equalTo("")));
  }
  @Test
  public void createTransactionFromTransparentRedirectSpecifyingMerchantAccountId() {
    TransactionRequest request =
        new TransactionRequest()
            .amount(TransactionAmount.AUTHORIZE.amount)
            .creditCard()
            .number(CreditCardNumber.VISA.number)
            .expirationDate("05/2009")
            .done();

    TransactionRequest trParams =
        new TransactionRequest()
            .type(Transaction.Type.SALE)
            .merchantAccountId(NON_DEFAULT_MERCHANT_ACCOUNT_ID);

    String queryString =
        TestHelper.simulateFormPostForTR(
            gateway, trParams, request, gateway.transparentRedirect().url());
    Result<Transaction> result = gateway.transparentRedirect().confirmTransaction(queryString);

    assertTrue(result.isSuccess());
    assertEquals(NON_DEFAULT_MERCHANT_ACCOUNT_ID, result.getTarget().getMerchantAccountId());
  }
  @Test
  public void createTransactionFromTransparentRedirect() {
    TransactionRequest request =
        new TransactionRequest()
            .amount(TransactionAmount.AUTHORIZE.amount)
            .creditCard()
            .number(CreditCardNumber.VISA.number)
            .expirationDate("05/2009")
            .done()
            .options()
            .storeInVault(true)
            .done();

    TransactionRequest trParams = new TransactionRequest().type(Transaction.Type.SALE);

    String queryString =
        TestHelper.simulateFormPostForTR(
            gateway, trParams, request, gateway.transparentRedirect().url());
    Result<Transaction> result = gateway.transparentRedirect().confirmTransaction(queryString);
    assertTrue(result.isSuccess());
    assertEquals(
        CreditCardNumber.VISA.number.substring(0, 6), result.getTarget().getCreditCard().getBin());
    assertEquals(TransactionAmount.AUTHORIZE.amount, result.getTarget().getAmount());
  }
  @Test
  public void canVault() {
    Result<Customer> customerResult = gateway.customer().create(new CustomerRequest());
    String customerId = customerResult.getTarget().getId();

    Result<? extends PaymentMethod> paymentMethodResult =
        gateway
            .paymentMethod()
            .create(
                new PaymentMethodRequest()
                    .customerId(customerId)
                    .paymentMethodNonce(Nonce.Coinbase));
    assertTrue(paymentMethodResult.isSuccess());

    CoinbaseAccount account = (CoinbaseAccount) paymentMethodResult.getTarget();
    assertNotNull(account);
    assertNotNull(account.getToken());
    assertNotNull(account.getUserId());
    assertThat(account.getUserId(), not(equalTo("")));
    assertNotNull(account.getUserName());
    assertThat(account.getUserName(), not(equalTo("")));
    assertNotNull(account.getUserEmail());
    assertThat(account.getUserEmail(), not(equalTo("")));
  }
  @Test
  public void updateUpdatesCoinbaseAccount() {
    Result<Customer> customerResult = gateway.customer().create(new CustomerRequest());
    String customerId = customerResult.getTarget().getId();

    PaymentMethodRequest venmoRequest =
        new PaymentMethodRequest().customerId(customerId).paymentMethodNonce(Nonce.VenmoAccount);
    Result<? extends PaymentMethod> venmoResult = gateway.paymentMethod().create(venmoRequest);
    VenmoAccount venmoAccount = (VenmoAccount) venmoResult.getTarget();
    assertTrue(venmoAccount.isDefault());

    PaymentMethodRequest request =
        new PaymentMethodRequest().customerId(customerId).paymentMethodNonce(Nonce.Coinbase);
    Result<? extends PaymentMethod> paymentMethodResult = gateway.paymentMethod().create(request);

    assertTrue(paymentMethodResult.isSuccess());
    String token = paymentMethodResult.getTarget().getToken();

    PaymentMethodRequest updatePaymentMethodRequest =
        new PaymentMethodRequest().options().makeDefault(true).done();

    Result<? extends PaymentMethod> result =
        gateway.paymentMethod().update(token, updatePaymentMethodRequest);

    assertTrue(result.isSuccess());
    assertTrue(result.getTarget() instanceof CoinbaseAccount);
    CoinbaseAccount coinbaseAccount = (CoinbaseAccount) result.getTarget();
    assertTrue(coinbaseAccount.isDefault());
  }