#vm1172

1 messages · Page 1 of 1 (latest)

tropic geodeBOT
empty moss
#

Hi there

#

So you are successfully hitting your backend endpoint and creating the Checkout Session but then seeing this error?

velvet otter
#

Hi! I can hit my backend endpoint to create a checkout session but I'm having trouble retrieving the information after a successful payment and the redirect

#

Hi!

sharing my code for get-checkout-session.ts here

import Stripe from 'stripe';
import { NextApiRequest, NextApiResponse } from 'next';
import { STRIPE_SECRET_KEY } from '../../routes/constant';

const stripe = new Stripe(STRIPE_SECRET_KEY, {
  // https://github.com/stripe/stripe-node#configuration
  apiVersion: '2022-11-15',
});

export interface GetCheckoutSessionBody {
  session_id: string;
}

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse,
) {
  try {
    const { session_id }: GetCheckoutSessionBody = req.body;
    const session = await stripe.checkout.sessions.retrieve(session_id);
    if (!session) {
      res.status(404).json({ statusCode: 404, message: 'Session not found' });
      return;
    } else {
      res.status(200).json(session);
    }
  } catch (err) {
    if (err.code !== 'resource_missing') {
      const errorMessage =
        err instanceof Error ? err.message : 'Internal server error';
      res.status(500).json({ statusCode: 500, message: errorMessage });
      return;
    }
  }
}

empty moss
#

Ah okay

#

So first thing is that I'd recommend relying on webhooks for this info

#

Is there a reason you are retrieving based on the redirect as opposed to using webhooks?

velvet otter
#

My success_url is set up like the documentation suggests

success_url: `${WEBSITE_URL}${PageNames.Summary}?session_id={CHECKOUT_SESSION_ID}`,

im facing issues with this Stripe endpoint

const session = await stripe.checkout.sessions.retrieve(sessi
on_id);
empty moss
#

Okay. Overall I'd recommend reading through https://stripe.com/docs/payments/checkout/fulfill-orders and implementing webhooks. This is important as it allows you to catch sessions where the customer closes the window before actually hitting the redirect or if they lose network connection during that time.

Learn how to fulfill orders after a customer pays with Stripe Checkout or Stripe Payment Links.

velvet otter
empty moss
#

But happy to help with the above in the meantime.

velvet otter
#

I'll go through it thank you.

empty moss
#

Are you fetching your backend endpoint right now?

#

If you are, a fetch request expects a response

#

So if you don't respond to that frontend request you will see the error that you are currently experiencing

velvet otter
#

im calling it from the client like this

    const sessionId = router.query.session_id as string;
    const body: GetCheckoutSessionBody = {
      session_id: sessionId,
    };
    const session = await fetchPostJSON('/api/get-checkout-session', body);
    const metadata: StripeMetadata = session.metadata;
// ...
empty moss
#

So you need to either respond with something to let the frontend know it was successful. Or you use something like a form submit on the frontend where a response isn't expected.

velvet otter
#

the odd thing is it works the first and second time (I can retrieve data and see the session response) and then stalls

empty moss
#

Yeah the issue is in the frontend here and its expectation that it will receive a response. Try adding something simple like

    if (session) {
      res.status(200)
      }```
velvet otter
#

gotcha. let me try that out

#

tried changing it like you suggested

    const session = await stripe.checkout.sessions.retrieve(session_id);
    if (session) {
      res.status(200).json(session);
    } else {
      res.status(404).json({ statusCode: 404, message: 'Session not found' });
    }

still pending

empty moss
#

Can you show me how you are fetching on your frontend?

velvet otter
empty moss
#

Ah sorry missed that

#

Can you add a log after const session = await fetchPostJSON('/api/get-checkout-session', body);
to log out session

velvet otter
#

I cannot log anything since the request ends up stalling...

API resolved without sending a response for /api/get-checkout-session, this may result in stalled requests.
empty moss
#

Yeah wanted to ensure that log wasn't firing at all

#

So now in your backend let's add a log in your if (session) block

#

Also since you are using fetchPostJSON you may need to respond with a JSON object

#

Instead of just a status

velvet otter
#

One more thing. If I end up commenting out everything and just

res.status(200).json({ hello: 'world' });
it works

empty moss
#

Yep so that is what I said above

velvet otter
#

So now in your backend let's add a log in your if (session) block
nothing shows up in the logs

empty moss
#

It is expecting JSON object

velvet otter
#

isnt session a JSON object?

empty moss
#

You are responding with session

#

Like you could do that, but no reason really to send the whole session object back to your frontend

velvet otter
#

switched to this

    const { session_id }: GetCheckoutSessionBody = req.body;
    const session = await stripe.checkout.sessions.retrieve(session_id);
    if (session) {
      console.log(session);
      res.status(200).json({ metadata: session.metadata });
    } else {
      res.status(404).json({ statusCode: 404, message: 'Session not found' });
    }

still stalling for me

#

nothing logs out either

empty moss
#

Okay so then the issue is in the initialization of your session variable

#

So you want to log out your req.body

velvet otter
#

sure one second.

#

I can see the session_id in the Request Payload in the Network tab though

tropic geodeBOT
velvet otter
#

when I comment out everything and just do
res.json({ req: req.body });

it returns with the session_id

empty moss
#

Okay and if you log out session below const session = await stripe.checkout.sessions.retrieve(session_id); does it log the full Checkout Session object?

#

(log it prior to your if statement)

velvet otter
#

no, as soon as I call the stripe.checkout.session.retrieve function it stalls

empty moss
#

Alrighty great

#

So last log then is for session_id

#

Right above that retrieve

velvet otter
#

it logs my checkout_session_id

#

but only if stripe.checkout.session.retrieve() is commented out. if i add it back in it stalls again

empty moss
#

hmmm very weird

velvet otter
#

im pretty sure im passing in the data correctly

empty moss
#

Let's hard code the Session ID in

velvet otter
#

into the stripe function

empty moss
#

Instead of using the variable

velvet otter
#

okay one sec

#

good idea

empty moss
#

This sounds like some funky Next.JS thing to me. I'm really not familiar with Next.JS at all tbh

velvet otter
#
    const { session_id }: GetCheckoutSessionBody = req.body;
    console.log(session_id);
    const session = await stripe.checkout.sessions.retrieve(
      'cs_test_ABC_XYZ',
    );
    if (session) {
      console.log(session);
      res.status(200).json({ metadata: session.metadata });
    } else {
      res.status(404).json({ statusCode: 404, message: 'Session not found' });
    }

when using this...

session_id from req.body and the hardcoded value inside the stripe SDK are both the same and get logged out.

but I still get the error

API resolved without sending a response for /api/get-checkout-session, this may result in stalled requests.

empty moss
#

So yeah this sounds like something specific to Next.JS endpoints

#

Try using res.end() like in that SO?

velvet otter
#

sounds like it.. since I can get the data directly from cURL..

    const { session_id }: GetCheckoutSessionBody = req.body;
    const session = await stripe.checkout.sessions.retrieve(session_id);
    if (session) {
      console.log(session);
      res.end(JSON.stringify(session, null, 2));
    }

i tried with and without the session if condition, still stalling

#

im just surprised stripe.checkout.sessions.create works so well and retrieve stalls

empty moss
#

Can you show me the whole endpoint code again?

velvet otter
#

yeah one second

#

its really not much lol

import Stripe from 'stripe';
import { NextApiRequest, NextApiResponse } from 'next';
import { STRIPE_SECRET_KEY } from '../../routes/constant';

const stripe = new Stripe(STRIPE_SECRET_KEY, {
  apiVersion: '2022-11-15',
});

export interface GetCheckoutSessionBody {
  session_id: string;
}

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse,
) {
  try {
    const { session_id }: GetCheckoutSessionBody = req.body;
    const session = await stripe.checkout.sessions.retrieve(session_id);
    if (session) {
      console.log(session);
      res.end(JSON.stringify(session, null, 2));
    }
  } catch (err) {
    if (err.code !== 'resource_missing') {
      const errorMessage =
        err instanceof Error ? err.message : 'Internal server error';
      res.status(500).json({ statusCode: 500, message: errorMessage });
      return;
    }
  }
}
empty moss
#

Yeah I'm pretty stumped unfortunately.

#

Trying to think of other things to try but I don't understand what Next.JS is expecting out of the GET request here

velvet otter
#

damn

empty moss
#

Can you add a breakpoint at your const session = await stripe.checkout.sessions.retrieve(session_id); line?

#

And see if it is actually entering that block at all

velvet otter
#

yeah hold on one second

#

it seems to be working now

#

this is so strange haha, no code change from my side

empty moss
#

Dang we probably should have just done a turn off/turn on earlier to see if it was just cached

velvet otter
#

that could have been it, was too deep into the weeds

#

ill keep running with multiple tests and flag if i face any more issues

#

my fix was to drop the stripe SDK and directly create a fetch request via the cURL API

#

I could also have possibly been using an old sessionId which wasn't mapping to a checkout session

empty moss
#

Hmm you definitely shouldn't need to cURL directly here

#

But I hear ya

#

Let us know if you run into further issues