#RGRTHAT

1 messages ยท Page 1 of 1 (latest)

vestal lintelBOT
storm rose
#

Hi there! Let's chat in this thread

#

Are the checkboxes greyed out?

#

If they are, I suspect these are customers listed in the "Guests" tab

#

Guest customers can't be deleted

drowsy lake
#

its customers of the connected account

#

i first presed on the connected account => customers.

#

i want to delete every customer i have deleted sofar

#

cuz its duplication.

#

im not supposed to have several customers that are the same

#

I need to delete them to check if my new implementation works

#

@storm rose

#

they are not guests

green salmon
#

Hey there

#

These are Standard accounts, right?

drowsy lake
#

express

#

connected account express

#

and the customers are attached to the connected account express

green salmon
#

Gotcha

#

I think you need to "View as" to delete

#

If you are deleting via the Dashboard

#

But why not just delete via the API?

#

You don't need to "View as" actually, you just need to view the Customer

#

We don't support a batch API here

drowsy lake
#

are u kidding me. I have like 70 customers i need to delete

green salmon
#

...

drowsy lake
#

i cant manually delete each customer

green salmon
#

So use the API?

drowsy lake
#

i still have to input customer_id of 70 customers

green salmon
#

No... you write a script

#

Where you list and loop

drowsy lake
#

i see

green salmon
#

Takes like 3 mins

drowsy lake
#

i wonder why u dont support batch delete

green salmon
#

Fair question!

#

We just haven't built it

#

It would be nice

#

But currently only batch operation we support is batch refunds

#

Just don't think it is high on the priority list overall

#

But I can note some feedback internally

drowsy lake
#

for some wierd ass reason, when on mount initialize a payment intent, it seems like the paymentintent creates 2 customers on the connected account

green salmon
#

Sounds like a bug in your code

#

PaymentIntents don't create Customers

#

So where/how are you creating Customers?

drowsy lake
#

no ofcourse haha ๐Ÿ˜„ but my code above it

#

i meant i called the request that initialize paymentintent

#

i have a conditional before i create the paymentintent. I first check if a customer already exist

#

if it exists, then i use that customers id and their paymentmethod

#

else i clone a existing platform customer and add paymentmethod

#
let alreadyExist = await stripe.customers.list(
      {
        email,
      },
      { stripeAccount }
    );

    console.log("alreadyExist", alreadyExist);

    if (alreadyExist.data.length > 0) {
      return alreadyExist.data[0];
    } else {
      return false;
    }
#

The problem i have now is.. as u can see in database picture. 2 customers were created

#

that means that when i do this request again, the list will be 2 not 1, when i fetch based on email

#

which again means that i might not get the paymentmethod assosiated with the right customer

#

i need to figure out why my code creates 2 customers..

green salmon
#

lol yep

#

Recommend adding some logs to see why your customer creation is duplicating

#

Could also use breakpoints if you want to debug that way

drowsy lake
#

another wierd ass thing is.. why isnt the paymentmethod listed in the picture above

#

i provided the payment method in the paymentintent

#

the paymentIntent was succeeded and payed

#

the paymentmethod id should be there..

green salmon
#

Did you pass setup_future_usage?

#

In your PaymentIntent creation

drowsy lake
#
setup_future_usage: "off_session",
```yup
green salmon
#

Ah actually I think the Dashboard only displays the default payment method (if one is set) in that column

#

If you actually look at the Customer page in the Dashboard is there a PaymentMethod attached?

drowsy lake
#

no paymentMethod in the customer page

green salmon
#

Can you give me the PaymentIntent ID or Customer ID to look at?

drowsy lake
green salmon
#

Yeah paste that Customer ID

#

So I can look

drowsy lake
#

cus_MUIDk8x7kUAdDM

green salmon
#

The PaymentIntent associated with that Customer is incomplete

#

Needs to be confirmed

#

You didn't pass confirm: true on creation

#

๐Ÿ™‚

#

You always have to confirm

drowsy lake
#

I confirm true client side

green salmon
#

Well sure

drowsy lake
#

with stripe.confirmPayment

#

but i havent done it will all the transactions

#

cuz i have just tested the paymentintent initialization

#

which happens on mount

green salmon
#

Then you need to do that to trigger the Charge and attach the PaymentMethod

drowsy lake
#

and i have ignored the actual payment as i know thats fine

green salmon
#

Yeah you won't see the PaymentMethod attached to the Customer until you confirm the PaymentIntent

drowsy lake
#

well i have put some console.logs in my request where i initialize the payment intent

#

and it console.log twice

#

something is defiently wrong lol

green salmon
#

lol

#

Add a log in each step to narrow it down

drowsy lake
#

My conditionals are based on the fact that its just 1 customer with 1 specific email per connected account

#

but as this function runs twice, i now have 2 customers

#

and when i after getting the customer.id and then fetch the paymentmethod, i get wrong paymentmethod

green salmon
#

But that is all due to the original bug that is creating two Customers, no?

drowsy lake
#

yeh

#

i have tried to fix some of the code, let me check again

#

when i see in browser network console

#

i see 2 requests are trying to send

#

wtf

#

i have the request fuction in useEffect on mount

green salmon
#

Share your client side code?

drowsy lake
#
let payment_intent = async () => {
    try {
      let result = await axios.post(
        `${helper_func.server_url}payment-intent`,
        { ...selectedPurchase },
        {
          withCredentials: true,
        }
      );

      setClientSecret(result.data.client_secret);
    } catch (error) {
      console.log(error);
    }
  };

  useEffect(() => {
    payment_intent();
  }, []);
#

I have a suspect in mind

#

I have put the stripePromise inside the function

#

which might cause a rerender when clientSecret change or something idk

green salmon
#

Yeah I would test with it outside useEffect to see if it is a re-render issue

drowsy lake
#

test to have ```js
payment_intent()

#

like so without useeffect?

green salmon
#

Yep

drowsy lake
#

it calls the request 4 times

green salmon
#

lol wat

drowsy lake
#

but functions like this should always be inside useeffct on mount

green salmon
#

Yes agreed

#

Just struggling from afar to understand what would be causing it to duplicate

drowsy lake
#

I have the stripePromise inside like so ```js
export default function checkout() {
const stripePromise = loadStripe(
"pk_test_..",
{
stripeAccount: selectedPurchase.service.connected_account_id,
}
);

green salmon
#

That looks fine

drowsy lake
#

i wanted to have it wrapped around main component

#

but as I needed the stripeAccount_id which is dynamic

#

im not able to access it if i wrap it in the main component

#

this stripePromise is inside my functional component

#

i wonder if that might cause the rerender

#

cuz when stripeAccount changes, then the Element component will rerender

#

idk

green salmon
#

Yeah that's fine though for Elements to re-render

#

I mean, ideally, you know the merchant you are paying before you render Payment Element at all

#

But if you handle that on the same page, then you will just end up with a bunch of incomplete PaymentIntents, which isn't the end of the world.

#

But yeah, try moving your stripePromise outside of your Checkout component

#

Also always recommend killing your app and running it again. As I've seen some random/weird behavior occur during local React development that has taken forever to debug and was fixed via a turn off/turn on

drowsy lake
#

In the example link above, the loadStripe is outside. The issue is, i cant have it outside of the function, because then i wont have access to my Context

#

When I use ```js
const stripePromise = loadStripe(
"pk_test_...",
{
stripeAccount: stripeAccount_state,
}
);

#

as u can see, i pass a stripeAccount state to the LoadStripe()

#

so the loadStripe needs to be inside function to access context

#

The fragile thing is. Someone else can easily just use something like postman and spam my request, and screw up for the stripe API

#

thats kinda what have happened here. cuz stripe wont be able to be quick enough to fetch the list, before i have created a new customer

#

thats why i have gotten 2 customers in a row

#

I cant risk having 2 of the same emails for customers

green salmon
#

No you should hit an object lock if you are trying to list customers and create a customer at the same time

#

I really think the issue here is just that something is causing you to hit your endpoint twice in short succession

drowsy lake
#

something in my react, some state or something causes a rerender

#

that causes the function on mount to be called twice

#

idk

green salmon
#

Any chance you can serve over ngrok or something and I can take a look?

drowsy lake
#

never done that before. no clue what that even is

#

I will just try to figure it out. i suspect its something with the Element

#

let me try to remove everything about that, and just see how the request change

#

NOPE, i removed everything about stripe. The element, stripePromise, everything

#

still twice requests

green salmon
#

Okay so.... what wraps your Checkout component?

drowsy lake
#

just normal divs

#

ok I know the issue i think

#

I have a bunch of hydration errors

green salmon
#

Totally forgot you are using Next.js

drowsy lake
green salmon
#

Which... I have never really played with tbh

drowsy lake
#

sometimes i HATE next

#

tbh

#

certain modules u cant import because they have locked it

#

for example u cant import css from node_modules

#

so u get errors when using certain libraries

#

next have a bunch of flaws like that

#

@green salmon I created a brand new page with nothing but a useEffect on mount and a console.log

#

the request is called twice

#

so its something wrong with my Header component

#

which is inside a wrapper component

green salmon
#

lol yeah this is beyond me and sounds like a Next thing tbh

#

Worth checking on that

drowsy lake
#

@green salmon fixed!

#

oh u have linked to strict mode

green salmon
#

Was it that?

drowsy lake
#

that was exactly what caused it

#

yes

green salmon
#

lol

#

WHY DOES THAT EXIST?!

#

๐Ÿ˜‰

drowsy lake
#

no clue it seems to be in development mode

#

react 18

green salmon
#

I mean I guess I understand why it could be useful

#

But.... that should never ever be enabled by default imo

drowsy lake
#

yup thats what i think aswell

#

never enable things by default. let the user enable it

green salmon
#

Yeah

#

Well, glad that is sorted

#

Sorry it took so long

drowsy lake
#

the only worrying thing is how the 2 customers was created at ones. Ofcourse this wont happen again now, as only 1 request will be sent at ones

#

but wierd stripe doesnt stop the 2nd request

green salmon
#

Why would Stripe stop the second request?

#

Plenty of people create multiple customers a second

drowsy lake
#

stripe should not stop the 2nd request, but the 2nd request to create 2 identical customer

green salmon
#

Yeah we don't de-duplicate by default

#

Similar to what you just noted above... we leave this up to the developer

#

Allows for more flexibility really, but also yes, having to deal with this if you don't want it

drowsy lake
#

how can i enable that?

green salmon
#

You can't

#

I'm saying we don't provide a feature like that

drowsy lake
#

oh

green salmon
#

Because some people want duplicates for ~reasons

#

I'm saying by not de-duplicating it allows for all use-cases

drowsy lake
#

I dont really like my payment details flow tbh

#

first asking for card details to setup paymentMethod. And then the customer have to put in card details again l8r on when purchasing

green salmon
#

What?

#

Why would they ever have to enter details again

#

The whole point of cloning is to not have to do that

drowsy lake
#

I first have to do a SetupInit to be able to have paymentMethod to pass to paymentIntent

green salmon
#

Sure? The Customer doesn't have to re-enter their details at that point though?

#

You just use the PaymentMethod object with the PaymentIntent

#

Really you want to change out your PaymentIntent for a SetupIntent in your Payment Element code above

drowsy lake
#

My current flow is this ```js

  1. user creates account on website

  2. user have to input card details.

  • for SetupIntent. Create a paymentMethod so i can duplicate user object at paymentIntent.
  1. When user want to purchase something, he also have to input card details.
  • I use the stripe.confirmPayment.
  • Serverside I do pass the paymentMethod.
#

@green salmon as I have understood, u cant prefill card details on the element

#

the user have to input their card details & press confirm

#

which will trigger stripe.confirmPayment

green salmon
#

Yeah no that's not correct.

#

client-side in this case you want to use confirmCardPayment if you are using a Card PaymentMethod

#

But really

#

You don't even do that

#

You confirm Server-side like I said above

#

Then, if 3DS is required, you confirm again client-side to handle 3DS

#

Really 3DS will rarely be required here since the card will already be set up via the SetupIntent

#

It would indeed be a horrible flow if your customer had to enter details twice.

#

You should only be using PaymentElement to collect new payment methods

drowsy lake
#

I see that with ```js
confirmCardPayment()

#

in other words u can actually just pass the client_secret it looks like

green salmon
#

Yes that's correct

#

But why not just confirm when you create the PaymentIntent on your server?

#

Why make the extra request here?

drowsy lake
#

i suppose its not necessary

#

i could just render UI based on what status paymentIntent init request gives me

#

i dont really need to confirm clientside

green salmon
#

Yep exactly

drowsy lake
#

its nice to have the option for user to select another payment option though

green salmon
#

If the PaymentIntent is in requires_action then you confirm client side

drowsy lake
#

so i can have a conditional, where the user can select a new card for example

green salmon
#

Oh yeah sure.

#

You would display their saved PaymentMethods alongside Payment Element (or a button to render Payment Element)

#

For a new Customer you just render PaymentElement

drowsy lake
#

u cant render a Element without a client_secret, so I suppose the best way would be to have 2 buttons. ```js

button 1: Pay now with saved card

button 2: Select different payment solution

  • Which render Element component & sends request to paymentIntent to retrieve client_secret. In this case no paymentMethod is attached
#

The thing i did encounter earlier is that, u cant pass a customer to the paymentIntent in stripe connected account, if the customer doesnt have a paymentMethod

green salmon
#

None of what you said is really true.

#

You can render Card Element without a client secret

#

You can't render Payment Element without a client secret

#

But yes, if you don't want to create extra SetupIntents on your platform, then using a button to "add a new payment method" for return Customers would be good

#

And u cant pass a customer to the paymentIntent in stripe connected account, if the customer doesnt have a paymentMethod isn't really true so would need more details to understand what you mean

drowsy lake
#

When creating a new paymentIntent for connected account, and u want to pass a customer in the paymentIntent, u also need to add payment_method

green salmon
#

You should not need to do that if you are passing setup_future_usage

#

Since you can always confirm client-side

#

There is really no difference here in how customers are treated on a Connected Account or on your Platform

drowsy lake
#

I see

#

I want to thank u so much for your help โค๏ธ

green salmon
#

It's been a fun ride

drowsy lake
#

its 2am here, so i need to goto sleep

#

yeh haha

#

strictmode 4 the win

green salmon
#

Feel free to pop back in next week if we can help more

drowsy lake
#

I have learned alot more about the api aswell

green salmon
#

๐Ÿ‘

#

Best of luck with the project