#masudrhossain
1 messages · Page 1 of 1 (latest)
Hello! We'll be with you shortly. Below are links to other discussions we've had with you in the past week in case you want to review that information. If your question is related to one of these previous discussions, please provide a comprehensive summary of the current state and what you need help with now. We help many users simultaneously, so a summary allows us to resolve your issue as soon as possible.
- masudrhossain, 22 hours ago, 10 messages
Hi there
hey
Can you provide the PaymentIntent ID that you are testing with?
I'm not using it with a paymentintent, instead of using it to save a card to a Customer profile as their default payment method.
Ah so SetupIntent then
Basically when the user submits the card on the frontend, my backend does this
# Create a customer with the payment method
customer = Stripe::Customer.create(
email: current_user.email,
payment_method: params[:paymentMethodId],
invoice_settings: {
default_payment_method: params[:paymentMethodId]
},
metadata: {
name: current_user.username
}
)
That is irrelevant to actually tokenizing the PaymentMethod and attaching it to the Customer.
That has to be done before what you are doing above.
And you should be using a SetupIntent to do that.
I don't think i'm doing setupintent either.
i'm just doing
import { CardElement, useStripe, useElements } from '@stripe/react-stripe-js';
<Elements stripe={stripePromise} options={options}>
<form onSubmit={handleSubmit}>
<CardElement options={{ style: { base: { fontSize: '16px' } } }} />
</form>
</Elements>
And on submit it'l do a post
Okay well that is why you aren't seeing 3DS most likely
What does your handleSubmit() function do?
It just calls createPaymentMethod I assume?
const handleSubmit = async (e) => {
e.preventDefault();
setDisabled(true)
if (!stripe || !elements) {
return;
}
setIsLoading(true);
const cardElement = elements.getElement(CardElement);
// Create a Payment Method using the Card Element
const { error, paymentMethod } = await stripe.createPaymentMethod({
type: 'card',
card: cardElement,
});
if (error) {
console.error(error);
setIsLoading(false);
return;
}
axios.post(`/api/o/${service.organization.token}/services/${match.params.service_id}/service_checkouts`, {
paymentMethodId: paymentMethod.id,
name,
email,
})
.then(function(response){
console.log(response);
if(response.data.success){
notice("Checkout successful");
} else {
setDisabled(false)
}
})
.catch(function(error){
console.log(error)
notice("An error occured");
setDisabled(false)
})
.then(function () {
setDisabled(false);
});
setIsLoading(false);
};
yes, and then i save that paymentmethod id to database for that customer.
You need to use a SetupIntent here as I noted.
Instead of calling createPaymentMethod() you call confirmCardSetup()
That will both create the PaymentMethod and handle 3DS
And it will attach the PaymentMethod to the Customer (if you passed the Customer ID when you create the SetupIntent on your backend)
Here is the frontend method you want to use: https://stripe.com/docs/js/setup_intents/confirm_card_setup
Oh okay so setupintet is required to use confirmCardSetup?
setup_intent = Stripe::SetupIntent.create(
payment_method_types: ['card'],
customer: customer.id, # Replace with the actual customer ID
setup_future_usage: 'off_session' # Set to 'off_session' for recurring payments
)
And prior to that, you create a SeupIntent via your backend: https://stripe.com/docs/api/setup_intents/create and pass the client_secret to your frontend.
Yep you need a client_secret to use confirmCardSetup()
Does setupintent work regardless if i'm doing a subscription or single product charge for my users future transacations?
So it's strictly a better way to handle saving a payment method to a customers profile and that's it?
Yep
appreciate it
Sure
Got everything to work 
But one final question. for usage: 'off_session', what if the Customer also wants to use that same payment method for recurring OR single charges?
setup_intent = Stripe::SetupIntent.create(
payment_method_types: ['card'],
customer: customer.id, # Replace with the actual customer ID
usage: 'off_session' # Set to 'off_session' for recurring payments
)
That is totally fine