#picklepaws - setup for customer
1 messages ยท Page 1 of 1 (latest)
Hello! Just starting a thread for you -- I'll review and respond as soon as I can ๐
hey there, can you share a failing request ID so I can understand waht you're trying to do?
like req_123
We have the same question over here!
TLDR; trying to create a customer, subscription and gather credit card info (that will become the customer's default payment method) all in one form. Rather than having one page to collect customer info --> stripe.createCustomer + stripe.createSubscription --> show payment gathering page
OP - i can start another thread if this isn't what's going on for you.
@robust dune that's exactly what's going on for me. I don't want to create the customer in Stripe until I know the user isn't going to back out when they realize they don't want to provide payment info.
+1 +1 us too. We were just wondering how to "clean up" customers who abandon their checkout
or...worse, go back to the initial page, change something and submit again..
@rugged pebble here is the request id: req_8vAJuawD6YQL0l
So instead of what you're both trying to do, just confirm the setup intent without a customer
Then the first action to take with that payment method is to attach it to the customer you create
Then set as the invoice default PM, or set for a subscription etc as needed
are you using the payment element or card element client integration?
PaymentElement over here, I'm calling stripe.confirmSetup(...) - will this call return a payment method ID to me?
We're using the payment element
Ok then yea, what i said
with the card element you could just defer the setup intent creation until after the card details were filled in, for example, and provide the client secret at the end just before confirming
But that isn't an option for the payment element, currently
Ahh, once the SetupIntent gets confirmed, it'll have a PaymentMethod attached to it, I see.
Okay, I think I know how to move forward from here then. Thank you so much @rugged pebble!! And good luck to you with your flow @robust dune ๐
I think we're all set here as well. Thank you both. Good luck to you too @lethal willow
Hmm: "You cannot confirm this SetupIntent because it's missing a payment method. Update the SetupIntent with a payment method and then confirm it again."
Well that's a separate issue, how are you confirming?
await stripe.setupIntents.confirm(setupIntentId, {});
I create the setup intent initially like: const setupIntent = await stripe.setupIntents.create({ payment_method_types: ["card"] });
then I use the clientSecret and setupIntentId from that initial request to render my checkout page for the customer
the "Submit" button on the checkout page will:
- create a customer
- try to finalize the setup intent --> this is what we thought your instructions were
- use the paymentMethodId resulting from the finalized setup intent above in order to create a new subscription for the customer
Sure, but when you use confirmSetup in the client, the customer needs to have filled out their payment details (card details)
don't confirm server side, you need to confirm in the client as the guide illustrates, to collect those payment details
The reason we're doing server side is that client side confirm will do a redirect rather than return the result of the confirmation.
Or are you saying that we need to let the redirect happen..and then on the confirmation page is where we'd be doing the subscription creation?
A customer id is required to create the subscription - so we can't create one without it.
I didn't read the whole backlog but in theory that's not the recommended flow
what we recommend is to
1/ Create a Customer
2/ Create a Subscription to the right Price with payment_behavior: 'default_incomplete'
3/ Client-side confirm the underlying PaymentIntent (if a payment is needed) or SetupIntent (if there's no upfront payment) to collect payment method details
@robust dune you can (sort of) turn off the redirection using redirect: if_required - if you're supporting payment methods/countries where the redirect will occur, then I imagine you'd have to build the redirect page out to handle the rest of your flow.
Ok - I think I finally have something that's "working" but I have a few questions
@wraith river we're both doing a flow where we're collecting payment details from the user upon registration and we want to prevent creation of customers for incomplete registrations.
If we do it the recommended way and create a customer up front, then when user backs out of registration upon deciding that they don't want to provide payment, there would have to be some sort of cleanup job that handles dealing with that unused Customer - could do it on an unload of the client, but if the user just closes their browser, I don't think that works. I suppose you could use some metadata on the Customer to indicate that they never completed their registration, and then if they ever return try to fetch the customer that matches their email instead of creating a new one.
Now that I'm describing the two solutions, they don't sound so bad, but unfortunately I've got to get this feature out soon and I've already spent too much time on it. ๐ฅฒ If I get a chance to rework it using the recommended flow, I will.
I've got to get this feature out soon and I've already spent too much time on it.
Amen to that ๐
So here's where I've gotten to:
I create an empty setupIntent.
I then use that setupIntents secret to render a form (along with some other fields I need)
When the Submit button is clicked I will:
- Create a new customer
- Create a new subscription and link it with the new customer. Important:
payment_behavior: "default_incomplete"for that subscription
doesn't make sense to use default_incomplete since you already collected card details anyways and you lose all benefit from it
- I call
confirmSetupand then I pass thesubscriptionIdand thecustomerIdas parameters to the redirect page
- On the page I've redirected to..I use those params, along with the
setupIntentto look up the payment method that resulted from the card gathering and then I use:
customer: customerId
});
await stripe.subscriptions.update(subscriptionId, {
default_payment_method: paymentMethodId
});
why do you have a Subscription and customer before the SetupIntent is even confirmed?
Like if you're similar to @lethal willow you want to avoid the empty customer, I can get that. But you don't seem to do that ๐
@wraith river I am in a similar boat to @lethal willow.
Without that parameter I get an error like StripeInvalidRequestError: This customer has no attached payment source or default payment method. when I try to create the subscription
@robust dune maybe you need to update the customer again to set that PM as their default? https://stripe.com/docs/api/customers/update#update_customer-invoice_settings-default_payment_method
I haven't gotten as far as you yet but I imagine I'll run into the same error in a moment. Curious if the setting the default PM would solve your problem.
Yes - I'm trying that now!
After attaching the PM you can make it the default yes. Or pass default_payment_method on subscription creation
there's no reason to have the subscription created before. Not unless you use the Subscription's SetupIntent?
Sorry you both are doing things differently and talking to each other so it's hard to help
Sorry! I will step out of the conversation and start a new thread if I get stuck. Good luck @robust dune ๐
No need for a new thread if you do the same thing
but maybe wait for each step to be resolved
So really you are both doing way too many calls/steps and I don't get why exactly
let me know if one of you has a specific question
I'm doing the following calls
- Create
SetupIntent(to get the secret so I can have myPaymentElementload) - Confirm
SetupIntent(to have it update with thePaymentMethodid) - Create
Customer - Update corresponding
PaymentMethodwithcustomer_id - Create
Subscription(in progress, haven't been able to test to see if I'll run into any errors).
@wraith river Assuming we're not doing the recommended flow and creating the customer ahead of the intent+subscription, how would you trim down the number of calls here?
That is the lowest number of calls you can do in that flow unfortunately
Gotcha. I think the primary reason I chose not to create the Customer first and do that fetch to see if a customer with the given email address already exists is because I'm using an older version of the Stripe PHP Client and it doesn't support the search method (https://stripe.com/docs/api/customers/search) so I chose not to do that. Upon reflecting here, I could have tried to get around that by using curl from my PHP app (or upgraded the client).
@lethal willow - your approach may have an advantage in that by the time you're creating your subscription, you've already got the payment method id.
you could simply use https://stripe.com/docs/api/customers/list with the email parameter too, you don't need search
There it is, right there in the parameters. ๐คฆ Thanks @wraith river
My current issue is that I've created my custom and subscription before i've collected the payment info and so I have everything that I want EXCEPT that I'm not sure how to then actually change the status of the subscription to "active" from "incomplete"
@robust dune yeah that's the problem, your flow is really different from @lethal willow
there's no reason to create a SetupIntent if you already have created a Subscription
@lethal willow @robust dune are you making progress? Do you still need help?
I got stuck with some silly React problem so I'm just now at the point of creating the subscription. I have confidence it will work, but I'll ping here to confirm.
sounds good
All set here! It worked. I have some other Stripe tasks still to finish, but at a good stage here. Thanks everyone so much for all of your help. ๐