#Matt1-PaymentIntent
1 messages · Page 1 of 1 (latest)
Hi, thanks!
I have a some PIs with bank issue.
When the payment was from a subscription the problem wasn't present but now with PIs yes. Eg:
pi_3LHxKXApMCw5clA306yBq6QE
pi_3LHxKbApMCw5clA313KqFKCI
Thanks. I can see that the transaction is declined with error code transaction_not_allowed, The customer needs to contact their card issuer for more information.
they contacted and said that the problem is mine
the weird thing is that previous transaction were successfull with same card
so I don't understand what I'm mistaken with PIs creation
can you understand something from PI logs?
I don't see a problem in your API calls, but the response we got from the card issurer is transaction_not_allowed
super weird
I keep not understanding why with subscriptions there wasn't this problem
Well, the card issuer has final say to approve or reject a transaction.
so you think there's nothing to do with some kind of flag during PI creation?
You are passing the correct params in the requests.
Do you ask your customer what exactly did their bank say?
yep, that our flow isn't compliant with the security standards
Hm, did they say which security standards and which flow?
well, I think that they are saying about the payment flow
and security standards stands for the 3ds
How did you collect the payment method? are you using SetupIntent or PaymentIntent API?
it depends. if the customer buy a plan with 7 trial days I collect it with setup intent otherwise payment intent
OK, do you set the setup_future_usage to off_session when using PaymentIntent?
it depends, I set it only if the user is on session
if is off session I set off_session: true
Did you pass a on_session paymentMethod for pi_3LHxKXApMCw5clA306yBq6QE
and pi_3LHxKbApMCw5clA313KqFKCI ?
how can I check it?
these are the request parameters:
{
"amount": "39700",
"customer": "cus_EzBLV7ndv5gauf",
"currency": "eur",
"payment_method": "card_1J8oGCApMCw5clA3Z8QGc0bV",
"confirm": "true",
"off_session": "true"
}
for the first one
and for the second one
{
"amount": "49700",
"customer": "cus_JmdK2oqWtu0QBC",
"currency": "eur",
"payment_method": "card_1J943oApMCw5clA3FKgnSqE0",
"confirm": "true",
"off_session": "true"
}
Ah, you are not using PaymentIntent/SetupIntent API to collect the payment method for card_1J8oGCApMCw5clA3Z8QGc0bV. You are still using the Tokens API.
Sign in to the Stripe Dashboard to manage business payments and operations in your account. Manage payments and refunds, respond to disputes and more.
Yes it is. You should use PaymentIntent/SetupIntent API which is SCA-ready https://stripe.com/docs/strong-customer-authentication
Sorry I should catch this problem earlier.
but I have stripe elements in my page
But your integration is using the Tokens API, you can check the log that I sent earlier
two questions:
1- what if I need to create a payment intent imemdiately? how I collect data?
2- what I need to create a payment intent from a card saved from tokens?
- You mean save the payment method from PaymentIntent? Set setup_future_usage to off_session
- Don't use token, use the PaymentMethod instead. You can use SetupIntent API (https://stripe.com/docs/payments/setup-intents) to collect a PaymentMethod
I don't really understand.
1- I have stripe elements to insert the card infos. How can I collect them immediately and create a PI?
2- I don't need to create a setup intent, I need to pay immediataly with an old card
the stripe documentation is so huge and different that I don't know which flow I need to take
this is my current situation.
I have a checkout form that collects card data.
I have two different plans, one with 7 days trial and one without.
If a customer select the trial plan I only need to collect the card data, for the other plan I need to collect data and pay immediately.
After 7 days, I have a recurring job that take the "trial plan" and transform it to an yearly plan creating a PI from the saved card.
With the same logic, after 365 days, the recurring job create another PI for the next year.
Before we had subscriptions, so a lot of users have the card data saved from token, so I need to charge them
Or you can share with me the code so we can walk through together?
this is the checkout form, is common for every plan
Can you share with me the API that you use in the checkout form that you built?
Don't worry about that.
So you are using stripe.createToken() to create a token and pass the token to your backend to create a PaymentIntent, am I right?
yes, payment intent or setup intent
Ok. sorry I need to take back my earlier comment, you integration is SCA-ready. I thought you are still using the Charge API.
ok thanks
so if I need to collect the customer data only I do this:
payment_method_id = ::Stripe::PaymentMethod.list({
customer: user.stripe_customer_id,
type: 'card'
}).data.first.id
setup_intent = ::Stripe::SetupIntent.create({
customer: user.stripe_customer_id,
payment_method_types: ['card'],
usage: 'off_session',
payment_method: payment_method_id
})
begin
::Stripe::SetupIntent.confirm(
setup_intent.id,
{ payment_method: payment_method_id }
)
rescue StandardError => e
end
of course earlier I do this:
stripe_customer = ::Stripe::Customer.create(
email: user.email,
description: user.full_name.to_s,
source: stripe_token
)
Wait, why are you passing a payment_method when creating a SetupIntent?
Complete reference documentation for the Stripe API. Includes code snippets and examples for our Python, Java, PHP, Node.js, Go, Ruby, and .NET libraries.
here is an optional param I can pass
Do you ever encounter a PaymentIntent/SetupIntent in status requires_action ?
payment_intent yes, setup_intent I don't know sincerely
To be honestly this is an unusual flow. Usually we collect PaymentMethod through SetupIntent instead of specifying one when creating a SetupIntent.
so, when I submit the checkout form (with the stripe_token) what do I need to do with it?
Can you use 4000002760003184 to test the setupIntent flow and see if the 3DS page is launched?
The usual flow is that the server side create SetupIntent/PaymentIntent, and pass the clientSecret to clientSide, then clientSide to call confirmPayment or confirmSetup, and 3DS flow will be triggered if necessary.
You are doing a server-side confirmation in your flow, so my concern is that your integration might not be able to handle the 3DS flow easily.
I'm creating a SI/PI later because maybe the customer can leave the checkout flow earlier and leave a SI/PI opened
I confirm that I'm not handling setup_intent 3ds, but later in the application if I find a PI with requires_actions I do this:
intent = Stripe::PaymentIntent.retrieve(intent_id)
if intent['status'] == 'requires_action'
return_url = subscribe_sca_success_url
intent = Stripe::PaymentIntent.confirm(
intent_id,
{
return_url: return_url
}
)
if intent && intent['next_action'] && intent['next_action']['redirect_to_url'] && intent['next_action']['redirect_to_url']['url']
to_url = intent['next_action']['redirect_to_url']['url']
redirect_to to_url
end
end
the first 300 setup_intents are all 'succeeded'
I don't really recommend to handle 3DS redirect URL in server side, you should use the Stripe.js to handle the requires_action at client side.
And I'll highly recommend to confirm the PaymentIntent/SetupIntent at client side so that your customer proceed with the 3DS flow.
I can't really confirm if your integration is SCA-ready as I need to do some tests based on the flow that you described, and my shift is ended so I'll hand over to my colleague to continue helping you. Alternatively you can also write in to us https://support.stripe.com/contact so that we can continue the discussion over email.
Find help and support for Stripe. Our support center provides answers on all types of situations, including account information, charges and refunds, and subscriptions information. Get your questions answered and find international support for Stripe.
Ok thanks, I just need to understand If I need to review all my flow and how to handle unfinished SI/PI.
thanks @visual mist
let me know when I can proceed with your colleague, thanks!
I've already informed him and he should join the thread soon.
it is really hard 😄 we chatted a lot with Jack.
I have a checkout form with stripe tokens
then, if I just need to collect customer data I do this:
stripe_customer = ::Stripe::Customer.create(
email: user.email,
description: user.full_name.to_s,
source: stripe_token
)
payment_method_id = ::Stripe::PaymentMethod.list({
customer: user.stripe_customer_id,
type: 'card'
}).data.first.id
setup_intent = ::Stripe::SetupIntent.create({
customer: user.stripe_customer_id,
payment_method_types: ['card'],
usage: 'off_session',
payment_method: payment_method_id
})
begin
::Stripe::SetupIntent.confirm(
setup_intent.id,
{ payment_method: payment_method_id }
)
rescue StandardError => e
end
otherwise If I need to pay immediately I create a PI with:
- setup_future_usage = 'off_session' if is the first time payment
- off_session: true if is my renew recurring job to create a PI
I'm not handling setup intent 3ds redirect (the last 400 SI are 'succeeded')
and the payment_intent 3ds is handles like this:
intent = Stripe::PaymentIntent.retrieve(intent_id)
if intent['status'] == 'requires_action'
return_url = subscribe_sca_success_url
intent = Stripe::PaymentIntent.confirm(
intent_id,
{
return_url: return_url
}
)
if intent && intent['next_action'] && intent['next_action']['redirect_to_url'] && intent['next_action']['redirect_to_url']['url']
to_url = intent['next_action']['redirect_to_url']['url']
redirect_to to_url
end
end
the thread started because I have this customer: cus_EzBLV7ndv5gauf that when we had subscriptions he was able to pay without any problema, but now with PIs the bank is blocking his payments
I'm creating SIs/PIs after the checkout submit so I can avoid that some SIs/PIs are left unfinished from customers that leave the checkout page
Thanks for the information!
now with PIs the bank is blocking his payments
Can you share some PaymentIntent that failed?
Thanks! Give me a few minutes to look into this.
of course, thank to you
pi_3LHxKXApMCw5clA306yBq6QE is a generic decline, not a developer or integration question so I can't help you with that . Nothing to do with your code.
same with pi_3LHxKbApMCw5clA313KqFKCI
https://stripe.com/docs/declines/codes
transaction_not_allowed The card was declined for an unknown reason. The customer needs to contact their card issuer for more information.
yes but if you see the customer had subscriptions in the past and everything worked
if you think your decline rate is unusual then contact https://support.stripe.com/?contact=true but this is never anything to do with your actual integration or code so it's not a developer support question for Discord
now with PI the bank is giving this error
any payment can be declined for any reason at any time really, that's how online payments work. Past success doesn't really mean anything
this chat is for developer/code/API questions, our support team are the experts on declines
Ok, so now I would like to continue the discussion about my integration
started with Jack
k, what's the question?
he told me that my integration is not fully correct and I need to change it
and then his shift terminated
your integration is fine, you just choose to not use our frontend libraries
I assume you have a reason for that
I don't know really, I found this flow from old developers
everything worked fine with subscriptions, but now with PI there's a lot of customers with issues
but you can use https://stripe.com/docs/payments/3d-secure#manual-redirect to manually redirect to 3D Secure instead of confirming the PaymentIntent client side with our libraries; which is what you're doing. As Jack said, confirming client side is the recommended integration — it's that you see documented on https://stripe.com/docs/payments/accept-a-payment for example. You went off the beaten path to use the manual 3D Secure redirect, which is fine and it's fully supported and documented and doesn't cause any issue
ok, so collecting data with tokens, create a SI/PI later passing the payment_method as params, redirecting manually on server is everything fine?
yes, it's not the default way to do it but lots of merchants integrate that way since it gives you more control over the overall flow and lets you see the card details before charging them and so on, it's totally normal
ok thanks, I wasn't able to understand this since everyone was recommending the frontend flow
one last thing
when I create the PI I'm trying to confirm it immediately, with confirm: true flag
is it correct to do this again? meaning confirm it again? or there is another api that I need to call?
return_url = subscribe_sca_success_url
intent = Stripe::PaymentIntent.confirm(
intent_id,
{
return_url: return_url
}
)
I don't see why you'd confirm it again
so this is maybe is causing some issues?
maybe! not aware of any specific reason it would though
but if I'm not confirming again how can I pass the return_url to the PI?
you pass it when calling PaymentIntent.create
https://stripe.com/docs/payments/3d-secure#manual-redirect
To redirect your customer to the 3DS authentication page, pass a return_url to the PaymentIntent when confirming on the server or on the client. You can also set return_url when creating the PaymentIntent.
ok nice, thanks!