zerakot
zerakot

Reputation: 93

Sending a response after a finalized transaction - Stripe

After a long discussion with ChatGPT, I managed to write code that redirects the user to the Stripe payment page and then captures an event when the transaction is successfully completed. The problem is that my fetch request has already received a response from the /checkout endpoint and is not waiting for a response from /webhook. And I would like my API to return a properly generated response after successfully finalizing the transaction. What am I doing wrong?

First, I send a request to the /checkout endpoint, which takes care of generating the payment link and sending it back:

fetch('http://localhost:3001/checkout', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
    },
    body: JSON.stringify({
        items: [
            {
                id: 0,
            },
        ],
    }),
})
    .then((res) => {
        if (res.ok) return res.json();
        return res.json().then((e) => console.error(e));
    })
    .then(({url}) => {
        console.log(url);
        window.location = url;
    })
    .catch((e) => {
        console.log(e);
    });

This code when I press the button redirects me to the Stripe payment page.

Endpoint /checkout:

app.post('/checkout', async (req, res) => {
  try {
      const session = await stripe.checkout.sessions.create({
          payment_method_types: ['card'],
          line_items: req.body.items.map(({id}) => {
              const storeItem = storeItems.get(id);
              return {
                  price_data: {
                      currency: 'pln',
                      product_data: {
                          name: storeItem.name,
                      },
                      unit_amount: storeItem.priceInCents,
                  },
                  quantity: 1,
              };
          }),
          mode: 'payment',
          success_url: `${process.env.CLIENT_URL}/success.html`,
          cancel_url: `${process.env.CLIENT_URL}/cancel.html`,
      });
      console.log(session.url);
      res.json({url: session.url});
  } catch (e) {
      // If there is an error send it to the client
      console.log(e.message);
      res.status(500).json({error: e.message});
  }
});

I connected StripeCLI to my server using stripe listen --forward-to localhost:3001/webhook. Now I can capture the successful transaction event using the /webhook endpoint, but I have no way to return The transaction was successful to the client:

app.post('/webhook', (req, res) => {
  const event = req.body;

  if (event.type === 'checkout.session.completed') {
      res.send('The transaction was successful');
  }
});

Upvotes: 2

Views: 1048

Answers (2)

Marty
Marty

Reputation: 140

After the suceesful payment the customer should be redirected back to your website. Where you can create success page.

success_url: `${process.env.CLIENT_URL}/success.html`,

If you want to get some data back from the Strapi after the paymant is successful page you can add this

success_url: `${process.env.CLIENT_URL}/success.html?&session_id={CHECKOUT_SESSION_ID}`

At the succes page you just deconstruct the data. And do whatever you want with them :)

If you deconstruct the object for example like this: (Next.js)

const stripe = require("stripe")(`${process.env.STRIPE_SECRET_KEY}`);

export async function getServerSideProps(params) {
  const order = await stripe.checkout.sessions.retrieve(
    params.query.session_id,
    {
      expand: ["line_items"],
    },
  );
  const shippingRate = await stripe.shippingRates.retrieve(
    "shr_1MJv",
  );

  return { props: { order, shippingRate } };
}


export default function Success({ order, shippingRate }) {
  const route = useRouter();

Yo can log out the whole object to see whats inside

console.log(order);

If the payment was sucessfull you should get in prop variable: payment_status: "paid"

Upvotes: 1

NeNaD
NeNaD

Reputation: 20334

Stripe will automatically redirect the client to the success_url that you specified when you created a Stripe session.

You can use the webhook for saving the order in the database for example, but not to redirect the client.

Upvotes: 0

Related Questions