#Matt11-PI

1 messages ยท Page 1 of 1 (latest)

vagrant zinc
#

๐Ÿ‘‹ happy to help

#

could you please provide the PI's id?

warm mountain
#

Hello!

#

of course pi_3LDbcHApMCw5clA31mqPheW2

#

can I try to explain my current logic?

vagrant zinc
#

yes sure

warm mountain
#
  1. we have an automatic script that look for out expired subscriptions and creates a payment_intent for renew them.
    I create id with ruby apis like this:
payment_intent = ::Stripe::PaymentIntent.create({
                                                          amount: amount,
                                                          customer: user.stripe_customer_id,
                                                          currency: 'eur',
                                                          payment_method_types: ['card'],
                                                          setup_future_usage: 'off_session',
                                                          payment_method: payment_method_id
                                                        })
#
  1. after that I try to confirm it like this
::Stripe::PaymentIntent.confirm(
            payment_intent.id,
            { payment_method: payment_method_id }
          )
vagrant zinc
#

ok

warm mountain
#
  1. when I land on my platform I check if the subscription is in 3DS status and do this:
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

I try to confirm it with a return_url

#

but it seems that the customer entered an infinite loop looking the payment_intent log on Stripe dashboard

#

do you understand what I'm doing wrong?

blissful beacon
#

Hey, taking over here

we have an automatic script that look for out expired subscriptions and creates a payment_intent for renew them.
This sounds non conventional. What's an 'expired' subscription?

warm mountain
#

I have a database table named 'subscriptions' where we write internal subscriptions with from/to dates. An expired subscription is a row with today greater than "to" field

#

So my 'subscriptions' are nothing to do with Stripe subscriptions. It is only a custom way to manage internal subscriptions. And for every renewal we create one-shot payment intents.
So you need to think that our automatic script, check if there is a database row with "to"<"today" and create a payment_intent with an amount.

blissful beacon
#

Why are you doing server-side confirmation?

#

You should just instead bring your customer back on-session and use confirmPayment from Stripe.js

#

They will likely need to do that anyway, so the server-side method is pointless in this case

warm mountain
#

I'm doing it because the automatic script is doing all the work.
Don't know how to bring the customer back on-session and confirm it from Stripe.js

#

Is it possible to fix this and do it in the server side way?
Do I need to confirm it with the redirect_url already in the first attempt?

blissful beacon
#

You will need to bring your user on-session to complete the 3DS flow (if requested), regardless of whether you confirm server-side or nor

#

This is way it's best to just use confirmPayment with Stripe.js โ€“ you pass it the PI client_secret and it handles the rest

warm mountain
#

how I achieve this procedure?

#

I don't know how

#

So I create the payment_intent server-side and it's in 'requires_confirmation' status, is correct?

blissful beacon
#

Yep, or you can pass confirm: true if you're passing a payment_method too

warm mountain
#

this is my api call

        payment_intent = ::Stripe::PaymentIntent.create({
                                                          amount: amount,
                                                          customer: user.stripe_customer_id,
                                                          currency: 'eur',
                                                          payment_method_types: ['card'],
                                                          setup_future_usage: 'off_session',
                                                          payment_method: payment_method_id
                                                        })
blissful beacon
blissful beacon
warm mountain
#

so the confirm:true flag is equal to do this?

::Stripe::PaymentIntent.confirm(
            payment_intent.id,
            { payment_method: payment_method_id }
          )
blissful beacon
#

Yep

warm mountain
#

and if there's not difference why I cannot keep "my version"?

blissful beacon
#

At that point, depending on the card used, the PI status will either be requires_action, succeeded or requires_payment_method

blissful beacon
#

Because a good portion of these payments are going to require 3DS/auth from the user

warm mountain
#

I pass you a customer on Stripe, is mine I just tried

#

cus_LveVg1CAg4lQF9

#

I did the current logic, so created a payment_intent and confirmed server-side

#

so the pi_3LDnKvApMCw5clA31WHU0bCF went to requires_action

#

and this is what happend on the platform

#

redirect to home page,
redirect to 3ds page
confirmed payment
and later insufficient funds

#

so I don't understand why this worked (pi_3LDnKvApMCw5clA31WHU0bCF is mine) and this one don't (pi_3LDbcHApMCw5clA31mqPheW2 another customer)

#

the only difference I see is that mine is like this:

"next_action": {
    "type": "use_stripe_sdk",
    "use_stripe_sdk": {
      "type": "three_d_secure_redirect",
    }
}
#

and the customer's one is like this:

"next_action": {
    "type": "use_stripe_sdk",
    "use_stripe_sdk": {
      "type": "stripe_3ds2_fingerprint",
    }
}
blissful beacon
#

Yep, this is why you should use Stripe.js instead of handling the next action yourself!

#

In this case its a 3DS2 biometric auth (i.e. FaceID, TouchID or similar)

#

Which I guess your integration can't handle because you're not using Stripe.js

warm mountain
#

so when I land on my platform I need to redirect the customer to a custom page with Stripe.js?

blissful beacon
warm mountain
blissful beacon
#

As you're not using Payment Element and have an existing pm_xxx object

warm mountain
#

ok thanks! but into the page what I need to put? the html I mean

#

to let Stripe build the page with JS

blissful beacon
#

Well this is the thing, if requires_action you're gonna need to bring your user back to a page in order for them to complete the 3DS auth

#

So you'll need to build that page/UI

#

btw, if you were using Billing we take care of a lot of this

warm mountain
#

so for example a page with a button, anche the action of that button is:

stripe
  .confirmCardPayment('{PAYMENT_INTENT_CLIENT_SECRET}', {
    payment_method: '{PAYMENT_METHOD_ID}',
  })
  .then(function(result) {
    // Handle result.error or result.paymentIntent
  });

?

blissful beacon
#

Yup ๐Ÿ˜„

warm mountain
#

Billing is the subscriptions logic from Stripe?

blissful beacon
#

Yep, exactly

warm mountain
#

we just moved away from this ๐Ÿ˜„

blissful beacon
#

Oh, how come?

warm mountain
#

because we have multiple gateways in our application so we don't want to have customer data all over them,

#

we have everything on our database and the make a single payment when needed

#

So with confirmCardPayment I don't need to do something like:

var stripe = Stripe('#{Rails.configuration.stripe[:publishable_key]}');
var elements = stripe.elements();
var card = elements.create('card', {style: style});
card.mount('#card-element');

?

#

to get a stripe form

blissful beacon
#

Yes, you'll need to initialise Stripe.js but you don't need an Elements instance no (as you already have the pm_xxx object)

#

If you wanted the user to provide new payment details then you'd need a Card Element yes

warm mountain
#

ok nice

#

I'm gonna try

#

can you keep this channel open please?

blissful beacon
#

Sure, my colleague @limpid zenith is taking over now โ€“ they can answer any follow-ups!

warm mountain
#

last question

#

how can handle the redirect_url?

blissful beacon
#

How do you mean?

warm mountain
#

If the 3ds is successfull I need to redirect the user to another URL

blissful beacon
#

You'd do that in your promise chain:

stripe
  .confirmCardPayment('{PAYMENT_INTENT_CLIENT_SECRET}', {
    payment_method: '{PAYMENT_METHOD_ID}',
  })
  .then(function(result) {
    if (result.paymentIntent) window.location.assign(redirect)
  });
warm mountain
#

oh ok thanks a lot!! ๐Ÿ™‚

rigid horizon
#

Hi @warm mountain ๐Ÿ‘‹ re-opened

warm mountain
#

Hi thanks!

#

I'd like to ask about the PAYMENT_INTENT_CLIENT_SECRET

#

I'm passing the pi_ but it tells me that is wrong. What I'm I missing?

soft orbit
#

What is the exact error that you are getting here?

#

Does it have the format pi_1234 or pi_1234_secret_5678?

warm mountain
#

pi_xyz

#

how can i get pi_1234_secret_5678?

soft orbit