#RGRTHAT
1 messages ยท Page 1 of 1 (latest)
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 aren't your usual Customer objects. Instead, these represent a grouped view of related payments - https://support.stripe.com/questions/guest-customer-faq
Guest customers can't be deleted
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
express
connected account express
and the customers are attached to the connected account express
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
are u kidding me. I have like 70 customers i need to delete
...
i cant manually delete each customer
So use the API?
i still have to input customer_id of 70 customers
i see
Takes like 3 mins
i wonder why u dont support batch delete
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
for some wierd ass reason, when on mount initialize a payment intent, it seems like the paymentintent creates 2 customers on the connected account
Sounds like a bug in your code
PaymentIntents don't create Customers
So where/how are you creating Customers?
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..
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
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..
setup_future_usage: "off_session",
```yup
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?
no paymentMethod in the customer page
Can you give me the PaymentIntent ID or Customer ID to look at?
cus_MUIDk8x7kUAdDM
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
I confirm true client side
Well sure
with stripe.confirmPayment
but i havent done it will all the transactions
cuz i have just tested the paymentintent initialization
which happens on mount
Then you need to do that to trigger the Charge and attach the PaymentMethod
and i have ignored the actual payment as i know thats fine
Yeah you won't see the PaymentMethod attached to the Customer until you confirm the PaymentIntent
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
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
But that is all due to the original bug that is creating two Customers, no?
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
Share your client side code?
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
Yeah I would test with it outside useEffect to see if it is a re-render issue
Yep
lol wat
but functions like this should always be inside useeffct on mount
Yes agreed
Just struggling from afar to understand what would be causing it to duplicate
I have the stripePromise inside like so ```js
export default function checkout() {
const stripePromise = loadStripe(
"pk_test_..",
{
stripeAccount: selectedPurchase.service.connected_account_id,
}
);
That looks fine
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
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
Like I would just mirror our quickstart (https://stripe.com/docs/payments/quickstart?platform=web&client=react) real quick and make sure there isn't something else going on here.
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
fun fact
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
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
something in my react, some state or something causes a rerender
that causes the function on mount to be called twice
idk
Any chance you can serve over ngrok or something and I can take a look?
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
Okay so.... what wraps your Checkout component?
Totally forgot you are using Next.js
Which... I have never really played with tbh
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
lol yeah this is beyond me and sounds like a Next thing tbh
Worth checking on that
Which would be in your next.config.js it seems: https://nextjs.org/docs/api-reference/next.config.js/react-strict-mode
Was it that?
I mean I guess I understand why it could be useful
But.... that should never ever be enabled by default imo
yup thats what i think aswell
never enable things by default. let the user enable it
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
Why would Stripe stop the second request?
Plenty of people create multiple customers a second
stripe should not stop the 2nd request, but the 2nd request to create 2 identical customer
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
how can i enable that?
oh
Because some people want duplicates for ~reasons
I'm saying by not de-duplicating it allows for all use-cases
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
What?
Why would they ever have to enter details again
The whole point of cloning is to not have to do that
I first have to do a SetupInit to be able to have paymentMethod to pass to paymentIntent
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
My current flow is this ```js
-
user creates account on website
-
user have to input card details.
- for SetupIntent. Create a paymentMethod so i can duplicate user object at paymentIntent.
- 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
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
I see that with ```js
confirmCardPayment()
in other words u can actually just pass the client_secret it looks like
Yes that's correct
But why not just confirm when you create the PaymentIntent on your server?
Why make the extra request here?
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
Yep exactly
its nice to have the option for user to select another payment option though
If the PaymentIntent is in requires_action then you confirm client side
so i can have a conditional, where the user can select a new card for example
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
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
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
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
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
It's been a fun ride
Feel free to pop back in next week if we can help more
I have learned alot more about the api aswell