private static void launchBrowserSwitch(BraintreeFragment fragment, ThreeDSecureLookup threeDSecureLookup) { String assetsBaseUrl = fragment.getConfiguration().getAssetsUrl() + THREE_D_SECURE_ASSETS_PATH; String returnUrl = String.format("%s/redirect.html?redirect_url=%s://x-callback-url/braintree/threedsecure?", assetsBaseUrl, fragment.getReturnUrlScheme()); Uri redirectUri = Uri.parse(assetsBaseUrl + "/index.html") .buildUpon() .appendQueryParameter("AcsUrl", threeDSecureLookup.getAcsUrl()) .appendQueryParameter("PaReq", threeDSecureLookup.getPareq()) .appendQueryParameter("MD", threeDSecureLookup.getMd()) .appendQueryParameter("TermUrl", threeDSecureLookup.getTermUrl()) .appendQueryParameter("ReturnUrl", returnUrl) .build(); fragment.browserSwitch(BraintreeRequestCodes.THREE_D_SECURE, redirectUri.toString()); } }
/** * Initiates the browser switch for a payment flow by opening a browser where the customer can authenticate with their bank. * * @param fragment {@link BraintreeFragment} * @param request {@link LocalPaymentRequest} which has already been sent to {@link #startPayment(BraintreeFragment, LocalPaymentRequest, BraintreeResponseListener)} * and now has an approvalUrl and paymentId. */ public static void approvePayment(BraintreeFragment fragment, LocalPaymentRequest request) { fragment.browserSwitch(BraintreeRequestCodes.LOCAL_PAYMENT, request.getApprovalUrl()); fragment.sendAnalyticsEvent(paymentTypeForAnalytics() + ".local-payment.webswitch.initiate.succeeded"); }
@Test public void authorizeAccount_startsBrowser() { BraintreeFragment fragment = mMockFragmentBuilder.build(); PayPal.authorizeAccount(fragment); ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); verify(fragment).browserSwitch(eq(BraintreeRequestCodes.PAYPAL), captor.capture()); Intent intent = captor.getValue(); assertEquals(Intent.ACTION_VIEW, intent.getAction()); assertEquals("checkout.paypal.com", intent.getData().getHost()); assertEquals("/one-touch-login/", intent.getData().getPath()); assertNotNull(intent.getData().getQueryParameter("payload")); assertNotNull(intent.getData().getQueryParameter("payloadEnc")); assertEquals("com.braintreepayments.api.braintree://onetouch/v1/success", intent.getData().getQueryParameter("x-success")); assertEquals("com.braintreepayments.api.braintree://onetouch/v1/cancel", intent.getData().getQueryParameter("x-cancel")); }
@Test public void requestOneTimePayment_userAction_canBeSetToCommit() { BraintreeFragment fragment = mMockFragmentBuilder .successResponse(stringFromFixture("paypal_hermes_response.json")) .build(); PayPal.requestOneTimePayment(fragment, new PayPalRequest("1").userAction(PayPalRequest.USER_ACTION_COMMIT)); ArgumentCaptor<Intent> dataCaptor = ArgumentCaptor.forClass(Intent.class); verify(fragment).browserSwitch(eq(BraintreeRequestCodes.PAYPAL), dataCaptor.capture()); Uri uri = dataCaptor.getValue().getData(); assertEquals("commit", uri.getQueryParameter("useraction")); }
@Test public void requestOneTimePayment_userAction_setsUserActionToBlankStringonDefault() throws JSONException { BraintreeFragment fragment = mMockFragmentBuilder .successResponse(stringFromFixture("paypal_hermes_response.json")) .build(); PayPal.requestOneTimePayment(fragment, new PayPalRequest("1").userAction(PayPalRequest.USER_ACTION_DEFAULT)); ArgumentCaptor<Intent> dataCaptor = ArgumentCaptor.forClass(Intent.class); verify(fragment).browserSwitch(eq(BraintreeRequestCodes.PAYPAL), dataCaptor.capture()); Uri uri = dataCaptor.getValue().getData(); assertEquals("", uri.getQueryParameter("useraction")); }
@Test public void requestBillingAgreement_startsBrowser() throws InvalidArgumentException { BraintreeFragment fragment = mMockFragmentBuilder .successResponse(stringFromFixture("paypal_hermes_billing_agreement_response.json")) .build(); PayPal.requestBillingAgreement(fragment, new PayPalRequest()); ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); verify(fragment).browserSwitch(eq(BraintreeRequestCodes.PAYPAL), captor.capture()); Intent intent = captor.getValue(); assertEquals(Intent.ACTION_VIEW, intent.getAction()); assertEquals("checkout.paypal.com", intent.getData().getHost()); assertEquals("/one-touch-login-sandbox/index.html", intent.getData().getPath()); assertEquals("create_payment_resource", intent.getData().getQueryParameter("action")); assertEquals("63cc461306c35080ce674a3372bffe1580b4130c7fd33d33968aa76bb93cdd06|created_at=2015-10-13T18:49:48.371382792+0000&merchant_id=dcpspy2brwdjr3qn&public_key=9wwrzqk3vr3t4nc8", intent.getData().getQueryParameter("authorization_fingerprint")); assertFalse(intent.getData().getQueryParameterNames().contains("amount")); assertFalse(intent.getData().getQueryParameterNames().contains("currency_iso_code")); assertEquals("false", intent.getData().getQueryParameter("experience_profile[address_override]")); assertEquals("false", intent.getData().getQueryParameter("experience_profile[no_shipping]")); assertEquals("dcpspy2brwdjr3qn", intent.getData().getQueryParameter("merchant_id")); assertEquals("com.braintreepayments.api.test.braintree://onetouch/v1/success", intent.getData().getQueryParameter("return_url")); assertEquals("com.braintreepayments.api.test.braintree://onetouch/v1/cancel", intent.getData().getQueryParameter("cancel_url")); }
@Override public void onResponse(List<IdealBank> idealBanks) { IdealBank bank = idealBanks.get(0); IdealRequest builder = new IdealRequest() .issuerId(bank.getId()) .amount("1.00") .currency("EUR") .orderId("abc-123"); Ideal.startPayment(mBraintreeFragment, builder, null); verify(mBraintreeFragment).browserSwitch(eq(BraintreeRequestCodes.IDEAL), eq("http://approval.example.com/")); latch.countDown(); } });
@Test public void requestOneTimePayment_startsBrowser() { BraintreeFragment fragment = mMockFragmentBuilder .successResponse(stringFromFixture("paypal_hermes_response.json")) .build(); PayPal.requestOneTimePayment(fragment, new PayPalRequest("1.00")); ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); verify(fragment).browserSwitch(eq(BraintreeRequestCodes.PAYPAL), captor.capture()); Intent intent = captor.getValue(); assertEquals(Intent.ACTION_VIEW, intent.getAction()); assertEquals("checkout.paypal.com", intent.getData().getHost()); assertEquals("/one-touch-login-sandbox/index.html", intent.getData().getPath()); assertEquals("create_payment_resource", intent.getData().getQueryParameter("action")); assertEquals("63cc461306c35080ce674a3372bffe1580b4130c7fd33d33968aa76bb93cdd06|created_at=2015-10-13T18:49:48.371382792+0000&merchant_id=dcpspy2brwdjr3qn&public_key=9wwrzqk3vr3t4nc8", intent.getData().getQueryParameter("authorization_fingerprint")); assertEquals("USD", intent.getData().getQueryParameter("currency_iso_code")); assertEquals("false", intent.getData().getQueryParameter("experience_profile[address_override]")); assertEquals("false", intent.getData().getQueryParameter("experience_profile[no_shipping]")); assertEquals("dcpspy2brwdjr3qn", intent.getData().getQueryParameter("merchant_id")); assertEquals("com.braintreepayments.api.test.braintree://onetouch/v1/success", intent.getData().getQueryParameter("return_url")); assertEquals("com.braintreepayments.api.test.braintree://onetouch/v1/cancel", intent.getData().getQueryParameter("cancel_url")); }
@Test public void authorizeAccount_callsCancelListenerWhenCanceled() { final BraintreeFragment fragment = mMockFragmentBuilder.build(); doAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { Intent intent = new Intent() .setData(Uri.parse("com.braintreepayments.api.test.braintree://onetouch/v1/cancel")); PayPal.onActivityResult(fragment, Activity.RESULT_OK, intent); return null; } }).when(fragment).browserSwitch(eq(BraintreeRequestCodes.PAYPAL), any(Intent.class)); PayPal.authorizeAccount(fragment); verify(fragment).postCancelCallback(BraintreeRequestCodes.PAYPAL); }
@Test public void requestBillingAgreement_startsBrowserWithPayPalCredit() { BraintreeFragment fragment = mMockFragmentBuilder .successResponse(stringFromFixture("paypal_hermes_billing_agreement_response.json")) .build(); PayPal.requestBillingAgreement(fragment, new PayPalRequest().offerCredit(true)); ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); verify(fragment).browserSwitch(eq(BraintreeRequestCodes.PAYPAL), captor.capture()); Intent intent = captor.getValue(); assertEquals(Intent.ACTION_VIEW, intent.getAction()); assertEquals("checkout.paypal.com", intent.getData().getHost()); assertEquals("/one-touch-login-sandbox/index.html", intent.getData().getPath()); assertEquals("create_payment_resource", intent.getData().getQueryParameter("action")); assertEquals("63cc461306c35080ce674a3372bffe1580b4130c7fd33d33968aa76bb93cdd06|created_at=2015-10-13T18:49:48.371382792+0000&merchant_id=dcpspy2brwdjr3qn&public_key=9wwrzqk3vr3t4nc8", intent.getData().getQueryParameter("authorization_fingerprint")); assertFalse(intent.getData().getQueryParameterNames().contains("amount")); assertEquals("true", intent.getData().getQueryParameter("offer_paypal_credit")); assertFalse(intent.getData().getQueryParameterNames().contains("currency_iso_code")); assertEquals("false", intent.getData().getQueryParameter("experience_profile[address_override]")); assertEquals("false", intent.getData().getQueryParameter("experience_profile[no_shipping]")); assertEquals("dcpspy2brwdjr3qn", intent.getData().getQueryParameter("merchant_id")); assertEquals("com.braintreepayments.api.test.braintree://onetouch/v1/success", intent.getData().getQueryParameter("return_url")); assertEquals("com.braintreepayments.api.test.braintree://onetouch/v1/cancel", intent.getData().getQueryParameter("cancel_url")); }
@Test public void requestOneTimePayment_startsBrowserWithPayPalCredit() { BraintreeFragment fragment = mMockFragmentBuilder .successResponse(stringFromFixture("paypal_hermes_response.json")) .build(); PayPal.requestOneTimePayment(fragment, new PayPalRequest("1.00").offerCredit(true)); ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); verify(fragment).browserSwitch(eq(BraintreeRequestCodes.PAYPAL), captor.capture()); Intent intent = captor.getValue(); assertEquals(Intent.ACTION_VIEW, intent.getAction()); assertEquals("checkout.paypal.com", intent.getData().getHost()); assertEquals("/one-touch-login-sandbox/index.html", intent.getData().getPath()); assertEquals("create_payment_resource", intent.getData().getQueryParameter("action")); assertEquals("63cc461306c35080ce674a3372bffe1580b4130c7fd33d33968aa76bb93cdd06|created_at=2015-10-13T18:49:48.371382792+0000&merchant_id=dcpspy2brwdjr3qn&public_key=9wwrzqk3vr3t4nc8", intent.getData().getQueryParameter("authorization_fingerprint")); assertEquals("USD", intent.getData().getQueryParameter("currency_iso_code")); assertEquals("true", intent.getData().getQueryParameter("offer_paypal_credit")); assertEquals("false", intent.getData().getQueryParameter("experience_profile[address_override]")); assertEquals("false", intent.getData().getQueryParameter("experience_profile[no_shipping]")); assertEquals("dcpspy2brwdjr3qn", intent.getData().getQueryParameter("merchant_id")); assertEquals("com.braintreepayments.api.test.braintree://onetouch/v1/success", intent.getData().getQueryParameter("return_url")); assertEquals("com.braintreepayments.api.test.braintree://onetouch/v1/cancel", intent.getData().getQueryParameter("cancel_url")); }
@Test public void requestBillingAgreement_cancelUrlTriggersCancelListener() { final BraintreeFragment fragment = mMockFragmentBuilder .successResponse(stringFromFixture("paypal_hermes_response.json")) .build(); doAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { Intent intent = new Intent() .setData(Uri.parse("com.braintreepayments.api.test.braintree://onetouch/v1/cancel")); PayPal.onActivityResult(fragment, Activity.RESULT_OK, intent); return null; } }).when(fragment).browserSwitch(eq(BraintreeRequestCodes.PAYPAL), any(Intent.class)); PayPal.requestBillingAgreement(fragment, new PayPalRequest()); verify(fragment).postCancelCallback(BraintreeRequestCodes.PAYPAL); }
@Override public void handleApproval(Request request, PayPalApprovalCallback paypalApprovalCallback) { PendingRequest pendingRequest = PayPalOneTouchCore.getStartIntent(fragment.getApplicationContext(), request); if (pendingRequest.isSuccess() && pendingRequest.getRequestTarget() == RequestTarget.wallet) { sendAnalyticsForPayPal(fragment, request, true, RequestTarget.wallet); fragment.startActivityForResult(pendingRequest.getIntent(), BraintreeRequestCodes.PAYPAL); } else if (pendingRequest.isSuccess() && pendingRequest.getRequestTarget() == RequestTarget.browser) { sendAnalyticsForPayPal(fragment, request, true, RequestTarget.browser); fragment.browserSwitch(BraintreeRequestCodes.PAYPAL, pendingRequest.getIntent()); } else { sendAnalyticsForPayPal(fragment, request, false, null); } } };
@Test public void requestOneTimePayment_isSuccessful() { final BraintreeFragment fragment = mMockFragmentBuilder .successResponse(stringFromFixture("paypal_hermes_response.json")) .build(); doAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { Intent intent = new Intent() .setData(Uri.parse("com.braintreepayments.api.test.braintree://onetouch/v1/success?PayerID=HERMES-SANDBOX-PAYER-ID&paymentId=HERMES-SANDBOX-PAYMENT-ID&token=EC-HERMES-SANDBOX-EC-TOKEN")); PayPal.onActivityResult(fragment, Activity.RESULT_OK, intent); return null; } }).when(fragment).browserSwitch(eq(BraintreeRequestCodes.PAYPAL), any(Intent.class)); mockStatic(TokenizationClient.class); doAnswer(new Answer<Void>() { @Override public Void answer(InvocationOnMock invocation) throws Throwable { ((PaymentMethodNonceCallback) invocation.getArguments()[2]).success(new PayPalAccountNonce()); return null; } }).when(TokenizationClient.class); TokenizationClient.tokenize(any(BraintreeFragment.class), any(PaymentMethodBuilder.class), any(PaymentMethodNonceCallback.class)); PayPal.requestOneTimePayment(fragment, new PayPalRequest("1")); verify(fragment).postCallback(any(PayPalAccountNonce.class)); SharedPreferences prefs = BraintreeSharedPreferences.getSharedPreferences(RuntimeEnvironment.application); assertNull(prefs.getString("com.braintreepayments.api.PayPal.REQUEST_KEY", null)); assertNull(prefs.getString("com.braintreepayments.api.PayPal.REQUEST_TYPE_KEY", null)); }
@Test public void checkout_cancelUrlTriggersCancelListener() { final BraintreeFragment fragment = mMockFragmentBuilder .successResponse(stringFromFixture("paypal_hermes_response.json")) .build(); doAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { Intent intent = new Intent() .setData(Uri.parse("com.braintreepayments.api.test.braintree://onetouch/v1/cancel")); PayPal.onActivityResult(fragment, Activity.RESULT_OK, intent); return null; } }).when(fragment).browserSwitch(eq(BraintreeRequestCodes.PAYPAL), any(Intent.class)); PayPal.requestOneTimePayment(fragment, new PayPalRequest("1")); verify(fragment).postCancelCallback(BraintreeRequestCodes.PAYPAL); }
@Test public void requestBillingAgreement_isSuccessful() { final BraintreeFragment fragment = mMockFragmentBuilder .successResponse(stringFromFixture("paypal_hermes_billing_agreement_response.json")) .build(); doAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { Intent intent = new Intent() .setData(Uri.parse("com.braintreepayments.api.test.braintree://onetouch/v1/success?PayerID=HERMES-SANDBOX-PAYER-ID&paymentId=HERMES-SANDBOX-PAYMENT-ID&ba_token=EC-HERMES-SANDBOX-EC-TOKEN")); PayPal.onActivityResult(fragment, Activity.RESULT_OK, intent); return null; } }).when(fragment).browserSwitch(eq(BraintreeRequestCodes.PAYPAL), any(Intent.class)); mockStatic(TokenizationClient.class); doAnswer(new Answer<Void>() { @Override public Void answer(InvocationOnMock invocation) throws Throwable { ((PaymentMethodNonceCallback) invocation.getArguments()[2]).success(new PayPalAccountNonce()); return null; } }).when(TokenizationClient.class); TokenizationClient.tokenize(any(BraintreeFragment.class), any(PaymentMethodBuilder.class), any(PaymentMethodNonceCallback.class)); PayPal.requestBillingAgreement(fragment, new PayPalRequest()); verify(fragment).postCallback(any(PayPalAccountNonce.class)); }
return null; }).when(fragment).browserSwitch(eq(BraintreeRequestCodes.PAYPAL), any(Intent.class));
@Test public void requestBillingAgreement_whenSuccessful_sendsAnalyticsEvents() { final BraintreeFragment fragment = mMockFragmentBuilder .successResponse(stringFromFixture("paypal_hermes_billing_agreement_response.json")) .build(); doAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { Intent intent = new Intent() .setData(Uri.parse("com.braintreepayments.api.test.braintree://onetouch/v1/success?PayerID=HERMES-SANDBOX-PAYER-ID&paymentId=HERMES-SANDBOX-PAYMENT-ID&ba_token=EC-HERMES-SANDBOX-EC-TOKEN")); PayPal.onActivityResult(fragment, Activity.RESULT_OK, intent); return null; } }).when(fragment).browserSwitch(eq(BraintreeRequestCodes.PAYPAL), any(Intent.class)); mockStatic(TokenizationClient.class); doAnswer(new Answer<Void>() { @Override public Void answer(InvocationOnMock invocation) throws Throwable { ((PaymentMethodNonceCallback) invocation.getArguments()[2]).success(new PayPalAccountNonce()); return null; } }).when(TokenizationClient.class); TokenizationClient.tokenize(any(BraintreeFragment.class), any(PaymentMethodBuilder.class), any(PaymentMethodNonceCallback.class)); PayPal.requestBillingAgreement(fragment, new PayPalRequest()); verify(fragment).sendAnalyticsEvent("paypal.billing-agreement.selected"); verify(fragment).sendAnalyticsEvent("paypal-billing-agreement.webswitch.started"); verify(fragment).sendAnalyticsEvent("paypal-billing-agreement.webswitch.succeeded"); }
@Test public void requestOneTimePayment_whenSuccessful_sendsAnalyticsEvents() { final BraintreeFragment fragment = mMockFragmentBuilder .successResponse(stringFromFixture("paypal_hermes_response.json")) .build(); doAnswer(new Answer() { @Override public Object answer(InvocationOnMock invocation) throws Throwable { Intent intent = new Intent() .setData(Uri.parse("com.braintreepayments.api.test.braintree://onetouch/v1/success?PayerID=HERMES-SANDBOX-PAYER-ID&paymentId=HERMES-SANDBOX-PAYMENT-ID&token=EC-HERMES-SANDBOX-EC-TOKEN")); PayPal.onActivityResult(fragment, Activity.RESULT_OK, intent); return null; } }).when(fragment).browserSwitch(eq(BraintreeRequestCodes.PAYPAL), any(Intent.class)); mockStatic(TokenizationClient.class); doAnswer(new Answer<Void>() { @Override public Void answer(InvocationOnMock invocation) throws Throwable { ((PaymentMethodNonceCallback) invocation.getArguments()[2]).success(new PayPalAccountNonce()); return null; } }).when(TokenizationClient.class); TokenizationClient.tokenize(any(BraintreeFragment.class), any(PaymentMethodBuilder.class), any(PaymentMethodNonceCallback.class)); PayPal.requestOneTimePayment(fragment, new PayPalRequest("1")); verify(fragment).sendAnalyticsEvent("paypal.one-time-payment.selected"); verify(fragment).sendAnalyticsEvent("paypal-single-payment.webswitch.started"); verify(fragment).sendAnalyticsEvent("paypal-single-payment.webswitch.succeeded"); }
return null; }).when(fragment).browserSwitch(eq(BraintreeRequestCodes.PAYPAL), any(Intent.class));