#madcat-paymentintent-clientside

1 messages ยท Page 1 of 1 (latest)

lyric gladeBOT
pastel drum
#

Hello! The client secret does allow some access to the Payment Intent and associated information, but the way you've described your implementation concerns me. Do you have a Webhook Endpoint set up to listen for payment events which you use to trigger fulfillment?

jolly bobcat
#

for context, I'm using Deno Fresh with Preact which has very little to no documentation on how to make this work. I tried to check for payment status before redirecting to success but I could not figure it out at all so what I decide to do was to create an api route that checks the payment status from the success page and once the status was confirmed, then I would update the db

pastel drum
#

I'm not familiar with Deno Fresh or Preact. What I'm concerned about is a scenario where you get paid but you don't perform your fulfillment steps. For example, let's say someone on a train is using your site/app and starts to pay. They get a 3D Secure challenge. They authenticate that challenge. Then the train goes into a tunnel and they lose their connection before the rest of your client-side code can run. The money moved when they completed 3D Secure, so you got paid, but it sounds like you wouldn't be fulfilling their oder (making the DB entries and whatnot).

jolly bobcat
pastel drum
#

That's just an example. There are a ton of other scenarios where this kind of thing happens, like someone's device running out of battery, the code crashing, network errors, all kinds of things.

#

I can't review a large amount of code like that.

#

Can you tell me if you're setting up a Webhook Endpoint to listen for payment Events and using that to trigger fulfillment?

jolly bobcat
#

I'm not sure I understand your question ๐Ÿ˜”

pastel drum
#

Let's back up a bit. What are you trying to build at a high level?

jolly bobcat
#

so, I have a checkout page with an order and a total, I use that total to make a payment intent to stripe. Once the payment details are submitted, on the stripe provided form, I use the stripe.confirmPayment function to submit the payment (I think) which redirects to the success route once finished

    const handleSubmit = async () => {
        payment.loading.value = true;
        const { error } = await window.stripe.confirmPayment({
            elements: window.stripeElements,
            confirmParams: {
                return_url: `${location.origin}/payment-success`,
            },
        });
        if( error.type === 'card_error' || error.code === 'payment_intent_authentication_failure') { payment.message.value = error.message! }
        else { payment.message.value = "An unexpected error occured" }
        payment.loading.value = false;
    }

What I was trying to do initially, was to check for the status as soon as the confirmation came in but I could not figure it out at all. No matter what I tried, I could not retrieve the status before getting redirected so the only option I thought of was to check for the payment status once the success page was loaded

fallow hawk
#

madcat-paymentintent-clientside

#

No matter what I tried, I could not retrieve the status before getting redirected
yes that's entirely expected, the status change happens during the redirect

#

so when you hit your return url, there, server-side, you check the status

jolly bobcat
#

I tried checking if there was no error, using the redirect: 'if_required', calling stripe.retrievePaymentIntent before confirming and nothing seemed to work

fallow hawk
#

I'm sorry that's all super abstract. Like you can't say "nothing seems to work" without a lot more specific details

#

Just handle the success after the redirect, that's the right way to integrate

jolly bobcat
#

but the Rubeus said I shouldn't do that because of like someone's device running out of battery, the code crashing, network errors, all kinds of things

fallow hawk
#

I mean the same exact thing would happen even if you checked the status client side

#

they could lose battery right at that time. For that you have to use webhooks for async reconciliation

jolly bobcat
#

is there a way for me to fire my updateDB function right before the redirect?

fallow hawk
#

it doesn't really make sense to want to do that

#

you can never trust client-side code

#

Do that as part of the redirect that's all. At that point they hit your server and there with server-side code you check the status and update your database

jolly bobcat
#

so I get the confirmation to know it has been paid from confirmPayment and I also update the db with the order

fallow hawk
#

confirmPayment() is client-side code. It can't be trusted. The customer get redirected to your return url and there you check

jolly bobcat
#

With the chance that I'm gonna sound like a broken record. Is this ok to do, once the success page was loaded?

    const payStatus = useSignal('');
    useEffect(() => {
        const clientSecret = new URLSearchParams(window.location.search).get('payment_intent_client_secret');
        const retrieveStripe = async () => {
            const stripe = await loadStripe(pubKey);
            if(stripe) { window.stripe = stripe }
            if(IS_BROWSER && clientSecret) {
                const { paymentIntent, error } = await window.stripe.retrievePaymentIntent(clientSecret);
                payStatus.value = ((paymentIntent?.status) as string);
                if(!error && payStatus.value === 'succeeded') {
                    updateDB();
                }
            }
        }
        retrieveStripe();
    }, []);
    const updateDB = async() => {
        const basketData = new Array<any>();
        for(let i = 0; i < lengthStorage(); i++){ const item = JSON.parse(getStorage(keyStorage(i))); basketData.push(item) }
        const res = await fetch('/api/stripe_success', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(basketData) })
        const data = await res.json();
        console.log(data);
        if(data.error) { console.log(data.error.json()) }
        else { for(let i = 0; i < lengthStorage() + 1; i++){  removeStorage(keyStorage(i)) }}
    }
fallow hawk
#

once the success page was loaded?
it doesn't make sense to do that

#

sorry I am not sure what words to use ti explain this differently

#

that hits your server. So your server-side code can already look at the PaymentIntent and then update your database before you respond

jolly bobcat
#

I understand

fallow hawk
#

ah cool. So really before you render the success/error on that return URL, you basically check the state, record the details in your DB, etc. and then say "yay success"

#

and that code can crash so you also listen to the payment_intent.succeeded event and you make sure that also updates your DB if it wasn't updated yet

jolly bobcat
#

I might come back with questions later because now I have to test stuff out again but thank you for this. It was very helpful

fallow hawk
#

happy to help!

jolly bobcat
#

also, just a little feedback. Two YouTube video's on Deno, without a single mention of how to use Stripe Elements with Fresh is not as helpful as it seems ๐Ÿ˜… . It's a good start, but at least one video would be helpful

fallow hawk
#

I've never heard of Fresh and what this is ๐Ÿ˜…

#

unfortunately there are thousands of stacks so it's hard to cover them all, but I'll share the feedback!

jolly bobcat
#

Fresh to Deno is like React to Nodejs. It was created by the Deno team as their default framework https://fresh.deno.dev/

fallow hawk
#

yeah see, that wording is perfect. Tons of people use Node.js and not React

jolly bobcat
#

to be fair, on Deno we have 3 supported frameworks at best. So making a tutorial on the default, kind of makes sense to me. You know, just saying. I'm more than happy to make one myself once I'm 100% sure that I'm doing the correct thing and I get someone from here to review my code if they want

fallow hawk
#

We wouldn't really be able to review your code. Sorry our help is a lot more transactional about problems/issues. I wouldn't feel comfortable vetting anyone's code myself. I've never used Deno and likely won't. But I will flag to the people who did the Deno videos!

jolly bobcat
#

sounds good

#

thanks again!

fallow hawk
#

If you do make a tutorial/example though let us know

#

we have a process to track those and we put some in our monthly developers digest we send to a lot of users

#

it's not my team but we can pass it along ๐Ÿ™‚

jolly bobcat
#

I would want someone to make sure I'm spreading the correct information, but videos can be remade

#

time to test!