#L0rdandBooz

1 messages · Page 1 of 1 (latest)

meager kelpBOT
finite swift
#

hello! can you share more on what's your question?

umbral wharf
#

Hey Alex!

#

I'm following this guide and having a heck of a time getting it to work.

#

I don't understand how the stripe account link modal just shows up and the steps to get there

finite swift
#

which specific step are you stuck with?

#

and what have you tried so far?

umbral wharf
#

I'm stuck on getting the modal to show up / using the collectBankAccount for setup. I'm fine in regards to creating setupIntent

#

Basically i'm stuck after getting the client secret

#

I'm using next.js if that helps

finite swift
umbral wharf
#

I looked through that and unfortunately it didn't really help 😦

#

It feels like there's so much code left out because where does the modal even appear from? It looks like it's provided by stripe but I never do anything to show it.

finite swift
#

the modal is automatically displayed by Stripe

umbral wharf
#

I wish there was a full file I could take a look at so I can see how everything interacts. Is that by chance a thing?

finite swift
#

you'd probably want to look at the ACH direct debit custom payment flow

finite swift
#

to clarify - the example is for accepting payments, which isn't exactly the same as what you're looking to do i.e. saving the bank account details for setup. But you can still see how the modal is displayed

umbral wharf
#

Right which helps.

#

stripe.collectBankAccountForSetup({
clientSecret: clientSecret,
params: {
payment_method_type: 'us_bank_account',
payment_method_data: {
billing_details: {
name: accountHolderNameField.value,
email: emailField.value,
},
},
},
expand: ['payment_method'],
})

#

is the expand on this what makes the modal pop out?

finite swift
#

no, nothing in the parameters specifically is what makes the modal pop out. when stripe.collectBankAccountForSetup is called, stripe.js will automatically display the modal to collect the bank details

umbral wharf
#

OK. How does it know which page and where on the page to display it?

#

Is this what does it?

finite swift
#

it's a modal, so it'll pop up on the page where you're calling it. I'm a bit confused by the question where on the page to display it - do you have any concerns about this?

umbral wharf
#

No what you said about it just popping up makes sense. How do I tell it what page to pop up on though?

#

Is there a component I need to place in the body or something specific I need to import?

finite swift
#

you don't need to tell it what page to pop up on, it'll pop up on the page where that specific line of code is called

umbral wharf
#

Ok I think that makes sense. I'm going to try and few things and see how it goes😭

#

Thank you so much

#

If you wouldn't mind leaving this ticket open until I report back so it's easily findable?

finite swift
#

the thread will automatically close, but you can reach out again on the main channel if you need help again or have more questions

#

generally, i've found it a lot easier to understand once i've tried something out

umbral wharf
#

Yeah that's the issue I've been trying for hours lol

#

This additional bit of insight is going to change that though

#

It will work!

#

Hey alex

#

I'm back

#

const response = await stripe.collectBankAccountForSetup(client_secret, {
billing_details: {
name: "John Doe",
email: "test@test.com",
},
});

#

TypeError: stripe.collectBankAccountForSetup is not a function

#

I'm getting a type error on this so I'm unable to call it

finite swift
#

did you import stripe.js?

umbral wharf
#

What's the proper way to do it? I've never seen an import statement like this. <script src="https://js.stripe.com/v3/"></script>

#

ReferenceError: Cannot access 'loadStripe' before initialization

#

import {loadStripe} from '@stripe/stripe-js';

const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);

const loadStripe = await loadStripe(process.env.STRIPE_SECRET_KEY);

raven timber
#

If you're using React, you should be able to import Stripe with:

import { loadStripe } from '@stripe/stripe-js';

const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_CLIENT_KEY);

// Then pass stripePromise into Elements creation
<Elements stripe={stripePromise}>
#

the key should be publishable key, not secret key

umbral wharf
#

Thank you! I'm getting this error now TypeError: Cannot read properties of null (reading 'collectBankAccountForSetup')

raven timber
#

How do you initialise stripe in stripe.collectBankAccountForSetup?

umbral wharf
#

const response = await loadStripes.collectBankAccountForSetup({
clientSecret: client_secret,
params: {
payment_method_type: 'us_bank_account',
payment_method_data: {
billing_details: {
name: 'john doe',
email: 'bruh',
},
},
},
});

raven timber
#

The stripe here should be from useStripe(), not from loadStripe. loadStripe is only for Elements initialisation:

import { useStripe } from '@stripe/react-stripe-js';

const stripe = useStripe();
const result = await stripe.collectBankAccountForSetup(...);
umbral wharf
#

Do you by chance know next.js at all?

#

TypeError: Cannot read properties of null (reading 'useContext')

#

Still getting the same error

#

It's basically react but you have to handle await and stuff a little differently

raven timber
#

Yup, I used next.js in my own testing as well

#

The above approach works for me

umbral wharf
#

const useStripes = useStripe(process.env.STRIPE_SECRET_KEY);

#

here's specifically what I'm doing for where the error currently is

#

I have this in my
export async function getServerSideProps(ctx) {

#

so it'll just render the modal on page load

raven timber
#

You don't have to put secret key in useStripe

#

Just simply:

const stripe = useStripe();
umbral wharf
#

I removed it and I'm still receiving the same error

raven timber
#

Can you share the full code?

#

Like how you initialise the stripe and call collectBankAccountForSetup?

umbral wharf
#

yeah standby

#

import {ErrorMessage, Field, Form, Formik} from "formik";
import Input from "./components/Input";
import {ClipboardListIcon} from "@heroicons/react/outline";
import React, {useState} from "react";
import {toast} from "react-hot-toast";
import axios from "axios";
import {getSession, signOut, useSession} from "next-auth/react";
import * as yup from "yup";
import {prisma} from "../lib/prisma";
import {useRouter} from "next/router";
import { useStripe } from '@stripe/react-stripe-js';
import { loadStripe } from '@stripe/stripe-js';
import {Elements} from "@stripe/react-stripe-js";

#

my import statements

#

If you need more I have more in the file but this is just the data fetching section

raven timber
#

It should be something like this in Next/React:

import { useStripe } from '@stripe/react-stripe-js';

type BankAccountProps = {
  clientSecret: string,
}

const BankAccountForm = (props: BankAccountProps) => {
  const handleConfirm = async () => {
    const stripe = useStripe();

    if (!stripe) {
      console.log('No stripe');
    }

    const result = await stripe.collectBankAccountForSetup(props.clientSecret, {
        payment_method_type: 'us_bank_account',
        payment_method_data: {
          billing_details: {
            name: 'Jane Yong',
            email: 'test@test.com',
          },
        },
    });
  };
};
umbral wharf
#

so do I need to render that or will it be done automatically?

raven timber
#

I tested in my own and it works fine.

Data collection should be done by your end and pass them into collectBankAccountForSetup

#

The parameters in your collectBankAccountForSetup is incorrect

#

Parameters in react's version is different

umbral wharf
#

My parameters look the same as yours. Forgive me but what am I missing?

#

It looks like you wrapped it into a bankaccount form function and are passing the secret in there but otherwise it seems like I'm doing the same thing

raven timber
#

Mine doesn't have params whereas yours has

umbral wharf
#

oh not sure how i missed that

raven timber
#

I recommend copying mine to yours first, and try it out

umbral wharf
#

Should I just copy and paste it where my current one is?

raven timber
#

Yup! There are two input parameters. First is client_scret, and second one is options for the payment method details

umbral wharf
#

Modified it slightly because my JS file doesn't support types.

#

let client_secret= setupIntent.client_secret;
let BankAccountProps = {
clientSecret: client_secret,
}

const BankAccountForm = (BankAccountProps) => {
    const handleConfirm = async () => {
        const stripe = useStripe();

        if (!stripe) {
            console.log('No stripe');
        }

        const result = await stripe.collectBankAccountForSetup(BankAccountForm.clientSecret, {
            payment_method_type: 'us_bank_account',
            payment_method_data: {
                billing_details: {
                    name: 'Jane Yong',
                    email: 'test@test.com',
                },
            },
        });
    };
};
#

Still getting the same error 😦

raven timber
#

What's the error message?

warm skiff
#

Hi @umbral wharf I'm taking over this thread

umbral wharf
#

wait

#

it started working

#

It doesn't display the modal though

#

River you are a hero thank you so much for getting me this far

#

How do I go about getting it to display the modal now?

#

I was under the impression it'd just show up if I called the collect bank account info item

warm skiff
#

I'm happy to learn that the problem is resolved.

#

Feel free to let me know if you have a follow-up question.

umbral wharf
#

Wait I'm still having an issue

#

How do I get the modal to display now?

#

const stripePromise = loadStripe();

return (

        <div>
            <h1>Please link an external bank account!</h1>
            <Elements stripe={stripePromise}>
                <PaymentElement />
            </Elements>

)

#

here's my current return statement

warm skiff
#

Hi @umbral wharf It's a long thread, can you give me a quick summary?

umbral wharf
#

Essentially I'm trying to verify peoples external bank accounts to allow for treasury account transfers in and out of the platform. I'm having a very hard time getting the stripe verification modal to show up on my page

#

I need to link the external bank account to the internal treasury financial account

warm skiff
#

OK, you mean no dialog is open after calling stripe.collectBankAccountForSetup() ?

umbral wharf
#

right it doesn't display anything

warm skiff
#

Did you see any error in the browser console?

umbral wharf
#

(node:7164) Stripe: Options found in arguments (stripeAccount). Did you mean to pass an options object? See https://github.com/stripe/stripe-node/wiki/Passing-Options.
(node:7164) Stripe: Invalid options found (attach_to_self, flow_directions, payment_method_types, payment_method_options); ignoring.
(node:7164) Stripe: Options found in arguments (stripeAccount). Did you mean to pass an options object? See https://github.com/stripe/stripe-node/wiki/Passing-Options.
(node:7164) Stripe: Invalid options found (attach_to_self, flow_directions, payment_method_types, payment_method_options); ignoring.

SERVER CONSOLE

GitHub

Node.js library for the Stripe API. . Contribute to stripe/stripe-node development by creating an account on GitHub.

#

Uncaught (in promise) IntegrationError: Missing value for Stripe(): apiKey should be a string.
at Q (v3:1:72155)
at $ (v3:1:72226)
at new t (v3:1:368652)
at as (v3:1:405619)
at initStripe (stripe.esm.js?ef25:101:1)
at eval (stripe.esm.js?ef25:125:1)

#

CLIENT CONSOLE

warm skiff
#

So you have problems in both front end and backend. Let's fix the frontend first.

umbral wharf
#

Sounds good.

#

const stripePromise = loadStripe(process.env.STRIPE_SECRET_KEY);

#

here's the stripe thing that is giving the frontend the error, or so I think

warm skiff
#

const stripePromise = loadStripe(process.env.STRIPE_SECRET_KEY);
You should pass the publishable key here, not the secret key

umbral wharf
#

oh ok. hold up while I switch that

#

IntegrationError: In order to create a payment element, you must pass a valid PaymentIntent or SetupIntent client secret when creating the Elements group.

e.g. stripe.elements({clientSecret: "{{CLIENT_SECRET}}"})

#

I'm getting this error now

warm skiff
#

Did you pass in a valid setupIntent_client_secret to elements?

umbral wharf
#

<Elements stripe={stripePromise}>

#

Here's all that I'm passing currently

#

What is the proper way to do go about it?

warm skiff
#

Ah, you also need to pass in a client_secret.

umbral wharf
#

Also I thought the client secret was only necessary for the collectBankAccountForSetup method

#

Do I need to pass it to the element as well?

warm skiff
#
    clientSecret,
..
  }

  return (
      <Elements options={options} stripe={stripePromise}>
...

Something like this.

umbral wharf
#

const options = {
client_secret
}

#

<Elements stripe={stripePromise} options={options}>

#

here's what I went with

#

By the way I still have the apikey errors in my client console

warm skiff
#

Did you change it to publishable key?

umbral wharf
#

yep

#

STRIPE_PUBLISHABLE_KEY=pk_test_51LruhiLQhKtna1xjr08WNjbsmDan9CfuRij30WPNRP2AhmZI5tAdApWHqQcKQ1vHckzI8UImddqSq5BY0E12Tdvh00TRDphdDf

#

const stripePromise = loadStripe(process.env.STRIPE_PUBLISHABLE_KEY);

#

here's the errors I'm getting

warm skiff
umbral wharf
#

Yes!

#

That fixed those errors we have some new ones but I think we're starting to get somewhere 😅

#

IntegrationError: In order to create a payment element, you must pass a valid PaymentIntent or SetupIntent client secret when creating the Elements group.

e.g. stripe.elements({clientSecret: "{{CLIENT_SECRET}}"})

#

Here's the current error

warm skiff
#

OK. Then you need to create a SetupIntent at your backend, pass the client_secret to frontend so that you can pass it to the elements

umbral wharf
#

That's what I'm doing is the thing

#

I've confirmed that I'm using the client secret in there because I console.log it on the client side to check

#

Is it a one time use? I'm currently using it in the collectBankAccountForSetup

#

seti_1M6TWaPu5lQVhWK8Vq6EMczm_secret_Mq9qj4bIcwZPGekuYYwdYZpqTGnSqfo

#

here's what the most recent one looked like

#

const BankAccountForm = (BankAccountProps) => {
const handleConfirm = async () => {
// eslint-disable-next-line react-hooks/rules-of-hooks
const stripe = useStripe();

        if (!stripe) {
            console.log('No stripe');
        }

        const result = await stripe.collectBankAccountForSetup(BankAccountForm.clientSecret, {
            payment_method_type: 'us_bank_account',
            payment_method_data: {
                billing_details: {
                    name: 'Jane Yong',
                    email: 'test@test.com',
                },
            },
        });

    };
};
#

here's the current bank account form function

warm skiff
#

Did you pass the client_secret to <Elements> ?

umbral wharf
#

Yes I did so via the options

#

console.log(client_secret);
const options = {
client_secret
}

#

<Elements stripe={stripePromise} options={options}>
<PaymentElement />
</Elements>

here's my elements tags

#

const setupIntent = await stripe.setupIntents.create({
stripeAccount: dbUser.connectAccountID,
attach_to_self: true,
flow_directions: ['inbound', 'outbound'],
payment_method_types: ['us_bank_account'],
payment_method_options: {us_bank_account: {verification_method: "automatic"}}
});
let client_secret= setupIntent.client_secret;
let BankAccountProps = {
clientSecret: client_secret,
}

#

here's my setup intent

warm skiff
#

Wait a second, actually you don't need to use Stripe elements.

umbral wharf
#

How do I go about it wise one?

warm skiff
#

You just need to pass the setup_intent_client_secret to stripe.collectBankAccountForSetup()

umbral wharf
#

I'm already doing that am I not?

warm skiff
umbral wharf
#

Right I've tried the stuff in that but can't get it to render. How do I go about getting it to show up?

#

This is one of the things I'm so confused about

#

<Elements stripe={stripePromise} options={options}>
<PaymentElement />
</Elements>

#

Do I need any of this or can I get rid of it all?

#

If I comment it out then this is the only error I have.

#

The issue is that it isn't rendering the modal still

warm skiff
#

Hmm. Are you using any chrome browser plugins?

umbral wharf
#

I'm using adblocker. I just turned it off and no longer have that error. It still isn't rendering though 🫤

#

here's the current serverside errors

#

Not sure if you'd really consider those errors though

warm skiff
#

Can you share with me the server side code?

umbral wharf
#

Yep

#

Lot's of comments because I'm removing functionality until this modal is working

warm skiff
#
const setupIntent = await stripe.setupIntents.create({
        stripeAccount: dbUser.connectAccountID,
        attach_to_self: true,
        flow_directions: ['inbound', 'outbound'],
        payment_method_types: ['us_bank_account'],
        payment_method_options: {us_bank_account: {verification_method: "automatic"}}
    });

attach_to_self and flow_directions are not valid params for SetupIntent creation API. Please refer to this API doc for the list of params that it accepts
https://stripe.com/docs/api/setup_intents/create?lang=ruby#create_setup_intent

umbral wharf
#

Hence why I'm so confused trying to do this😅

warm skiff
#

I see, these are beta params and not available to everyone yet.

umbral wharf
#

I should be on this beta though is the thing.

#

Is there a way for you to check if I have access?

#

At the very least I should have access to the test environment.

#

I was able to confirm that I do have access in test mode.

#

This seems like a better guide

#

Do you know if this still accomplishes the external bank account ownership verification though?

warm skiff
#

Correction. the attach_to_self and flow_directions are valid params, sorry for my oversights.

#

Can I have your merchant ID so that I can take a look at the log?

umbral wharf
#

All good. Absolutely one second

#

acct_1LruhiLQhKtna1xj

#

This is what you're looking for right?

warm skiff
#

And also the connected account ID?

umbral wharf
#

Yes standby

#

acct_1M6LUzPu5lQVhWK8

#

Connected account ID ^^

warm skiff
#

Thanks. I think there's a problem with the example code in this doc

const setupIntent = await stripe.setupIntents.create({
        attach_to_self: true,
        flow_directions: ['inbound', 'outbound'],
        payment_method_types: ['us_bank_account'],
        payment_method_options: {us_bank_account: {verification_method: "automatic"}}
    },{
          stripeAccount: dbUser.connectAccountID,
});

Can you change it to this and try again?

umbral wharf
#

yep standby

#

I'm no longer getting those errors in the console. The issue is the modal still isn't rendering.

#

What'd you change on the server side?

warm skiff
umbral wharf
#

Oh man. Dang good catch

#

I'm not getting any errors but I'm still not seeing my modal. Do you know what the issue could be?

warm skiff
#

And you also need to specify the connected_account ID in your frontend when initializing Stripe.js

const stripePromise = loadStripe('{{PLATFORM_PUBLISHABLE_KEY}}', {
  stripeAccount: '{{CONNECTED_STRIPE_ACCOUNT_ID}}',
});
umbral wharf
#

Ok standby while I do that.

#

const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY, {stripeAccount: dbUser.connectAccountID});

#

alright here's how it looks on my end now

#

Still not seeing the modal fyi

warm skiff
#

any errors in the browser console?

umbral wharf
#

nope

#

I'm still not certain where it is supposed to render from because we aren't putting anything into the return statement

#

Are you sure we don't need this?

            {/*<Elements stripe={stripePromise} options={options}>*/}
            {/*    <PaymentElement />*/}
            {/*</Elements>*/}
#

I've tried uncommenting it and it's still the same error.

warm skiff
#

There's no error when you call stripe.collectBankAccountForSetup() ?

umbral wharf
#

correct but it looks like it may not even be getting called

#

const BankAccountForm = (BankAccountProps) => {
const handleConfirm = async () => {
// eslint-disable-next-line react-hooks/rules-of-hooks
const stripe = useStripe();

        if (!stripe) {
            console.log('No stripe');
        }

        const result = await stripe.collectBankAccountForSetup(BankAccountForm.clientSecret, {
            payment_method_type: 'us_bank_account',
            payment_method_data: {
                billing_details: {
                    name: 'Jane Yong',
                    email: 'test@test.com',
                },
            },
        });

    };
    console.log('in');
};
#

that console.log isn't printing

warm skiff
#

It seems like the param names are omitted. Can you add in the param names and try again?

  {
    clientSecret: '{SETUP_INTENT_CLIENT_SECRET}',
    params: {
      payment_method_type: 'us_bank_account',
      payment_method_data: {
        billing_details: {name: 'Jenny Rosen', email: 'jenny@example.com'},
      },
    },
  }
);

// Handle the setupIntent or error
umbral wharf
#

const result = await stripe.collectBankAccountForSetup({
clientSecret: BankAccountForm.clientSecret,
params:{
payment_method_type: 'us_bank_account',
payment_method_data: {
billing_details: {
name: 'Jane Yong',
email: 'test@test.com',
},
},
},
});

#

Here's what I updated it to

#

doesn't appear to have made a difference

#

const BankAccountForm = async (BankAccountProps) => {

#

for some reason it isn't going into the bank account form at all

#

I got rid of it and am getting this error now

#

let client_secret= setupIntent.client_secret;
let BankAccountProps = {
clientSecret: client_secret,
}

        // eslint-disable-next-line react-hooks/rules-of-hooks
        const usestripe = useStripe();

        const result = await usestripe.collectBankAccountForSetup({
            clientSecret: client_secret,
            params:{
            payment_method_type: 'us_bank_account',
            payment_method_data: {
                billing_details: {
                    name: 'Jane Yong',
                    email: 'test@test.com',
                },
            },
            },
        });
#

here's the current code

warm skiff
#

Can you upload the whole project to somewhere that I can download? so that I can reproduce the problem at my end.

umbral wharf
#

Yes. Does a zip work?

warm skiff
#

Sure

umbral wharf
#

account:

sign in with google (you need to access it from the sidebar) the homepage version is deprecated.

#

That's the test account info

#

It should automatically take you to the application page, but if not just go /application in the url

#

Thanks so much for being willing to do this it's really above and beyond

warm skiff
#

Ah, please remove the env file

#

discord is a public place, everyone can see you file

umbral wharf
#

oh dear

#

I forgot about that lol

warm skiff
#

The discord is quite busy at this moment and I may not be able to find a solution today.

#

Can I suggest you to write in to Stripe support https://support.stripe.com/contact , send them the code and tell them you've talked to the engineers in discord. They'll forward the ticket to us and we'll continue to help you from there.

umbral wharf
#

Yep! is there anyway I could circumvent them and email straight to your team? I've found them to be pretty slow in getting back to me.

#

Alright it's been sent. Thanks so much for all of your help Jack. You're incredible.

#

Off to bed now it is nearly 2am my time😎