#masudrhossain-cc-mandates
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, 5 hours ago, 37 messages
- masudrhossain, 1 day ago, 10 messages
Looks like you are using the 4000003800000446 test card which requires 3DS for any on-session payments like starting a Subscription
So you either want to pass off_session: true (https://stripe.com/docs/api/subscriptions/create#create_subscription-off_session) when you create the Subscription or you wan to use a different test card
So it should work fine if it's a single charge?
This card is already set up for off-session use. It requires authentication for one-time and other on-session payments. However, all off-session payments succeed as if the card has been previously set up.
but isn't this the 3DS verification?
Yes that's from the SetupIntent
You could also call confirmPayment() client-side using the PaymentIntent's client_secret to handle 3DS for the PaymentIntent
Let's back up a second.
If i'm doing the SetupIntent do i need to do PaymentIntent's too? I thought it was either or
What are you trying to simulate here?
Is the customer on-session when you create this Subscription?
And are you trying to collect a new card or used a previously saved PaymentMethod?
We had an issue with an indian connect customer who was testing with an indian card. and they got an error for 3DS. So i added SetupIntent to show the 3DS popup to confirm it. And so I'm using these cards to test that 3DS.
And the connect customer was testing with an indian for a subscription (but he also has single charge plans too, so we need it to work with either type)
Okay well that's a whole different thing.
Indian cardholders have their own requirements. We document this here: https://stripe.com/docs/india-recurring-payments
I'm able to successfully collect a new card and save it to the customers profile. But it seems i cannot use the params[:paymentMethodId] to create a subscriptino or single charge payment on the backend. params[:paymentMethodId]
So if you are attempting to set up a PaymentMethod for an Indian cardholder then you need to pass through the necessary payment_method_options parameters as shown in the above doc
You said PaymentMethod, did you meant PaymentIntent?
No, you use a SetupIntent to setup a PaymentMethod for future use
You can also setup the PaymentMethod when you charge it initially by certain parameters on the PaymentIntent as well
It really depends on what you are trying to do.
So I'll ask again whether the customer is on-session in this case and whether you are trying to charge them using a new card or a saved card?
Stripe.api_key = 'REMOVED'
Stripe::SetupIntent.create({
payment_method_types: ['card'],
payment_method_options: {
card: {
# Add specific options for the card here if needed
# For example, to request a 3D Secure authentication
request_three_d_secure: 'any'
}
}
})
like this?
This is specifically for an Indian cardholder?
I'm not sure what on-session means.
But to answer your 2nd question, the saved card.
On-session means the customer is in your checkout flow at that moment.
Oh, then yes. the customer is
Okay and you are trying to charge a card they had already saved in the past?
Yes
Okay how did you originally save that card?
Like really at that point you shouldn't need to do anything but create/confirm the PaymentIntent or Subscription. 3DS shouldn't need to be completed again -- it should already have been handled in the original setup.
Stripe elements, submit form with reactjs
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
stripe.confirmCardSetup(setupIntentClientSecret, {
payment_method: {
card: cardElement
},
})
.then(function(result) {
if (result.error) {
// Handle error (e.g., display an error message to the user)
console.error(result.error.message);
} else {
// Handle success (e.g., redirect to a success page or perform additional actions)
// You can access the SetupIntent using result.setupIntent
console.log("SetupIntent confirmed successfully:", result.setupIntent);
axios.post(`/api/o/${service.organization.token}/services/${match.params.service_id}/service_checkouts`, {
paymentMethodId: result.setupIntent.payment_method,
name,
email,
address,
price_id: price,
coupon_code: coupon_code,
intent_due_amount: amount_due,
selected_addons: selectedAddons,
project_id: new URLSearchParams(new URL(window.location.href).search).get('project_id'),
project_service_checkout_id: new URLSearchParams(new URL(window.location.href).search).get('psc'),
new: true,
referral_code: referralCode
})
.then(function(response){
console.log(response);
if(response.data.success){
notice("Checkout successful");
history.push(`/portal/o/${service.organization.token}/projects/${response.data.project_id}/tasks?show_task=true`);
notice("You can now add a task")
} else {
setDisabled(false)
}
})
.catch(function(error){
console.log(error)
notice("An error occured");
setDisabled(false)
})
.then(function () {
setDisabled(false);
});
setIsLoading(false);
}
})
.catch(function(error) {
// Handle any unexpected errors
console.error(error);
});
};
I created a SetupIntent like this and passed that in to the form
@setup_intent = Stripe::SetupIntent.create(
payment_method_types: ['card'],
usage: 'off_session' # Set to 'off_session' for recurring payments
)
When user submits the form on the frontend, i do this on the backend>
# Create a customer with the payment method
customer = Stripe::Customer.create(
email: current_user.email,
name: current_user.username
)
# Attach the payment method to the customers profile
payment_method = Stripe::PaymentMethod.attach(
params[:paymentMethodId],
{customer: customer.id},
)
# Make the payment_method the default for the customer
Stripe::Customer.update(customer.id,
{
invoice_settings: {
default_payment_method: params[:paymentMethodId]
},
},
)
and then i try to charge it like this if it's a subscription
subscription = Stripe::Subscription.create({
customer: customer.id, # Replace with the actual customer ID
items: [
{ price: params[:price_id] }
],
coupon: stripe_coupon,
metadata: {
service_id: @service_price.token
},
expand: ['latest_invoice.payment_intent'],
description: "#{@service.title} -#{@service_price.token}",
application_fee_percent: affiliate_application_fee_percent
})
Okay let's pause for a second
First, you don't need to do # Attach the payment method to the customers profile payment_method = Stripe::PaymentMethod.attach( params[:paymentMethodId], {customer: customer.id}, ) at all
You should create the Customer when you create the SetupIntent
Right, users have 2 ways to submit a payment.
Add a new card or use a saved card that's default payment on their Customer profile.
The saved way of course doesn't ask for 3DS (but still fails in charging the card).
And pass the Customer ID to the SetupIntent: https://stripe.com/docs/api/setup_intents/create#create_setup_intent-customer
Then the PaymentMethod will be automatically attached to the Customer upon successful confirmation on your frontend and you reduce the number of API requests you are making.
Yeah, I can make this change. Since i don't have to do setupintent when they reuse a card. so i'l only do the setupintent when it's a new customer adding a card.
Yes that's correct.
Now let's pause again
Are you specifically working on handling an Indian customer?
No, any customer that stripe supports.
Only person that had this issue was 1 indian connect account.
(we're a platform that lets people create customizable checkout forms for their service business)
Okay well if you are going to support Indian users then you do need to implement the proper parameters to create Mandates when necessary. Those are documented here: https://stripe.com/docs/india-recurring-payments?integration=paymentIntents-setupIntents#create-mandate
So you want to add those parameters to your SetupIntent creation request
So that a India Mandate is created when it is required for Indian customers/accounts.
Is this mandate required for indian CONNECT ACCOUNTS or indian card users (ie customer)?
Pause and read the doc above end to end
Because i'm curious if this issue will arise if an indian person uses their card with a usa account
Hi 👋
I'm stepping in as my colleague needs to go. The documentation provided extends to Customers in India as well.
Does stripe have a way of automatically knowing if it's an indian card or is that up to me?
No that is up to you.
Okay so i did this to setup the mandate
@setup_intent = Stripe::SetupIntent.create({
customer: @customer.stripe_customer,
usage: 'off_session',
payment_method_types: ['card'],
payment_method_options: {
card: {
mandate_options: {
reference: '{{REFERENCE}}',
description: '{{DESCRIPTION}}',
amount: 2000000,
currency: 'inr',
start_date: 1675238400,
amount_type: 'maximum',
interval: 'month',
interval_count: 1,
supported_types: ['india'],
},
},
},
})
Which gave me the client_secret which i then used in
stripe.confirmCardSetup(setupIntentClientSecret, {
payment_method: {
card: cardElement
},
})
And then i submitted a charge for $100 USD and i got this again
am i suppose to use PaymentIntent instead of SetupIntent? I thought it was one or the other.
Can you share an API request ID for this message? It will start with req_
Here's how you can find a request ID: https://support.stripe.com/questions/finding-the-id-for-an-api-request
Wait wait wait
What do you mean
And then i submitted a charge for $100 USD and i got this again
Setup Intents are used to save payment methods for future use. They do not collect funds
I think you need to read this https://stripe.com/docs/payments/save-and-reuse for Setup Intents and this https://stripe.com/docs/payments/accept-a-payment for Payment Intents carefully to understand the differences
Right and i was trying to make a charge using that payment method.
So if you are trying to make a charge, you need to use a PaymentIntent
so paymentintent for single charges and setupintent for recurring charges
No
You need to read the documents we provide thoroughly
Setup Intent creates a Payment Method and attaches it to a Customer
It does not charge funds, ever
Oh yeah, I know that
That's what i used it for
So i added a payment method to a customer.
which showed up correclty
Okay, so if you are going to charge the customer using that payment method then you need to use a Payment Intent
fingers crossed this resolves it.
good lord, it finally worked.
all i had to do was use PaymentIntent and not SetupIntent.
Do you guys have a list of countries that have these weird requirements?
Also, what's the point of having these if the charges goes through regardless of these amount and start_date
Please read the docs. All of this is explained completely in our docs