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