Why is the response (payment Intent) after completing the payment undefined? - node.js

myReactApp/functions/index.js
const functions = require("firebase-functions");
const express = require("express");
const cors = require("cors");
const stripe = require('stripe')
('sk_test_**********');
// API
// App config
const app = express();
// Middlewares
app.use( cors({origin:true}) );
app.use(express.json());
// API routes
app.get('/', (request, respond) => respond.status(200).send("page is working") );
app.post('/payment/create', async (request, response) => {
const total = request.query.total;//get the value of total from URL using query
console.log('payment request recived >>>' , total);
const paymentIntent = await stripe.paymentIntents.create({
amount: total,
currency: 'USD'
})
response.status(201).send({
clientSecret : paymentIntent.client_secret,
})
})
//http://localhost:5001/clone-21937/us-central1/api
// Listen command
exports.api = functions.https.onRequest(app);
myReactApp/src/payment.js
import React, { useEffect, useState } from 'react';
import Orders from './Orders';
import CheckoutProduct from './CheckoutProduct';
import CurrencyFormat from 'react-currency-format';
import { CardElement, useElements, useStripe } from '#stripe/react-stripe-js';
import { collection, addDoc, setDoc } from 'firebase/firestore/lite'
import { Link, useNavigate } from 'react-router-dom';
import { useStateValue } from './StateProvider';
import { db } from './firebase';
import axios from './axios';
const Payment = () => {
const stripe = useStripe();
const elements = useElements();
const navigate = useNavigate();
const [{ basket, subtotal, user }, dispatch] = useStateValue();
const [succeeded, setSucceeded] = useState(false);
const [processing, setProcessing] = useState('');
const [error, setError] = useState(null);
const [disabled, setDisabled] = useState(true);
const [clientSecret, setClientSecret] = useState(true);
useEffect(() => {
const getClientSecret = async () => {
const response = await axios({
method: 'POST',
url: `/payment/create?total=${subtotal * 100}`
});
//clientSecret is the amount to be paid
//fetching the clientSecret send from response (Index.js)
setClientSecret(response.data.clientSecret);
}
getClientSecret();
}, [basket]);
//handle submitting the form
const handleSubmit = async (event) => {
event.preventDefault();
setProcessing(true);
const payload = await stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: elements.getElement(CardElement)
}
}).then( ({paymentIntent}) => {
console.log(paymentIntent);//undefined
try {
addDoc(
collection(db,'users', user?.uid, 'orders'),{
basket:basket
}
)
}
catch (error) {
alert(error.message);
}
//empty the basket after order
dispatch({
type: 'EMPTY_BASKET'
})
setSucceeded(true);
setProcessing(false);
setError(null);
// navigate('/orders');
})
}
const handleChange = (event) => {
setDisabled(event.empty);
setError(event.error ? event.error.message : '');
}
return (
<div className="payment_sectionTransaction">
<form onSubmit={handleSubmit}>
<CardElement className='payment_cardElement' onChange={handleChange}/>
<CurrencyFormat
value={subtotal}
prefix={'$'}
decimalScale={2}
thousandSeparator={true}
displayType={'text'}
renderText={(value) => {
return <>
<p><strong>Amount: {value}</strong></p>
</>
}} />
<button type='submit' disabled={processing || succeeded || disabled} >
{processing ? 'Processing..' : 'Confirm Order'}
</button>
</form>
</div>
)
}
export default Payment
After payment I am trying to get the response-paymentIntent but it shows to be undefined.
I can see the payment in the stripe dashboard so may be payment sections is all good but response after the payment is not good.
I also get this error in console after payment get done:
POST http://localhost:5001/clone-21937/us-central1/api/payment/create?total=0 net::ERR_FAILED 200

getClientSecret is async function. You must write code look like
const result = await getClientSecret();

Related

Cookies doesn't show up in my application ReactJS

Hello i'm trying to code auth for my app i'm using json web token the problem is when i send post request using postman i can see the cookie and access token in headers but in my application i can't see anything in my localstorage&cookies
Here is my code
authContext.js
import axios from "axios";
import { createContext, useEffect, useState } from "react";
export const AuthContext = createContext();
export const AuthContextProvider = ({ children }) => {
const [currentUser, setCurrentUser] = useState(
JSON.parse(localStorage.getItem("user")) || null
);
const login = async (inputs) => {
const res = await axios.post("http://localhost:8800/api/auth/login", inputs, {
withCredentials: true,
});
setCurrentUser(res.data)
};
useEffect(() => {
localStorage.setItem("user", JSON.stringify(currentUser));
console.log(currentUser);
}, [currentUser]);
return (
<AuthContext.Provider value={{ currentUser, login }}>
{children}
</AuthContext.Provider>
);
};
in login.jsx
const [inputs, setInputs] = useState({
username: "",
password: "",
});
const [err, setErr] = useState(null);
const navigate = useNavigate()
const handleChange = (e) => {
setInputs((prev) => ({ ...prev, [e.target.name]: e.target.value }));
};
const login = useContext(AuthContext);
const handleLogin = async (e) => {
e.preventDefault();
try {
await login(inputs);
navigate("/")
} catch (err) {
setErr(err.response.data);
}
};
console.log(err);
console.log(inputs);
I'm trying to solve the problem because i'm trying to create a basic social app i need accessToken to display posts in my feed easily

React+Node webpage - Update endpoint throws 404 error

I have setup a webpage to search a number via user input and if it's available in the SQL Server database, 2 text boxes would show up with the data using AXIOS GET endpoint. Then I'm trying to get those ID's of the data rows and if the user needs to UPDATE it, then UPDATE it via AXIOS PUT endpoint. The issue is once user clicks the UPDATE button it throws an error PUT http://localhost:5000/api/customerOrder/[object%20Object],[object%20Object] 404 (Not Found)
Here's what I've tried
Server endpoints :
dboperations.js
var config = require('./dbconfig');
const sql = require('mssql');
async function getallcustomerOrders(){
try{
let pool = await sql.connect(config);
let orders = await pool.request()
.query("SELECT * FROM [100].[dbo].[OELINCMT_SQL] order by ID desc");
return orders.recordsets;
}
catch (error){
console.log(error);
}
}
async function getcustomerOrders(orderNumber){
try{
let pool = await sql.connect(config);
let orders = await pool.request()
.input('input_parameter', sql.NChar, orderNumber)
.query("SELECT ID,cmt FROM [100].[dbo].[OELINCMT_SQL] where LTRIM(ord_no) = LTRIM(#input_parameter)");
return orders.recordsets;
}
catch (error){
console.log(error);
}
}
async function updateComments(ID){
try {
let pool = await sql.connect(config);
let orders = await pool.request()
.input('ID', sql.NChar, ID)
.query(`SELECT ID,cmt FROM [100].[dbo].[OELINCMT_SQL] WHERE ID = #ID`);
let order = orders.recordset.length ? orders.recordset[0] : null;
if (order) {
await pool.request()
.input('cmt', req.body.cmt)
.query(`UPDATE [100].[dbo].[OELINCMT_SQL] SET cmt = #cmt WHERE ID = #ID;`);
order = { ...order, ...req.body };
res.json(order);
} else {
res.status(404).json({
message: 'Record not found'
});
}
} catch (error) {
res.status(500).json(error);
}
}
module.exports = {
getallcustomerOrders : getallcustomerOrders,
getcustomerOrders : getcustomerOrders,
updateComments : updateComments
}
api.js
var Db = require('./dboperations');
var dboperations = require('./dboperations');
var express = require('express');
var bodyParser = require('body-parser');
var cors = require('cors');
const { request, response } = require('express');
var app = express();
var router = express.Router();
app.use(bodyParser.urlencoded({ extended: true}));
app.use(bodyParser.json());
app.use(cors());
app.use('/api', router);
router.use((request,response,next)=> {
console.log('middleware');
next();
})
router.route('/customerOrder').get((request,response)=>{
dboperations.getallcustomerOrders().then(result => {
response.json(result[0]);
console.log(result[0]);
})
})
router.route('/customerOrder/:orderNumber').get((request,response)=>{
dboperations.getcustomerOrders(request.params.orderNumber).then(result => {
response.json(result[0]);
console.log(result[0]);
})
})
router.route('customerOrder/:ID').put((request,response)=>{
dboperations.updateComments(request.params.ID).then(result => {
response.json(result[0]);
console.log(result[0]);
})
})
var port = process.env.PORT || 5000;
app.listen(port);
console.log('Customer Order API is running at ' + port);
dboperations.getcustomerOrders().then(result => {
console.log(result);
})
dboperations.getallcustomerOrders().then(result => {
console.log(result);
})
dboperations.updateComments().then(result => {
console.log(result);
})
Client :
EmailFaxDetails.js : This is the page user enters the number
import React, { useState,useEffect } from 'react'
import FetchOrderDetails from './FetchOrderDetails';
import axios from 'axios'
import '../App.css';
const EmailFaxDetails = () => {
const [orderNumber, setOrderNumber] = useState('');
const [id, setId] = useState([]);
const [isShown, setIsShown] = useState(false);
const url = `http://localhost:5000/api/customerOrder/${orderNumber}`
useEffect(() => {
axios.get(url)
.then(response => {
console.log(response.data)
setId(response.data)
})
.catch((err) => console.log(err));
}, [url]);
const handleChange = event => {
setOrderNumber(event.target.value);
console.log(event.target.value);
};
const handleClick = event => {
event.preventDefault();
setIsShown(true);
console.log(orderNumber);
}
return(
<div>
<br></br>
<br></br>
Order Number: <input placeholder="Order Number" type="text" id="message" name="message" onChange={handleChange} value={orderNumber} autoComplete="off" />
{id.map((idnum) => (
<div key={idnum.ID}>
<br></br>
ID : {idnum.ID}
</div>
))}
<button onClick={handleClick}>Search</button>
{isShown && <FetchOrderDetails ord_no={orderNumber} ID={id}/>}
</div>
)
}
export default EmailFaxDetails;
FetchOrderDetails.js : In this page user get's the output if the number is available in SQL server and let then UPDATE accordingly.
import React, { useEffect, useState } from 'react'
import axios from 'axios'
import '../App.css';
const FetchOrderDetails = ({ord_no,ID}) => {
const [data, setData] = useState([]);
const url = `http://localhost:5000/api/customerOrder/${ord_no}`
useEffect(() => {
axios.get(url)
.then(response => {
console.log(response.data)
setData(response.data)
})
.catch((err) => console.log(err));
}, [url]);
const url2 = `http://localhost:5000/api/customerOrder/${ID}`
const onSubmit = () => {
axios.put(url2)
.then((response) => {
if (response.status === 200) {
alert("Comment successfully updated");
ID.history.push(`/customerOrder/${ord_no}`);
} else Promise.reject();
})
.catch((err) => alert("Something went wrong"));
}
if(data) {
return(
<div>
{data.map((order) => (
<div key={order.ID}>
<br></br>
ID : {order.ID}
<br></br>
Email/Fax: <input defaultValue={order.cmt} placeholder="Sales Ack Email" id="salesAck" style={{width: "370px"}} />
</div>
))}
<div>
<br></br>
<br></br>
<button onClick={onSubmit}>Update</button>
</div>
</div>
)
}
return (
<h1>Something went wrong, please contact IT!</h1>
)
}
export default FetchOrderDetails;
What I suspect is the issue might be coming from the EmailFaxDetails.js page while trying to pass the ID since there are 2 ID's per number the user search. I might be wrong, if anyone could find the error and help making it correct I would really appreciate it.
I think problem here
setId(response.data)
You need retrieve only id and same for for orderid

Showing only Post That user Posted in Reactjs with Server Side is Node Js, Mongodb

What I want?
I want to add post that only login user post. This post only showing My Item component page. here is my all code. When I login and try to add post and then check my item component page. this page showing all of the post. app.get and Server url '/product' it's collect ```email object'''
Thank you.
async function run() {
try {
await client.connect();
const productCollection = client.db("data").collection("product");
app.get("/product", async (req, res) => {
const query = {};
const cursor = productCollection.find(query);
const products = await cursor.toArray();
res.send(products);
});
app.get("/product", async (req, res) => {
const email = req.query.email;
const query = {email: email};
const cursor = productCollection.find(query);
const products = await cursor.toArray();
res.send(products);
});
app.get("/product/:id", async (req, res) => {
const id = req.params.id;
const query = { _id: ObjectId(id) };
const product = await productCollection.findOne(query);
res.send(product);
});
app.post("/product", async (req, res) => {
const newProduct = req.body;
const result = await productCollection.insertOne(newProduct);
res.send(result);
});
// DELETE
app.delete("/product/:id", async (req, res) => {
const id = req.params.id;
const query = { _id: ObjectId(id) };
const result = await productCollection.deleteOne(query);
res.send(result);
});
app.put('/update-quantity/:id', async (req, res) => {
const id = req.params.id;
const updatedInventoryInfo = req.body;
const filter = { _id: ObjectId(id) };
const options = { upsert: true };
const updatedDoc = {
$set: {
quantity: updatedInventoryInfo.quantity,
sold: updatedInventoryInfo.sold
}
}
const result = await productCollection.updateOne(filter, updatedDoc, options);
res.send(result);
})
} finally {
}
}
Client Side Code React Js
import axios from "axios";
import React, { useEffect } from "react";
import { Button, Col, Container, Row } from "react-bootstrap";
import { useAuthState } from "react-firebase-hooks/auth";
import { useNavigate } from "react-router-dom";
import auth from "../../firebase.init";
import useProduct from "../../Hooks/useProduct";
const MyItem = () => {
const [user] = useAuthState(auth);
const [products, setProducts] = useProduct();
const navigate = useNavigate();
useEffect(() => {
const getItems = async () => {
const email = user.email;
console.log(email);
const url = `http://localhost:5000/product?email=${email}`;
const { data } = await axios.get(url);
setProducts(data);
};
getItems();
}, [user]);
const handelDelete = (id) => {
const process = window.confirm(
"Are you sure you want to delete this item?"
);
if (process) {
const url = `http://localhost:5000/product/${id}`;
fetch(url, {
method: "DELETE",
})
.then((res) => res.json())
.then((result) => {
console.log(result);
setProducts(products.filter((product) => product._id !== id));
});
}
};
const navigateToProductDetails = (id) => {
navigate(`/product/${id}`);
};
return (
<>
<Container>
<Row>
{products.map((product, index) => {
return (
<Col key={index} md={4}>
<div className="product-aria">
<img src={product.img} alt="" />
<div>
<h1>{product.name}</h1>
<p>Details:{product.content}</p>
<div className="d-flex gap-3 flex-wrap justify-content-center">
<Button
onClick={() => navigateToProductDetails(product._id)}
variant="primary"
>
Manage
</Button>
<Button
onClick={() => handelDelete(product._id)}
variant="danger"
>
Delete
</Button>
</div>
</div>
</div>
</Col>
);
})}
</Row>
</Container>
</>
);
};
export default MyItem;
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Node Js
Your Are using same api url /products. So I Change this url and its work fine now.
app.get("/products", async (req, res) => {
const query = {};
const cursor = productCollection.find(query);
const products = await cursor.toArray();
res.send(products);
});
app.get("/product", async (req, res) => {
const email = req.query.email;
const query = {email: email};
const cursor = await productCollection.find(query).toArray();
res.send(cursor);
});
app.get("/product/:id", async (req, res) => {
const id = req.params.id;
const query = { _id: ObjectId(id) };
const product = await productCollection.findOne(query);
res.send(product);
});
app.post("/products", async (req, res) => {
const newProduct = req.body;
const result = await productCollection.insertOne(newProduct);
res.send(result);
});
I think you are using a custom hook. useProduct() I just comment it and use useState() hook and change the dependancy useEffect hook user to email. Here is my code.
const [user] = useAuthState(auth);
const { email } = user;
console.log(email);
// const [products, setProducts] = useProduct();
const [products, setProducts] = useState([]);
const navigate = useNavigate();
useEffect(() => {
const getItems = async () => {
// console.log(email);
const url = `http://localhost:5000/product?email=${email}`;
const { data } = await axios.get(url);
setProducts(data);
};
getItems();
}, [email]);

401 error in axios post request to local server

Context
I'm building a simple web application using the MERN stack for practice. In the app, logged-in users should be able to add a new blog to the site. However, for some reason my axios post request to the backend is failing and I'm receiving a 401 error. I'm using jsonwebtoken to handle the authentication. Submitting a POST request via Insomnia works fine so I don't believe it's an issue with my endpoint. I'm running backend server locally on my machine on port 3003 and have set up a proxy so there's no issues with cors. This works fine as the blogs from the backend are displays on the frontend once a user has logged in.
I've also checked the headers and can confirm that logged-in users have a valid bearer token.
What could be causing the issue?
Frontend
I can't post any images but here's a link to the frontend view:
https://imgur.com/a/DdUlfg9
App.js
import React, { useState, useEffect } from 'react'
import Blog from './components/Blog'
import blogService from './services/blogs'
import loginService from './services/login'
import LoginForm from './components/loginForm'
import BlogForm from './components/blogForm'
const App = () => {
const [blogs, setBlogs] = useState([])
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
const [user, setUser] = useState(null)
const [errorMessage, setErrorMessage] = useState(null)
const [newBlog, setNewBlog] = useState({
title: '',
author: '',
url: ''
})
useEffect(() => {
blogService.getAll().then(blogs =>
setBlogs( blogs )
)
}, [])
useEffect(() => {
const loggedInUser = window.localStorage.getItem("loggedBlogUser")
if(loggedInUser){
const user = JSON.parse(loggedInUser)
setUser(user)
}
},[])
const handleLogin = async (event) => {
event.preventDefault()
try {
const user = await loginService.login({
username, password
})
window.localStorage.setItem(
'loggedBlogUser', JSON.stringify(user)
)
blogService.setToken(user.token)
setUser(user)
setUsername('')
setPassword('')
} catch (exception){
setErrorMessage('Wrong credentials')
setTimeout(() => {
setErrorMessage(null)
}, 5000)
}
}
const handleLogout = async (event) => {
event.preventDefault()
if(user){
window.localStorage.removeItem("loggedBlogUser")
setUser(null)
}
}
const handleBlogField = (event) => {
event.preventDefault()
const {name, value} = event.target
console.log(newBlog.title)
setNewBlog(prevBlog => ({
...prevBlog,
[name] : value
}))
}
const addBlog = async (event) => {
event.preventDefault()
try {
const blog = await blogService.create(newBlog)
console.log("POST REQUEST: ",newBlog)
console.log('lets geddit')
setBlogs(blogs.concat(blog))
} catch (exception){
setErrorMessage('Uh oh, try again :[')
setTimeout(() => {
setErrorMessage(null)
}, 5000)
}
}
if(user === null){
return(
<>
{errorMessage}
<h2>Log into application</h2>
<LoginForm handleLogin={handleLogin} setUsername={setUsername} setPassword={setPassword} username={username} password={password}/>
</>
)
}
return (
<div>
<h2>blogs</h2>
{user &&
<div>
<h3>{user.username} logged in</h3>
<button onClick={handleLogout}>Logout</button>
</div>
}
<BlogForm handleSubmission={addBlog} newBlog={newBlog} handleBlogField={setNewBlog}/>
{/* <BlogForm addBlog={addBlog} title={newBlog.title} setTitle={setTitle} setAuthor={setAuthor} author={newBlog.author} url={newBlog.url} setUrl={setUrl}/> */}
{blogs.map(blog =>
<Blog key={blog.id} blog={blog} />
)}
</div>
)
}
export default App
Blogs.js
import axios from 'axios'
const baseUrl = '/api/blogs'
let token = null
//let config
const setToken = (newToken) => {
token = `bearer ${newToken}`
}
const getAll = async () => {
const response = await axios.get(baseUrl)
return response.data
}
const create = async (newObject) => {
const config = {
headers: {
Authorization: token
}
}
const response = await axios.post(baseUrl, newObject, config)
console.log(`RESPONSE: ${newObject}`)
return response.data
}
const blogService = {
getAll, setToken, create
}
export default blogService
Have you configured CORS?, in order to accept your localhost requests?

How to retrieve products from Shopify API using CLI

Run the Shopify CLI but still is very difficult to do anything.
Would like to retrieve 10 articles from Shopify between those id's but I am getting an error that URLSearchParams is not recognized.
Pretty sure that is something really easy.
The full code below is where I am at the moment.
index.js
import { Heading, Page } from "#shopify/polaris";
const Index = () => (
<Page
title='Trustpilot Aggreggation Uploader'
primaryAction={{
content: 'Update Metafields',
onAction: () =>
{
console.log('appliying products');
var limit = 10;
var sinceId = '0,921728736';
const product = async (limit, sinceId) => {
const res = await fetch(
"/products?" +
new URLSearchParams({
limit,
since_id: sinceId,
})
);
return await res.json();
};
}
}}
/>
);
export default Index;
server.js
import "#babel/polyfill";
import dotenv from "dotenv";
import "isomorphic-fetch";
import createShopifyAuth, { verifyRequest } from "#shopify/koa-shopify-auth";
import Shopify, { ApiVersion } from "#shopify/shopify-api";
import Koa from "koa";
import next from "next";
import Router from "koa-router";
dotenv.config();
const port = parseInt(process.env.PORT, 10) || 8081;
const dev = process.env.NODE_ENV !== "production";
const app = next({
dev,
});
const handle = app.getRequestHandler();
Shopify.Context.initialize({
API_KEY: process.env.SHOPIFY_API_KEY,
API_SECRET_KEY: process.env.SHOPIFY_API_SECRET,
SCOPES: process.env.SCOPES.split(","),
HOST_NAME: process.env.HOST.replace(/https:\/\//, ""),
API_VERSION: ApiVersion.October20,
IS_EMBEDDED_APP: true,
// This should be replaced with your preferred storage strategy
SESSION_STORAGE: new Shopify.Session.MemorySessionStorage(),
});
// Storing the currently active shops in memory will force them to re-login when your server restarts. You should
// persist this object in your app.
const ACTIVE_SHOPIFY_SHOPS = {};
app.prepare().then(async () => {
const server = new Koa();
const router = new Router();
server.keys = [Shopify.Context.API_SECRET_KEY];
server.use(
createShopifyAuth({
async afterAuth(ctx) {
// Access token and shop available in ctx.state.shopify
const { shop, accessToken, scope } = ctx.state.shopify;
ACTIVE_SHOPIFY_SHOPS[shop] = scope;
const response = await Shopify.Webhooks.Registry.register({
shop,
accessToken,
path: "/webhooks",
topic: "APP_UNINSTALLED",
webhookHandler: async (topic, shop, body) =>
delete ACTIVE_SHOPIFY_SHOPS[shop],
});
if (!response.success) {
console.log(
`Failed to register APP_UNINSTALLED webhook: ${response.result}`
);
}
// Redirect to app with shop parameter upon auth
ctx.redirect(`/?shop=${shop}`);
},
})
);
const handleRequest = async (ctx) => {
await handle(ctx.req, ctx.res);
ctx.respond = false;
ctx.res.statusCode = 200;
};
router.get("/", async (ctx) => {
const shop = ctx.query.shop;
// This shop hasn't been seen yet, go through OAuth to create a session
if (ACTIVE_SHOPIFY_SHOPS[shop] === undefined) {
ctx.redirect(`/auth?shop=${shop}`);
} else {
await handleRequest(ctx);
}
});
router.get("/products", async (ctx) => {
try {
const { shop, accessToken } = ctx.session;
const res = await fetch( 'https://${SHOPIFY_API_KEY}:${accessToken}#${shop}/admin/api/2020-10/products.json?${new URLSearchParams(
ctx.request.query
)}'
);
ctx.body = await res.json();
ctx.status = 200;
} catch (error) {
console.log('Failed to process products: ${error}');
}
});
router.post(
"/graphql",
verifyRequest({ returnHeader: true }),
async (ctx, next) => {
await Shopify.Utils.graphqlProxy(ctx.req, ctx.res);
}
);
router.get("(/_next/static/.*)", handleRequest); // Static content is clear
router.get("/_next/webpack-hmr", handleRequest); // Webpack content is clear
router.get("(.*)", verifyRequest(), handleRequest); // Everything else must have sessions
server.use(router.allowedMethods());
server.use(router.routes());
server.listen(port, () => {
console.log(`> Ready on http://localhost:${port}`);
});
});
Please beware that URLSearchParams class was added as a Global Object only on Node v10.
On older versions of Node you have to import it first:
import { URLSearchParams } from 'url';
global.URLSearchParams = URLSearchParams

Resources