995 viewsMern Amazona
0 Comments

Is there any way to implement Stripe Checkout into the shopping cart we built in your “React Shopping Cart for Absolute Beginners” video? Excellent video, by the way!T.

Bassir Changed status to publish November 26, 2023

hello there,

in backend:

npm i stripe

then create stripeRouter.js like this:

/* eslint-disable camelcase */
import Stripe from 'stripe';
import express from 'express';
import config from '../config.js';
import Order from '../models/orderModel.js';

const stripe = Stripe(config.STRIPE_SECRET_KEY);

const stripeRouter = express.Router();
stripeRouter.get('/secret/:id', async (req, res) => {
  const order = await Order.findById(req.params.id).populate(
    'user',
    '_id name email'
  );
  const paymentIntent = await stripe.paymentIntents.create({
    amount: order.totalPrice * 100,
    currency: 'usd',
    // Verify your integration in this guide by including this parameter
    metadata: { integration_check: 'accept_a_payment' },
  });
  res.send({ order, client_secret: paymentIntent.client_secret });
});

stripeRouter.get('/key', (req, res) => {
  res.send(config.STRIPE_PUBLISHABLE_KEY);
});

export default stripeRouter;

and add to the routes in server.js

import stripeRouter from './routers/stripeRouters.js';
...

app.use('/api/stripe', stripeRouter);

and set env variable in .env:

STRIPE_SECRET_KEY=sk_xxx
STRIPE_PUBLISHABLE_KEY=pk_xxx

get them from stripe.com

in frontend install

 npm i @stripe/react-stripe-js @stripe/stripe-js

and create this component:

import React, { useState } from 'react';
import {
  useStripe,
  useElements,
  CardElement,
  Elements,
} from '@stripe/react-stripe-js';
import { Button } from 'react-bootstrap';
import Axios from 'axios';

function CheckoutForm(props) {
  const [processing, setProcessing] = useState(false);
  const stripe = useStripe();
  const elements = useElements();

  const handleSubmit = async (event) => {
    // We don't want to let default form submission happen here,
    // which would refresh the page.
    event.preventDefault();

    if (!stripe || !elements) {
      // Stripe.js has not yet loaded.
      // Make sure to disable form submission until Stripe.js has loaded.
      return;
    }
    setProcessing(true);
    const { data } = await Axios(`/api/stripe/secret/${props.orderId}`);
    const clientSecret = data.client_secret;
    // Call stripe.confirmCardPayment() with the client secret.

    const result = await stripe.confirmCardPayment(clientSecret, {
      payment_method: {
        card: elements.getElement(CardElement),
        billing_details: {
          name: data.order.user.name,
          email: data.order.user.email,
        },
      },
    });

    if (result.error) {
      // Show error to your customer (e.g., insufficient funds)
      console.log(result.error.message);
      alert(result.error.message);
    } else {
      // The payment has been processed!
      if (result.paymentIntent.status === 'succeeded') {
        props.handleSuccessPayment(result.paymentIntent);
        console.log(result.paymentIntent);
        // alert(result.paymentIntent.status);
      }
    }
    setProcessing(false);
  };

  return (
    <form onSubmit={handleSubmit}>
      <CardElement />

      <Button
        type="submit"
        className="btn-block"
        disabled={!stripe || processing}
      >
        Pay With Stripe
      </Button>
    </form>
  );
}

const StripeCheckout = (props) => (
  <Elements stripe={props.stripe}>
    <CheckoutForm
      orderId={props.orderId}
      handleSuccessPayment={props.handleSuccessPayment}
    />
  </Elements>
);
export default StripeCheckout;

then use it in OrderScreen.js

import { loadStripe } from '@stripe/stripe-js/pure';
import StripeCheckout from '../components/StripeCheckout';

in useEffect:

const [stripe, setStripe] = useState(null);
useEffect(() => {
    const addStripeScript = async () => {
      const { data: clientId } = await axios.get('/api/stripe/key');
      const stripeObj = await loadStripe(clientId);
      setStripe(stripeObj);
    };
    if (order.paymentMethod === 'stripe') {
        if (!stripe) {
          addStripeScript();
        }

in the return part:

{!order.isPaid && !stripe && <LoadingBox />}
                  {!order.isPaid && stripe && (
                    <StripeCheckout
                      stripe={stripe}
                      orderId={order._id}
                      handleSuccessPayment={handleSuccessPayment}
                    />
                  )}
Bassir Answered question October 25, 2022

hello there,

it doesn’t have backend. for handling payment you need backed. take mern courses please. link in the header menu > courses

Bassir Answered question October 14, 2022