1

I have implemented Stripe in my project to test the payments , but even after the payment is successful with the test card , the payment dashboard in Stripe show the payment status as incomplete but when i go visit the url inside stripejs in the event log details, the authentication is done and the payment status show success, but i want my code to do that automatically and without my intervention. my code are - backend-

const express = require("express");
const router = express.Router();
const Booking = require("../models/booking");
const Room = require("../models/room");
const moment = require("moment");
const { v4: uuidv4 } = require("uuid");
const stripe = require("stripe")(
"stripe key"
);

router.post("/bookroom", async (req, res) =\> {
const {
room,
userid,
roomid,
frommonth,
tomonth,
totalmonths,
totalamount,
token,
} = req.body;

try {
const customer = await stripe.customers.create({
email: token.email,
source: token.id,
});

    const paymentIntent = await stripe.paymentIntents.create({
      amount: totalamount * 100,
      currency: "INR",
      customer: customer.id,
      receipt_email: token.email,
      payment_method: token.card.id,
      confirm: true,
    });
    
    if (paymentIntent.status === "requires_action") {
      const { use_stripe_sdk } = paymentIntent;
      if (use_stripe_sdk && use_stripe_sdk.type === "three_d_secure_redirect") {
        // Inform the user that the payment requires 3D Secure authentication
        return res.status(200).json({
          error: "Payment requires 3D Secure authentication",
          clientSecret: paymentIntent.client_secret,
        });
      }
    }
    
    const newBooking = new Booking({
      room: room.name,
      roomid,
      userid,
      frommonth: moment(frommonth, "MMMM YYYY").format("DD-MM-YYYY"),
      tomonth: moment(tomonth, "MMMM YYYY").format("DD-MM-YYYY"),
      totalmonths,
      totalamount,
      transactionId: "1234",
      token,
    });
    
    const booking = await newBooking.save();
    
    const roomtemp = await Room.findOne({ _id: roomid });
    
    roomtemp.currentbookings.push({
      bookingid: booking._id,
      fromdate: moment(frommonth).format("DD-MM-YYYY"),
      todate: moment(tomonth).format("DD-MM-YYYY"),
      userid: userid,
      status: booking.status,
    });
    
    await roomtemp.save();
    
    return res.send("Payment Successful, Your Room is Booked");

} catch (error) {
return res.status(400).json({ error: error.message });
}
});

module.exports = router;

and my frontend -

import React, { useState, useEffect } from "react";
import axios from "axios";
import { useParams } from "react-router-dom";
import Loader from "../components/Loader";
import Error from "../components/Error";
import moment from "moment";
import StripeCheckout from "react-stripe-checkout";

function Bookingscreen() {
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);
const [room, setRoom] = useState({});
const { roomid, frommonth, tomonth } = useParams();

const fromDate = moment(frommonth, "MMMM YYYY"); // Convert frommonth to a moment object
const toDate = moment(tomonth, "MMMM YYYY"); // Convert tomonth to a moment object
const totalmonths = toDate.diff(fromDate, "months");
const totalamount = totalmonths * room.rentpermonth;

useEffect(() => {
const fetchRoomData = async () => {
try {
setLoading(true);
const response = await axios.get(`/api/rooms/getroomsbyid/${roomid}`);
setRoom(response.data);
setLoading(false);
} catch (error) {
setError(true);
setLoading(false);
}
};

    fetchRoomData();

}, [roomid]);

async function onToken(token) {
console.log(token);
const bookingDetails = {
room,
userid: JSON.parse(localStorage.getItem("currentUser"))._id,
roomid, // Add roomid here
frommonth,
tomonth,
totalmonths,
totalamount,
token,
};

    try {
      const result = await axios.post("/api/bookings/bookroom", bookingDetails);
      console.log(result);
    } catch (error) {
      console.log(error);
    }

}

return (
<div>
{loading ? (
<Loader/>
) : room ? (
<div className="m-5">
<div className="row justify-content-center mt-5 bsw">
<div className="col-md-6">

<h1>{room.name}</h1>
<img />


            <div className="col-md-6">
              <div style={{ textAlign: "right" }}>
                <h1>Booking Details</h1>
                <hr>
                <b>
                  <p>
                    Name: {JSON.parse(localStorage.getItem("currentUser")).name}{" "}
                  </p>
                  <p>Size: {room.size} </p>
                  <p>Location: {room.location} </p>
                  <p>From Month : {frommonth}</p>
                  <p>To Month :{tomonth}</p>
                </b>
              </div>
    
              <div style={{ textAlign: "right" }}>
                <b>
                  <h1>Amount</h1>
                  <hr>
                  <p>No of Months : {totalmonths} </p>
                  <p>Rent Per Month : {room.rentpermonth} </p>
                  <p>Total Amount : {totalamount}</p>
                </b>
              </div>
    
              <div style={{ float: "right" }}>
                <StripeCheckout
                  amount={totalamount * 100}
                  token={onToken}
                  currency="INR"
                  stripeKey="stripekey"
                >
                  <button className="btn btn-primary">Pay Now</button>
                </StripeCheckout>
              </div>
            </div>
          </div>
        </div>
      ) : (
        <Error />
      )}
    </div>

);
}

export default Bookingscreen;

i expect my code to work properly so that my payment status in stripe show succeeded instead of incomplete. and i have removed the key and replaced it with stripekey

pranab
  • 11
  • 3
  • when you retrieve that specific PaymentIntent, what's it's [status](https://stripe.com/docs/api/payment_intents/object#payment_intent_object-status)? – alex May 29 '23 at 00:17

0 Answers0