Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG]: us_bank_account payment method does not work in webview #463

Closed
sir-captainmorgan21 opened this issue Jun 27, 2023 · 9 comments
Closed
Labels
bug Something isn't working stale

Comments

@sir-captainmorgan21
Copy link

What happened?

We are trying to accept ACH as a payment method for future payments. We are using setup intents to get this done. The app is a React app. The payment flow (or bank detail collection flow), works perfectly fine in the browser. However, when in a webview, it does not. When the user finishes authenticating with their bank, they are stuck in the browser and are not being brought back to the app.

I have been through the ringer with support with no help. I did notice that in the docs for iOS, the collectBankAccountForSetup method accepts a return url to bring the user back to the native app. However, the stripe-js version of collectBankAccountForSetup does not. I think this is what is missing for this to work.

I did quite a bit of debugging, and found that after authenticating, stripe ultamitely lands on this url: https://connections-auth.stripe.com/testmode/complete?state=bcsess_1NLWY1HmbQZtVN0XzHFxkziy&code=success
In the webview experience this tab just closes right away (which makes sense based on the logic which is pasted below)

  var isPollingOnly = document.getElementById('is_polling_only').getAttribute('data-message') === "true";

    if (isPollingOnly || !window.opener) {
      window.close();
    } else {
      var authSessionId = document.getElementById('auth_session_token').getAttribute('data-message');
      var oauthStatusCode = document.getElementById('oauth_status_code').getAttribute('data-message');
      var oauthError = document.getElementById('oauth_error').getAttribute('data-message');

      var isAbstractAuth = document.getElementById('is_abstract_auth').getAttribute('data-message') === 'true';
      if (isAbstractAuth) {
        // If additional information is added here, ensure that it is safe to send to * origin.
        window.opener.postMessage({
          partnerStatusParams: document.getElementById('status').getAttribute('data-message')
        }, "*");
      } else {
        var response = {type: 'oauth-completed', authSessionId: authSessionId, code: oauthStatusCode, error: oauthError};
        if (!authSessionId) {
          response.error = "No authSessionId provided in redirect";
        }

        var originList = document.getElementById('post_message_origins').getAttribute('data-message').split(',');
        for (var i = 0; i < originList.length; i++) {
          window.opener.postMessage(response, originList[i]);
        }

        window.close();
      }
    }

This script looks like it assumes the whole flow is happening in browser (which is fair because it is a JS library we are using), however, webviews are very common (especially with ionic being popular). I think allowing for a return url would be a nice addition to the library. I have included some links to videos of both the browser and webview flows to give you an idea. It is not at the confirm stage like support keeps suggesting.

WEB BROWSER: https://www.loom.com/share/a10fb94e9c684432a73c20b790ad73a8?sid=3826cdfb-c8ef-4d46-b763-ec639252802d

NATIVE WEBVIEW: https://www.loom.com/share/594108eb69d242dc9e3fadd9ffe8bd0a?sid=350c7cbf-9bf8-4a0c-bf4b-2d8d6ac4c952

Environment

N/A

Reproduction

No response

@sir-captainmorgan21 sir-captainmorgan21 added the bug Something isn't working label Jun 27, 2023
@brendanm-stripe
Copy link
Contributor

hey there @sir-captainmorgan21 I want to make sure I understand more about this before filing a feature request like you describe, so a few questions:

  1. Can you share the details of your integration, ie exactly how you're using Stripe.js?
  2. Do you get the successful result and setupIntent object returned when the setup succeeds ? ( See "Returns" here https://stripe.com/docs/js/setup_intents/confirm_us_bank_account_setup )
  3. Are you able to test and share the behaviour observed for the same flow on Android?

@sir-captainmorgan21
Copy link
Author

@brendanm-stripe

  1. it may be tough to share, since the repo is private, but the support rep asked for the code as well, so I am going to work on creating a minimal reproduction today. I can say that we are using react-stripe-js and we are using the PaymentElements provided. Ill provide a summary of what we do. Maybe it helps prior to me getting a full reproduction for you
    a. We create a setup intent, providing the customerid and paymentmethod of us_bank_account
    b. We take the clientsecret and hand it off to Elements from @stripe/react-stripe-js'
    c. We pass PaymentElement from @stripe/react-stripe-js' as children to Elements
    d. And thats basically it. From there the elements ui is presented by stripe-js with the OAuth bank account you can select, where it ultimately breaks.
  2. Im not sure when confirmUsBankAccountSetup is supposed to be called, but we dont call that anywhere directly in our code (maybe its called from stripe-js somewhere in the Elements? But like I said it is breaking before we can even get to the point where we would confirm the setup. Were you able to watch the videos I provided?
  3. I have not tested in android, no. I can get that info as well.

@sir-captainmorgan21
Copy link
Author

@brendanm-stripe I really encourage you watch those videos, and itll layout where it fails. I think that is important to rule out the confirm step

@brendanm-stripe
Copy link
Contributor

Yep I watched them (thanks for recording!) but apologies for misunderstanding slightly the step of the failure on collect vs confirm. I'm going to try to repro myself but it might take some time.

In the videos I noticed you used the OAuth test bank. Is that required for the issue to happen, or does it happen with the first test bank too?

@sir-captainmorgan21
Copy link
Author

@brendanm-stripe
OAuth is required for the issue to happen. The root issue is specifically OAuth, when a user is taken away from the native app to a web browser. I have created a repro, and will get the link here soon.

@sir-captainmorgan21
Copy link
Author

@brendanm-stripe here is the repro: https://github.com/sir-captainmorgan21/stripe-ach-webview-repro

NOTE: I did not do anything past just authenticating with a bank and select accounts, since the bug prevents you from getting past that point anyway.

@brendanm-stripe
Copy link
Contributor

Just wanted to update here that I have been able to repro/confirm the behaviour described here and we're looking at options. Currently, I'd say that this flow is not fully supported and that you'd need to use either the mobile SDKs (with a bridge for ionic) or open in a native browser.

It also looks like you've written in to get support on this so we'll continue to work with you there on potential workaround or solutions.

@sir-captainmorgan21
Copy link
Author

@brendanm-stripe ok sounds good. I thought about contributing to the stripe capacitor plugin to add ACH support. The iOS package API does have an option for a return url for the collectBankAccountForSetup, so I'd imagine the backend API must support it. I'm wondering if stripe JS just needs to surface a return URL for the same function as well?

@stale
Copy link

stale bot commented Jul 22, 2023

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Jul 22, 2023
@stale stale bot closed this as completed Jul 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working stale
Projects
None yet
Development

No branches or pull requests

2 participants