@Override public void success(PaymentMethodNonce paymentMethodNonce) { performVerification(fragment, paymentMethodNonce.getNonce(), amount); }
@Test(timeout = 5000) public void onActivityResult_doesNothingWhenResultCodeNotOk() { Intent intent = mock(Intent.class); ThreeDSecure.onActivityResult(mock(BraintreeFragment.class), Activity.RESULT_CANCELED, intent); verifyZeroInteractions(intent); } }
/** * Verification is associated with a transaction amount and your merchant account. To specify a * different merchant account (or, in turn, currency), you will need to specify the merchant * account id when <a href="https://developers.braintreepayments.com/android/sdk/overview/generate-client-token"> * generating a client token</a> * * During lookup the original payment method nonce is consumed and a new one is returned, * which points to the original payment method, as well as the 3D Secure verification. * Transactions created with this nonce will be 3D Secure, and benefit from the appropriate * liability shift if authentication is successful or fail with a 3D Secure failure. * * @param fragment the {@link BraintreeFragment} backing the http request. This fragment will * also be responsible for handling callbacks to it's listeners * @param nonce The nonce that represents a card to perform a 3D Secure verification against. * @param amount The amount of the transaction in the current merchant account's currency. */ public static void performVerification(final BraintreeFragment fragment, final String nonce, final String amount) { ThreeDSecureRequest request = new ThreeDSecureRequest() .nonce(nonce) .amount(amount); performVerification(fragment, request); }
@Test(timeout = 1000) public void onActivityResult_postsPaymentMethodNonceToListener_fromUri() throws InterruptedException { BraintreeFragment fragment = getFragmentWithAuthorization(mActivity, new TestClientTokenBuilder().withThreeDSecure().build()); fragment.addListener(new PaymentMethodNonceCreatedListener() { @Override public void onPaymentMethodNonceCreated(PaymentMethodNonce paymentMethodNonce) { assertIsANonce(paymentMethodNonce.getNonce()); assertEquals("11", ((CardNonce) paymentMethodNonce).getLastTwo()); assertTrue(((CardNonce) paymentMethodNonce).getThreeDSecureInfo().wasVerified()); mCountDownLatch.countDown(); } }); Uri responseUri = Uri.parse("http://demo-app.com") .buildUpon() .appendQueryParameter("auth_response", stringFromFixture("three_d_secure/authentication_response.json")) .build(); Intent data = new Intent() .setData(responseUri); ThreeDSecure.onActivityResult(fragment, Activity.RESULT_OK, data); mCountDownLatch.await(); }
@Override public void onPaymentMethodNonceCreated(PaymentMethodNonce paymentMethodNonce) { super.onPaymentMethodNonceCreated(paymentMethodNonce); if (!mThreeDSecureRequested && paymentMethodNonce instanceof CardNonce && Settings.isThreeDSecureEnabled(this)) { mThreeDSecureRequested = true; mLoading = ProgressDialog.show(this, getString(R.string.loading), getString(R.string.loading), true, false); ThreeDSecure.performVerification(mBraintreeFragment, paymentMethodNonce.getNonce(), "1"); } else if (paymentMethodNonce instanceof CardNonce && Settings.isAmexRewardsBalanceEnabled(this)) { mLoading = ProgressDialog.show(this, getString(R.string.loading), getString(R.string.loading), true, false); AmericanExpress.getRewardsBalance(mBraintreeFragment, paymentMethodNonce.getNonce(), "USD"); } else { Intent intent = new Intent() .putExtra(MainActivity.EXTRA_PAYMENT_RESULT, paymentMethodNonce) .putExtra(MainActivity.EXTRA_DEVICE_DATA, mDeviceData); setResult(RESULT_OK, intent); finish(); } }
@Test public void onActivityResult_handlesThreeDSecureResult() throws InvalidArgumentException { BraintreeFragment fragment = BraintreeFragment.newInstance(mActivity, TOKENIZATION_KEY); mockStatic(ThreeDSecure.class); Intent intent = new Intent(); fragment.onActivityResult(BraintreeRequestCodes.THREE_D_SECURE, Activity.RESULT_OK, intent); verifyStatic(); ThreeDSecure.onActivityResult(fragment, Activity.RESULT_OK, intent); }
@Test public void performVerification_sendsMinimumParamatersInLookupRequest() throws InterruptedException, JSONException { ThreeDSecureRequest request = new ThreeDSecureRequest() .nonce("a-nonce") .amount("1.00"); ThreeDSecure.performVerification(mFragment, request); ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class); verify(mFragment.getHttpClient()).post(anyString(), captor.capture(), any(HttpResponseCallback.class)); JSONObject body = new JSONObject(captor.getValue()); assertEquals("1.00", body.getString("amount")); JSONObject customer = body.getJSONObject("customer"); assertTrue(customer.isNull("mobilePhoneNumber")); assertTrue(customer.isNull("email")); assertTrue(customer.isNull("shippingMethod")); assertTrue(customer.isNull("billingAddress")); }
@Test(timeout = 2000) public void onActivityResult_postsPaymentMethodNonceToListener() throws JSONException, InterruptedException { BraintreeFragment fragment = getFragmentWithAuthorization(mActivity, new TestClientTokenBuilder().withThreeDSecure().build()); fragment.addListener(new PaymentMethodNonceCreatedListener() { @Override public void onPaymentMethodNonceCreated(PaymentMethodNonce paymentMethodNonce) { assertIsANonce(paymentMethodNonce.getNonce()); assertEquals("11", ((CardNonce) paymentMethodNonce).getLastTwo()); assertTrue(((CardNonce) paymentMethodNonce).getThreeDSecureInfo().wasVerified()); mCountDownLatch.countDown(); } }); JSONObject authResponse = new JSONObject( stringFromFixture("three_d_secure/authentication_response.json")); Intent data = new Intent() .putExtra(ThreeDSecureWebViewActivity.EXTRA_THREE_D_SECURE_RESULT, ThreeDSecureAuthenticationResponse.fromJson(authResponse.toString())); ThreeDSecure.onActivityResult(fragment, Activity.RESULT_OK, data); mCountDownLatch.await(); }
.phoneNumber("12345678")); ThreeDSecure.performVerification(mFragment, request);
@Test(timeout = 2000) public void onActivityResult_postsUnrecoverableErrorsToListeners() throws InterruptedException { BraintreeFragment fragment = getFragmentWithAuthorization(mActivity, new TestClientTokenBuilder().withThreeDSecure().build()); fragment.addListener(new BraintreeErrorListener() { @Override public void onError(Exception error) { assertEquals("Error!", error.getMessage()); mCountDownLatch.countDown(); } }); ThreeDSecureAuthenticationResponse authResponse = ThreeDSecureAuthenticationResponse.fromException("Error!"); Intent data = new Intent() .putExtra(ThreeDSecureWebViewActivity.EXTRA_THREE_D_SECURE_RESULT, authResponse); ThreeDSecure.onActivityResult(fragment, Activity.RESULT_OK, data); mCountDownLatch.await(); }
.countryCodeAlpha2("US")); ThreeDSecure.performVerification(mFragment, request);
@Test(timeout = 2000) public void onActivityResult_postsRecoverableErrorsToListener() throws InterruptedException { BraintreeFragment fragment = getFragmentWithAuthorization(mActivity, new TestClientTokenBuilder().withThreeDSecure().build()); fragment.addListener(new BraintreeErrorListener() { @Override public void onError(Exception error) { assertEquals("Failed to authenticate, please try a different form of payment", error.getMessage()); mCountDownLatch.countDown(); } }); Intent data = new Intent() .putExtra(ThreeDSecureWebViewActivity.EXTRA_THREE_D_SECURE_RESULT, ThreeDSecureAuthenticationResponse.fromJson( stringFromFixture("errors/three_d_secure_error.json"))); ThreeDSecure.onActivityResult(fragment, Activity.RESULT_OK, data); mCountDownLatch.await(); }
@Test(timeout = 30000) public void performVerification_doesALookupAndReturnsACardAfterATimeout() throws InterruptedException { BraintreeFragment fragment = getFragment(); fragment.addListener(new PaymentMethodNonceCreatedListener() { @Override public void onPaymentMethodNonceCreated(PaymentMethodNonce paymentMethodNonce) { assertIsANonce(paymentMethodNonce.getNonce()); CardNonce cardNonce = (CardNonce) paymentMethodNonce; assertEquals("44", cardNonce.getLastTwo()); assertFalse(cardNonce.getThreeDSecureInfo().isLiabilityShifted()); assertFalse(cardNonce.getThreeDSecureInfo().isLiabilityShiftPossible()); assertTrue(((CardNonce) paymentMethodNonce).getThreeDSecureInfo().wasVerified()); mCountDownLatch.countDown(); } }); CardBuilder cardBuilder = new CardBuilder() .cardNumber(THREE_D_SECURE_LOOKUP_TIMEOUT) .expirationDate("12/20"); ThreeDSecure.performVerification(fragment, cardBuilder, TEST_AMOUNT); mCountDownLatch.await(); }
break; case BraintreeRequestCodes.THREE_D_SECURE: ThreeDSecure.onActivityResult(this, resultCode, data); break; case BraintreeRequestCodes.VENMO:
@Test(timeout = 10000) public void performVerification_doesALookupAndReturnsACardWhenThereIsAMPILookupError() throws InterruptedException { BraintreeFragment fragment = getFragment(); fragment.addListener(new PaymentMethodNonceCreatedListener() { @Override public void onPaymentMethodNonceCreated(PaymentMethodNonce paymentMethodNonce) { assertIsANonce(paymentMethodNonce.getNonce()); CardNonce cardNonce = (CardNonce) paymentMethodNonce; assertEquals("85", cardNonce.getLastTwo()); assertFalse(cardNonce.getThreeDSecureInfo().isLiabilityShifted()); assertFalse(cardNonce.getThreeDSecureInfo().isLiabilityShiftPossible()); assertTrue(((CardNonce) paymentMethodNonce).getThreeDSecureInfo().wasVerified()); mCountDownLatch.countDown(); } }); CardBuilder cardBuilder = new CardBuilder() .cardNumber(THREE_D_SECURE_MPI_LOOKUP_ERROR) .expirationDate("12/20"); ThreeDSecure.performVerification(fragment, cardBuilder, TEST_AMOUNT); mCountDownLatch.await(); }
@Test(timeout = 10000) public void performVerification_doesALookupAndReturnsACardAndANullACSUrlWhenAuthenticationIsNotRequired() throws InterruptedException { BraintreeFragment fragment = getFragment(); fragment.addListener(new PaymentMethodNonceCreatedListener() { @Override public void onPaymentMethodNonceCreated(PaymentMethodNonce paymentMethodNonce) { assertIsANonce(paymentMethodNonce.getNonce()); CardNonce cardNonce = (CardNonce) paymentMethodNonce; assertEquals("51", cardNonce.getLastTwo()); assertFalse(cardNonce.getThreeDSecureInfo().isLiabilityShifted()); assertFalse(cardNonce.getThreeDSecureInfo().isLiabilityShiftPossible()); assertTrue(((CardNonce) paymentMethodNonce).getThreeDSecureInfo().wasVerified()); mCountDownLatch.countDown(); } }); CardBuilder cardBuilder = new CardBuilder() .cardNumber(THREE_D_SECURE_VERIFICATON_NOT_REQUIRED) .expirationDate("12/20"); ThreeDSecure.performVerification(fragment, cardBuilder, TEST_AMOUNT); mCountDownLatch.await(); }
@Test(timeout = 30000) public void performVerification_returnsASuccessfulAuthenticationWhenIssuerDoesNotParticipate() throws InterruptedException { BraintreeFragment fragment = getFragment(); fragment.addListener(new PaymentMethodNonceCreatedListener() { @Override public void onPaymentMethodNonceCreated(PaymentMethodNonce paymentMethodNonce) { assertIsANonce(paymentMethodNonce.getNonce()); CardNonce cardNonce = (CardNonce) paymentMethodNonce; assertEquals("01", cardNonce.getLastTwo()); assertTrue(cardNonce.getThreeDSecureInfo().isLiabilityShifted()); assertTrue(cardNonce.getThreeDSecureInfo().isLiabilityShiftPossible()); assertTrue(((CardNonce) paymentMethodNonce).getThreeDSecureInfo().wasVerified()); mCountDownLatch.countDown(); } }); CardBuilder cardBuilder = new CardBuilder() .cardNumber(THREE_D_SECURE_ISSUER_DOES_NOT_PARTICIPATE) .expirationDate("12/30"); ThreeDSecure.performVerification(fragment, cardBuilder, TEST_AMOUNT); mCountDownLatch.await(); }
@Test(timeout = 10000) public void performVerification_doesALookupAndReturnsACardWhenThereIsALookupError() throws InterruptedException { BraintreeFragment fragment = getFragment(); fragment.addListener(new PaymentMethodNonceCreatedListener() { @Override public void onPaymentMethodNonceCreated(PaymentMethodNonce paymentMethodNonce) { assertIsANonce(paymentMethodNonce.getNonce()); CardNonce cardNonce = (CardNonce) paymentMethodNonce; assertEquals("77", cardNonce.getLastTwo()); assertFalse(cardNonce.getThreeDSecureInfo().isLiabilityShifted()); assertFalse(cardNonce.getThreeDSecureInfo().isLiabilityShiftPossible()); assertTrue(((CardNonce) paymentMethodNonce).getThreeDSecureInfo().wasVerified()); mCountDownLatch.countDown(); } }); CardBuilder cardBuilder = new CardBuilder() .cardNumber(THREE_D_SECURE_LOOKUP_ERROR) .expirationDate("12/20"); ThreeDSecure.performVerification(fragment, cardBuilder, TEST_AMOUNT); mCountDownLatch.await(); }
@Test(timeout = 10000) public void performVerification_doesALookupAndReturnsACardWhenAuthenticationIsUnavailable() throws InterruptedException { BraintreeFragment fragment = getFragment(); fragment.addListener(new PaymentMethodNonceCreatedListener() { @Override public void onPaymentMethodNonceCreated(PaymentMethodNonce paymentMethodNonce) { assertIsANonce(paymentMethodNonce.getNonce()); CardNonce cardNonce = (CardNonce) paymentMethodNonce; assertEquals("69", cardNonce.getLastTwo()); assertFalse(cardNonce.getThreeDSecureInfo().isLiabilityShifted()); assertFalse(cardNonce.getThreeDSecureInfo().isLiabilityShiftPossible()); assertTrue(((CardNonce) paymentMethodNonce).getThreeDSecureInfo().wasVerified()); mCountDownLatch.countDown(); } }); CardBuilder cardBuilder = new CardBuilder() .cardNumber(THREE_D_SECURE_AUTHENTICATION_UNAVAILABLE) .expirationDate("12/20"); ThreeDSecure.performVerification(fragment, cardBuilder, TEST_AMOUNT); mCountDownLatch.await(); }
@Test(timeout = 1000) public void performVerification_withInvalidThreeDSecureRequest_postsException() throws InterruptedException, InvalidArgumentException { String clientToken = new TestClientTokenBuilder().withThreeDSecure().build(); BraintreeFragment fragment = getFragmentWithAuthorization(mActivity, clientToken); fragment.addListener(new BraintreeErrorListener() { @Override public void onError(Exception error) { assertEquals("The ThreeDSecureRequest nonce and amount cannot be null", error.getMessage()); mCountDownLatch.countDown(); } }); ThreeDSecureRequest request = new ThreeDSecureRequest() .amount("5"); ThreeDSecure.performVerification(fragment, request); mCountDownLatch.await(); }