Im trying to integrate stripe payment using axios with node.js but at the end Im getting back an error message: Request failed with status code 500, although in the request payload I do see a token data filled properly.
here is my node.js code:
const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
const path = require("path");
if (process.env.NODE_ENV !== "production") require("dotenv").config();
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);
const app = express();
const port = process.env.PORT || 5000;
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());
if (process.env.NODE_ENV === "production") {
app.use(express.static(path.join(__dirname, "client/build")));
app.get("*", function (req, res) {
res.sendFile(path.join(__dirname, "client/build", "index.html"));
});
}
app.listen(port, (error) => {
if (error) throw error;
console.log("Server running on port " + port);
});
app.post("/payment", (req, res) => {
const body = {
source: req.body.token.id,
amount: req.body.amount,
currency: "eur",
};
stripe.charges.create(body, (stripeErr, stripeRes) => {
if (stripeErr) {
res.status(500).send({ error: stripeErr });
} else {
res.status(200).send({ success: stripeRes });
}
});
});
and here is my client side code using axios library and stripe-checkout pre-built component
const priceForStripe = price * 100;
const publishableKey = "pk_test_i28ouERO9Dli1OlxDdGM7HFA00hCEjnkrw";
const onToken = (token) => {
axios({
url: "/payment",
method: "POST",
headers: { "content-type": "application/json" },
data:{
amount: priceForStripe,
token,
},
})
.then((response) => {
alert("Payment was successfull !!");
})
.catch((error) => {
console.log("Payment error:", error);
alert("There was an issue with your payment");
});
};
return (
<StripeCheckout
label="PAY NOW"
name="Shibukas&Co"
billingAddress
shippingAddress
image="https://sendeyo.com/up/d/f3eb2117da"
description={`Your total price is €${price}`}
amount={priceForStripe}
panelLabel="Pay Now"
token={onToken}
stripeKey={publishableKey}
/>
);
};```
Related
I am currently learning how to use the fetch api for my front-end. I continue to get the XHR 404 POST error.
//Backend file
const express = require("express");
const app = express();
require("dotenv");
const Port = process.env.PORT || 5000;
app.use(express.static("public"));
app.use(express.json());
app.use(
express.urlencoded({
extended: false,
})
);
const nodemailer = require("nodemailer");
const Mail = require("nodemailer/lib/mailer");
require("nodemailer-mailgun-transport");
app.use(express.json());
app.get("/", (req, res) => {
res.sendFile("/public");
res.sendFile("/public/js/mail.js");
});
app.listen(Port, (req, res) => {
console.log(`listening on port ${Port}`);
});
app.post("/email"),
(req, res) => {
FromMailjs = req.body;
console.log(FromMailjs);
const transporter = nodemailer.createTransport({
auth: {
user: process.env.Email,
pass: process.env.Pass,
},
});
const MailOptions = {
from: req.body.Email,
to: process.env.MyEmail,
text: `${req.body.FirstName}, ${req.body.LastName}
, ${req.body.PhoneNumber}, ${req.body.Email}`,
};
transporter.sendMail(MailOptions, (error, info) => {
if (error) {
console.log(error);
res.send("error");
} else {
console.log("Email sent");
res.send("success");
}
});
};
//Frontend file
const ContactForm = document.querySelector(".contact-form");
ContactForm.addEventListener("submit", (e) => {
e.preventDefault();
let FirstName = document.getElementById("Fname");
let LastName = document.getElementById("Lname");
let PhoneNumber = document.getElementById("PhoneNumber");
let Email = document.getElementById("Email");
const FormData = {
FirstName: FirstName.value,
LastName: LastName.value,
PhoneNumber: PhoneNumber.value,
Email: Email.value,
};
const PostOptions = {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(FormData),
};
console.log(FormData);
fetch("/email", PostOptions);
});
XHRPOSThttp://localhost:5000/email
[HTTP/1.1 404 Not Found 27ms]
I have tried changing the routes hoping that it was just a routing issue and I still get the same error. I was using XHR before fetch and I got the same 404 error. My front-end is receiving the correct information but I can't get my backend to receive the information.
You have a typo. Please use:
app.post("/email", (req, res) => {
Instead of:
app.post("/email"),
(req, res) => {
I'm not getting any response from postman due to this error. I tried to add app.use(express.json()); in index.js but still not working. Any idea on how to solve this?
const stripeAPI = require('../stripe');
async function createCheckoutsession(res, req) {
const domainUrl = process.env.WEB_APP_URL;
const { line_items, customer_email } = req.body;
if (!line_items || !customer_email) {
return res.status(400).json({ error: 'missing required session paramaters' });
}
let session;
try {
session = await stripeAPI.checkout.sessions.create({
payment_method_types: ['card'],
mode: 'payment',
line_items,
customer_email,
success_url: `${domainUrl}/success?session_id={CHECKOUT_SESSION_ID}`,
cancel_url: `${domainUrl}/canceled`,
shipping_address_collection: { allowed_countries: ['GB', 'US'] }
});
res.status(200).json({ sessionId: session.id, });
} catch (error) {
console.log(error);
res.status(400).json({ error: 'an error occurred, unable to create session' });
}
}
module.exports = createCheckoutsession;
(index.js)
const express = require('express');
const cors = require('cors');
require('dotenv').config({ path: './.env' });
const createCheckoutSession = require('./api//checkout');
const app = express();
const port = 8080;
app.use(express.json());
app.use(cors({origin: true}));
app.get('/', (req, res) => res.send('HELLO WORLD!'));
app.post('/create-checkout-session', createCheckoutSession);
app.listen(port, () => console.log('server listening on port', port));
(stripe.js)
const stripeAPI = require('stripe')(process.env.SECRET_KEY);
module.exports = stripeAPI;enter code here
I assume you are using Express server?
Your route handler is using wrong parameters:
// Wrong
async function createCheckoutsession(res, req) {
}
// Correct
async function createCheckoutsession(req, res) {
}
Try
app.use(bodyParser.urlEncoded({extended:false}))
I've been trying to get something to send to my shoutbox_endpoint, but on the Express.JS Backend where the endpoint is it returns req.body as undefined
Post Request
const headers = {
"SMN-Auth-JWT": " REDACTED "
};
axios.post(this.endpoint_shoutbox, {
headers: headers,
data: {
user: who,
message: message,
}
}).then(function (response) {
console.log(response);
}).catch(function (error) {
console.log(error);
});
Backend Endpoint
router.post('/shoutbox-relay', async (req, res) => {
console.log(req.params); // {}
console.log(req.query); // {}
console.log(req.body); // Undefined
});
Main.js
const Logger = require("./LogHandler");
const config = require("../Settings/conf.json");
const Path = require("path");
const ExpressJS = require("express");
const Router = require("./RouterHandler");
const bodyParser = require('body-parser');
const app = ExpressJS();
module.exports.start = async (client) => {
try {
app.set("view engine", "ejs");
app.use("/assets", ExpressJS.static(Path.join(__dirname, "../Website/assets")));
app.use("/socket.io", ExpressJS.static(Path.join(__dirname, "../Website/assets/socket.io")));
app.set("views", Path.join(__dirname, "../Website/views"));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.disable("x-powered-by");
app.use(function (req, res, next) {
req.bot = client;
next();
});
app.use("/", Router.index);
app.use("/about", Router.about);
app.use("/chat", Router.chat);
app.use(function (req, res, next) {
var err = new Error("File Not Found");
err.status = 404;
next();
});
const Listener = http.listen(config.Website.port, function () {
Logger.log("Website Handler", "Webserver Started.");
});
} catch (err) {
Logger.error("Website Handler", `Webserver failed to load due to: ${err}`);
}
};
One observation is that, DATA on the client-side JavaScript isn't JSON-stringified. And I would prefer mentioning contentType: 'application/json'
Here is a sample at my end, that's working well with pretty much your configuration.
Client-side JS:
function saveBankDetails() {
someDetails = { bankDetails: {
someKey1: "SOME VALUE 1,
someKey2: "SOME VALUE 2"
}
}
$.ajax({
url: ("SOME PATH"),
method: 'POST',
data: JSON.stringify(someDetails),
contentType: 'application/json'
})
.done(function(data, textStatus, jXhr) {
console.log(data);
})
.fail(function(jXhr) {
console.log('failure')
console.log(jXhr)
});
}
Server-side code:
router.post('SOME PATH', async (req, res) {
console.log(req.body.bankDetails)
});
Output:
{
someKey1: "SOME VALUE 1,
someKey2: "SOME VALUE 2"
}
Im building an express instance for the first time and ive run into an issue where everything works locally, but when deployed sending a post request to the route responds:
Failed to load resource: the server responded with a status of 405
(Not Allowed)
Ive included the relevant code below:
server/index.js
const express = require('express');
const bodyParser = require('body-parser')
const path = require('path');
const app = express();
app.use(express.static(path.join(__dirname, 'build')));
const routes = require('./routes')(express)
require('./db')
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
app.get('/', function (req, res) {
res.sendFile(path.join(__dirname, 'build', 'index.html'));
});
app.listen(process.env.PORT || 8080);
app.use('/', routes);
routes/index.js
var mongoose = require("mongoose");
const randomId = require('random-id');
const Submissions = require('../api/Submissions')
// routes/index.js
module.exports = (express) => {
// Create express Router
var router = express.Router();
// add routes
router.route('/submission')
.post((req, res) => {
let newSubmission = new Submissions(req.body);
newSubmission._id = randomId(17, 'aA0');
// Save the new model instance, passing a callback
newSubmission.save(function(err,response) {
if (err) {
console.log(err)
} else {
res.setHeader('Content-Type', 'application/json');
res.json({'success':true})
}
// saved!
})
});
return router;
}
client.js
let submission = {
name: this.state.newSubmission.name.trim(),
body: this.state.newSubmission.body.trim(),
email: this.state.newSubmission.email.trim(),
};
const requestOptions = {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(submission),
};
fetch("/submission", requestOptions)
.then((response) =>
response.json().then((data) => ({
data: data,
status: response.status,
}))
)
.then((res) => {
if (!res.data.success) {
notifier.warning('Failed to submit');
} else {
notifier.success('Submission successful');
}
});
I'm using the MERN stack to build an application for the first time.
In order to log HTTP requests I use "morgan".
I managed to send data to mongodb which seems to be working fine. The problem is that my post request is not coming through. It says "pending" for 4 minutes, then fails.
Here's what I think is the relevant part of my code:
"server.js":
const express = require("express");
const mongoose = require("mongoose");
const morgan = require("morgan");
const path = require("path");
const cors = require("cors");
const app = express();
const PORT = process.env.PORT || 8080;
const routes = require("./routes/api");
const MONGODB_URI =
"...";
mongoose.connect(MONGODB_URI || "mongodb://localhost/app", {
useNewUrlParser: true,
useUnifiedTopology: true
});
mongoose.connection.on("connected", () => {
console.log("Mongoose is connected.");
});
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cors());
app.use(morgan("tiny"));
app.use("/api", routes);
app.listen(PORT, console.log(`Server is starting at ${PORT}`));
Then I've put my routes into another file "api.js":
const express = require("express");
const router = express.Router();
const Lane = require("../models/lanes");
router.get("/", (req, res) => {
Lane.find({})
.then(data => {
res.json(data);
console.log("Get request successful!");
})
.catch(error => {
console.log("Error: ", error);
});
});
router.post("/save", (req, res) => {
const data = req.body;
const newLane = new Lane();
newLane.collection.insertMany(data, err => {
if (err) {
console.log(err);
} else {
console.log("Multiple docs inserted");
}
});
});
module.exports = router;
I'm using axios to send the request. This happens after submitting a form within my application.
reducer function:
const reducer = (state, action) => {
switch (action.type) {
case "add":
axios({
url: "http://localhost:8080/api/save",
method: "POST",
data: [...state, { id: uuid(), title: action.title, tasks: [] }]
})
.then(() => {
console.log("Data has been sent to the server");
})
.catch(() => {
console.log("Internal server error");
});
return [...state, { id: uuid(), title: action.title, tasks: [] }];
The reducer is being used by my context provider component, which looks like this:
export function LanesProvider(props) {
const [lanes, dispatch] = useReducer(reducer, defaultLanes);
return (
<LanesContext.Provider value={lanes}>
<DispatchContext.Provider value={dispatch}>
{props.children}
</DispatchContext.Provider>
</LanesContext.Provider>
);
}
The "add" method inside my reducer is being called when submitting a form inside another component.
Please let me know if I can add anything to my question that would help.
Thank you in advance!
you are not sending any response back to client. Try to modify post method like
router.post("/save", (req, res) => {
const data = req.body;
const newLane = new Lane();
newLane.collection.insertMany(data, err => {
if (err) {
console.log(err);
res.send(err)
} else {
console.log("Multiple docs inserted");
res.send("Multiple docs inserted")
}
});
});