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

Add Personal Bank Account via Plaid flow #2746

Merged
merged 13 commits into from
May 17, 2021
Merged

Add Personal Bank Account via Plaid flow #2746

merged 13 commits into from
May 17, 2021

Conversation

marcaaron
Copy link
Contributor

@marcaaron marcaaron commented May 7, 2021

Details

This issue is sort of holding on https://github.com/Expensify/Expensify/issues/163233 where we'll add the Android app package name to the Plaid dashboard. I don't have the access level to do this so until that is done Android cannot be tested on production - but should be testable on dev and staging which are both using the sandbox. This is done now so we can test on release builds.

Fixed Issues

Fixes https://github.com/Expensify/Expensify/issues/161736
Fixes https://github.com/Expensify/Expensify/issues/149395

Notes on testing this on native platforms

This flow is only accessible via deep link at the moment so we'll need to follow instructions here

If you are using ngrok on iOS simulator make sure you also have certs on your simulator device. I wasted some time trying to figure out why iOS couldn't call secure.

Notes on testing on Android

In order to access local web-secure on Android it's necessary to create a separate endpoint for web-secure. I created a whole new one by following instructions here but a temporary one should work too.

After setting up a new "secure" ngrok url to use I ran this and everything worked fine.

ngrok http -hostname=secure-expensify-marc.ngrok.io --host-header rewrite secure.expensify.com.dev:443

Tests

  1. Navigate to /add-bank-account
  2. Enter "Chase" for the bank
  3. Enter the test credentials user_good/pass_good
  4. Select "Plaid Checking"
  5. Enter Password
  6. Tap Continue
  7. Verify that the alert pops up and says the account has been added
  8. Verify in expensify.com.dev that the account has been added

QA Steps (Internal)

QA is largely the same for staging. Making it internal because it may be tricky to get the deep links to work.
I can also do the QA for this (or help out) if whoever is assigned asks.

Tested On

  • Web
  • Mobile Web
  • Desktop / Not Accessible via Desktop
  • iOS
  • Android

Screenshots

Web

2021-05-10_13-29-33

2021-05-10_13-29-37

2021-05-10_13-29-52

2021-05-10_13-30-01

2021-05-10_13-30-10

2021-05-10_13-38-22

2021-05-10_13-38-45

2021-05-10_13-39-45

2021-05-10_13-39-50

2021-05-10_13-43-07

2021-05-10_13-43-14

2021-05-10_13-45-41

Mobile Web

2021-05-10_13-47-59

2021-05-10_13-48-05

2021-05-10_13-48-10

2021-05-10_13-48-18

2021-05-10_13-48-23

2021-05-10_13-48-33

2021-05-10_13-48-42

2021-05-10_13-48-50

Desktop

N/A

iOS

2021-05-10_14-01-34

2021-05-10_14-01-50

2021-05-10_14-01-56

2021-05-10_14-02-04

2021-05-10_14-02-12

2021-05-10_14-02-20

Android

2021-05-10_14-12-04

2021-05-10_14-12-20

2021-05-10_14-12-28

2021-05-10_14-12-46

2021-05-10_14-12-54

@marcaaron marcaaron self-assigned this May 7, 2021
@@ -10,7 +10,7 @@
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems necessary after adding the Plaid SDK there's some more information here about this:

https://medium.com/google-developers/faster-android-studio-builds-with-dex-in-process-5988ed8aa37e

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TL;DR is that without this enabled the android app wouldn't build at all.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What version of the JDK do we target? MaxPermSize was removed in JDK 8 so that param might not do anything

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JDK 8 I believe, I don't know much about Java though I just uncommented this line out based on the advice in that blog post.

add the add bank account page

Add PlaidLink on web and ability to add bank account

add react plaid link library

derp

revert plist changes

Add Android configs

Add secure NGROK option

add note about dependency

add secure ngrok option

temp disable flipper

add nativeModules files

Fix up propTypes

Use React.Fragment

add translation stuff

add comments

add doc
@marcaaron marcaaron changed the title [WIP] Add Personal Bank Account flow [HOLD] Add Personal Bank Account flow May 10, 2021
@marcaaron marcaaron changed the title [HOLD] Add Personal Bank Account flow [HOLD] Add Personal Bank Account via Plaid flow May 11, 2021
@marcaaron marcaaron marked this pull request as ready for review May 11, 2021 00:41
@marcaaron marcaaron requested a review from a team as a code owner May 11, 2021 00:41
@marcaaron marcaaron changed the title [HOLD] Add Personal Bank Account via Plaid flow Add Personal Bank Account via Plaid flow May 11, 2021
@MelvinBot MelvinBot requested review from francoisl and removed request for a team May 11, 2021 00:41
@marcaaron
Copy link
Contributor Author

@francoisl this PR is kind of huge so going to add a couple more reviewers to it 😄

ios/Podfile Outdated
post_install do |installer|
flipper_post_install(installer)
# flipper_post_install(installer)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops forgot to remove this guy. It needed so that iOS will build on dev for now. 🙃

@@ -3,7 +3,7 @@
buildscript {
ext {
buildToolsVersion = "29.0.2"
minSdkVersion = 16
minSdkVersion = 21
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears to be a requirement in order to use the Plaid SDK on Android

https://github.com/plaid/react-native-plaid-link-sdk#3-configure-gradle

I'm hoping it's OK ? @Jag96

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We talked about doing this a while back but this is definitely fine, the issue is here: https://github.com/Expensify/Expensify/issues/149395

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh nice!

props.onSuccess({publicToken, metadata});
}, []);

const {open, ready, error} = usePlaidLink({
Copy link
Contributor Author

@marcaaron marcaaron May 11, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We normally should not need to use hooks (and kind of discourage it), but the Plaid library we're using for React web here really only offers this option to launch the flow programmatically.

currency: 'USD',
fieldsType: 'local',
plaidAccessToken,
isForStripeConnect: false,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ctkochan22 wondering if you can help us figure out whether we need all of this stuff. I loosely based these parameters on what we send when adding a PBA on e.com.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't need isForStripeConnect. The rest are necessary I think. But when it comes to additionalData, more info is always good I think. What you have now is good.

Copy link
Contributor

@francoisl francoisl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, a lot of it is over my head though. Still trying to test but I think my .env file is messed up and causing me errors, going to look into that.

@@ -10,7 +10,7 @@
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Default value: -Xmx10248m -XX:MaxPermSize=256m
# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What version of the JDK do we target? MaxPermSize was removed in JDK 8 so that param might not do anything

}

/**
* Get list of bank accounts
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious why this method gets a doc but not the one below?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only because it has a return value. I think at one point we were enforcing method docs but now only making them if there is a param or return that needs to be documented or some additional comments.

@francoisl
Copy link
Contributor

Conflicts

@marcaaron
Copy link
Contributor Author

Updated and fixed the conflicts.

@marcaaron
Copy link
Contributor Author

@shawnborton I was thinking we could do styling stuff in a follow up with a contributor if that works for ya. Mostly just trying to scaffold some stuff out here.

@shawnborton
Copy link
Contributor

Cool, that works for me. Though it is a bit strange that our default component wouldn't have the default font/color baked into it? But yeah, we can investigate that elsewhere.

src/CONFIG.js Outdated

// Throw errors on dev if config variables are not set correctly
if (ENVIRONMENT === CONST.ENVIRONMENT.DEV) {
if (!useNgrok && expensifyURL.endsWith('dev') && !expensifyURLSecure.endsWith('dev')) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my .env file, I have a trailing slash for both the EXPENSIFY_URL_COM and the EXPENSIFY_URL_SECURE values, so this logic doesn't throw the error if I have EXPENSIFY_URL_COM=https://www.expensify.com.dev/ and EXPENSIFY_URL_SECURE=https://secure.expensify.com/

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦 fixed this up and changed it to an String.includes()

Jag96
Jag96 previously approved these changes May 14, 2021
ctkochan22
ctkochan22 previously approved these changes May 17, 2021
Copy link
Contributor

@ctkochan22 ctkochan22 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great

francoisl
francoisl previously approved these changes May 17, 2021
Copy link
Contributor

@francoisl francoisl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a conflict

@marcaaron marcaaron dismissed stale reviews from francoisl, ctkochan22, and Jag96 via 4d18304 May 17, 2021 20:42
@Jag96 Jag96 merged commit c100011 into main May 17, 2021
@Jag96 Jag96 deleted the marcaaron-addBankAccount branch May 17, 2021 21:12
@OSBotify
Copy link
Contributor

✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release.

@isagoico
Copy link

@Jag96 Heyo! Will this be internally tested? Let me know so we can check it of the list. 🙇

@marcaaron
Copy link
Contributor Author

This should be QA testable. With the exception of desktop since there are no deep links.

@marcaaron
Copy link
Contributor Author

I'm happy to takeover the testing for this. I think I intended it to be Internal just because of how weird it is.

@marcaaron
Copy link
Contributor Author

Web is working fine 🎉
Android doesn't work 🤔
Will test iOS next...

I think no need to block on this as long as the rest of the app works. Nothing is using the flow yet.

@marcaaron
Copy link
Contributor Author

Oh hmm I think judging from logs the native Android app is not using the staging server...
I assumed that it would, but that seems wrong since there is no badge in the sidebar header.

cc @roryabraham to confirm.

@marcaaron
Copy link
Contributor Author

Probably we will need to test this on production anyway to be sure it works - I think it will, but I don't have an account to test with as my bank is not an option in Plaid.

@roryabraham
Copy link
Contributor

@marcaaron Are you asking if the E.cash Android beta (staging) app communicates with the staging API? If so, the answer is no – E.cash staging only communicates with the production API, by design. There was a fair amount of discussion around this already, but basically the reason is that if E.cash staging can't talk to our staging API, then there's no chance we deploy code that breaks E.cash production because it is dependent upon a staging API which has not yet been deployed.

@marcaaron
Copy link
Contributor Author

Let me ask another way... 😅

https://staging.expensify.cash appears to use the .env.staging variables but native apps do not?

@roryabraham
Copy link
Contributor

Ah, yes that's true. The reason for that is because when we run an iOS/Android deploy we just take an existing beta build and release it for production.

@marcaaron
Copy link
Contributor Author

Got it! Thanks for the context. I think this will need to be Production QA in that case and someone with a bank account can help us test it eventually. Anyways, @isagoico no need to block on this one.


useEffect(() => {
if (error) {
props.onError(error);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This usage leads to #38069. This happened due to a change in onError on each re-render as it wasn't memoized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants