#Matt1-PaymentIntent

1 messages · Page 1 of 1 (latest)

visual mist
#

Hi there, how can I help?

white lichen
#

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

visual mist
#

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.

white lichen
#

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?

visual mist
#

I don't see a problem in your API calls, but the response we got from the card issurer is transaction_not_allowed

white lichen
#

super weird

#

I keep not understanding why with subscriptions there wasn't this problem

visual mist
#

Well, the card issuer has final say to approve or reject a transaction.

white lichen
#

so you think there's nothing to do with some kind of flag during PI creation?

visual mist
#

You are passing the correct params in the requests.

#

Do you ask your customer what exactly did their bank say?

white lichen
#

yep, that our flow isn't compliant with the security standards

visual mist
#

Hm, did they say which security standards and which flow?

white lichen
#

well, I think that they are saying about the payment flow

#

and security standards stands for the 3ds

visual mist
#

How did you collect the payment method? are you using SetupIntent or PaymentIntent API?

white lichen
#

it depends. if the customer buy a plan with 7 trial days I collect it with setup intent otherwise payment intent

visual mist
#

OK, do you set the setup_future_usage to off_session when using PaymentIntent?

white lichen
#

it depends, I set it only if the user is on session

#

if is off session I set off_session: true

visual mist
#

Did you pass a on_session paymentMethod for pi_3LHxKXApMCw5clA306yBq6QE
and pi_3LHxKbApMCw5clA313KqFKCI ?

white lichen
#

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"
}
visual mist
#

Ah, you are not using PaymentIntent/SetupIntent API to collect the payment method for card_1J8oGCApMCw5clA3Z8QGc0bV. You are still using the Tokens API.

white lichen
#

why are you saying "still using"?

#

is this a problem?

visual mist
#

Sorry I should catch this problem earlier.

white lichen
#

but I have stripe elements in my page

visual mist
#

But your integration is using the Tokens API, you can check the log that I sent earlier

white lichen
#

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?

visual mist
white lichen
#

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
visual mist
#

Or you can share with me the code so we can walk through together?

white lichen
#

this is the checkout form, is common for every plan

visual mist
#

Can you share with me the API that you use in the checkout form that you built?

white lichen
#

sorry it didn't send me the file

visual mist
#

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?

white lichen
#

yes, payment intent or setup intent

visual mist
#

Ok. sorry I need to take back my earlier comment, you integration is SCA-ready. I thought you are still using the Charge API.

white lichen
#

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
          )
visual mist
#

Wait, why are you passing a payment_method when creating a SetupIntent?

white lichen
#

here is an optional param I can pass

visual mist
#

Do you ever encounter a PaymentIntent/SetupIntent in status requires_action ?

white lichen
#

payment_intent yes, setup_intent I don't know sincerely

visual mist
#

To be honestly this is an unusual flow. Usually we collect PaymentMethod through SetupIntent instead of specifying one when creating a SetupIntent.

white lichen
#

so, when I submit the checkout form (with the stripe_token) what do I need to do with it?

visual mist
#

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.

white lichen
#

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'

visual mist
#

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.

white lichen
#

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!

visual mist
#

I've already informed him and he should join the thread soon.

brittle citrus
#

Hi! I'm taking over this thread.

#

Could you try to summarize your question?

white lichen
#

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

brittle citrus
#

Thanks for the information!

now with PIs the bank is blocking his payments
Can you share some PaymentIntent that failed?

white lichen
#

of course

#

pi_3LHxKXApMCw5clA306yBq6QE
pi_3LHxKbApMCw5clA313KqFKCI

brittle citrus
#

Thanks! Give me a few minutes to look into this.

white lichen
#

of course, thank to you

void tiger
#

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

white lichen
#

yes but if you see the customer had subscriptions in the past and everything worked

void tiger
#

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

white lichen
#

now with PI the bank is giving this error

void tiger
#

this chat is for developer/code/API questions, our support team are the experts on declines

white lichen
#

Ok, so now I would like to continue the discussion about my integration

#

started with Jack

void tiger
#

k, what's the question?

white lichen
#

he told me that my integration is not fully correct and I need to change it

#

and then his shift terminated

void tiger
#

your integration is fine, you just choose to not use our frontend libraries

#

I assume you have a reason for that

white lichen
#

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

void tiger
#

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

white lichen
#

ok, so collecting data with tokens, create a SI/PI later passing the payment_method as params, redirecting manually on server is everything fine?

void tiger
#

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

white lichen
#

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
          }
        )
void tiger
#

I don't see why you'd confirm it again

white lichen
#

so this is maybe is causing some issues?

void tiger
#

maybe! not aware of any specific reason it would though

white lichen
#

but if I'm not confirming again how can I pass the return_url to the PI?

void tiger
#

you pass it when calling PaymentIntent.create

white lichen
#

ok nice, thanks!