I am using stripe for the payment in react native app. For the backend, I have NodeJS running and it is working fine means when I pass the token, the payment gets successfully debited. However, in react native side, I am getting customer card details and creating token and then passing this token to my NodeJS server for payment but every time it gets network error.
React native Code
pay() {
stripe.createToken({
card: {
"number": '4242424242424242',
"exp_month": 12,
"exp_year": 2020,
"cvc": '123',
"name": "RAM",
}
}).then((token_object) => {
fetch('https://<IP address>:3000/pay', {
method:"POST",
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(token_object)
}).then(response => response.json())
.then(data => {
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error.message);
});
console.log(token_object.id);
});
}
NODEJS code
const express = require ('express')
const cors = require('cors')
const stripe = require ('stripe')('sk_test_')
const app = express()
const bodyParser = require('body-parser')
const PORT = process.env.PORT || 3000
app.use(bodyParser.json())
app.use(cors())
app.get('/',(req,res) =>{
res.send("hello from NodeJS!!!!")
})
app.post('/pay',async (req,res) =>{
console.log(req.body)
try {
const {token} = req.body,
charge = await stripe.charges.create({
amount: 15 * 100,
currency: 'inr',
description: 'Jewwllwry',
source: (token),
});
console.log("charged",{charge})
res.send("payment done")
} catch (error) {
console.log(error)
}
})
app.listen(PORT, ()=>{
console.log("server is running on port" + PORT)
})
Try sending your request with http instead of https as you you are working on local env.
Related
Whenever my frontend (React) runs at localhost:3000 and my backend (express) runs locally on localhost:8282, I get a 503 error and am able to see expected results.
My fronten has been deployed at netlify and backend in heroku. I run into cors error and some other weird error that I am unable to solve. Here are the code snippets:
getting the following errors:
Access to fetch at 'https://projectname.herokuapp.com/payment' from
origin 'https://projectnamee.netlify.app' has been blocked by CORS policy: No
'Access-Control-Allow-Origin' header is present on the requested resource.
If an opaque response serves your needs, set the request's mode to 'no-cors' to
fetch the resource with CORS disabled.
POST https://projectname.herokuapp.com/payment net::ERR_FAILED 503
fetch call in frontend:
const backend_api = process.env.NODE_ENV == 'production' ? 'https://projectname.herokuapp.com/payment' : 'http://localhost:8282/payment';
const purchase = token => {
let product = purchaseProduct
const body = {
token,
product
}
const headers = {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Credentials": "true",
"Access-Control-Allow-Methods": "*"
}
return fetch(backend_api, {
method: "POST",
headers,
body: JSON.stringify(body)
}).then(response => {
console.log("Response ", response)
const {status} = response;
console.log("STATUS ", status)
})
.catch(error => console.log(error))
}
backend index.js:
require('dotenv').config();
const cors = require("cors")
const express = require("express")
const stripe = require("stripe")(process.env.STRIPE_SEC_KEY)
const { v4: uuidv4 } = require('uuid');
const app = express();
// middleware
app.use(express.json())
// I tried a lot of variations of this, none worked
app.use(cors({
origin: '*'
}))
// routes
app.get("/", (req, res) => {
res.send("Works here")
})
app.post("/payment", (req, res) => {
const {product, token} = req.body;
console.log("Product", product)
console.log("price", product.price)
console.log("email", token.email)
const idempotencyKey = uuidv4()
return stripe.customers.create({
email: token.email,
source: token.id
}).then(customer => {
stripe.charges.create({
amount: product.price * 100,
currency: 'usd',
customer: customer.id,
receipt_email: token.email,
description: `Purchase of ${product.name}`,
shipping: {
name: token.card.name,
address: {
country: token.card.address_country
}
}
}, {idempotencyKey})
}).then(result => res.status(200).json(result))
.catch(err => console.log(err))
})
// listen
const port = process.env.PORT || 8282
app.listen(port, () => console.log(`Listening on port ${port}`))
I'm building a React-Node app to consume QuickBooks APIs using OAuth 2 authentication. The app is structured so that the react app runs off a dev server at localhost:3000, and proxies http requests to the express server at localhost:3001.
So, I'm having some trouble making API calls: the react component responsible for rendering API data is crashing, and I'm getting the following error
"Missing required parameter: access_token"
I have the following code in my express server, which converts the authorization code into an access token, and then (I think) passes that token to http://localhost:3000/companyInfo. However I suspect this is where the problem is - is the token actually being sent to this address, or have I misunderstood how OAuth works? Here's the server-side code in question:
app.get("/callback", function (req, res) {
oauthClient
.createToken(req.url)
.then(function (authResponse) {
oauth2_token_json = JSON.stringify(authResponse.getJson(), null, 2);
})
.catch(function (e) {
console.error(e);
});
res.redirect("http://localhost:3000/companyInfo" );
});
...here's my entire server:
const express = require("express");
const OAuthClient = require("intuit-oauth");
const bodyParser = require("body-parser");
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
const port = process.env.PORT || 3001;
let urlencodedParser = bodyParser.urlencoded({ extended: true });
let oauth2_token_json = null;
let oauthClient = null;
app.get("/authUri", urlencodedParser, (req, res) => {
oauthClient = new OAuthClient({
clientId: "****",
clientSecret: "****",
environment: "sandbox",
redirectUri: "http://localhost:3001/callback",
});
let authUri = oauthClient.authorizeUri({
scope: [OAuthClient.scopes.Accounting],
state: "testState",
});
res.send(authUri);
});
app.get("/callback", function (req, res) {
oauthClient
.createToken(req.url)
.then(function (authResponse) {
oauth2_token_json = JSON.stringify(authResponse.getJson(), null, 2);
})
.catch(function (e) {
console.error(e);
});
res.redirect("http://localhost:3000/companyInfo" );
});
app.get("/getCompanyInfo", (req, res) => {
let companyID = oauthClient.getToken().realmId;
let url =
oauthClient.environment == "sandbox"
? OAuthClient.environment.sandbox
: OAuthClient.environment.production;
oauthClient
.makeApiCall({
url: url + "v3/company/" + companyID + "/companyinfo/" + companyID,
})
.then(function (authResponse) {
console.log(
"The response for API call is :" + JSON.stringify(authResponse)
);
res.send(JSON.parse(authResponse.text()));
})
.catch(function (e) {
console.error(e);
});
});
app.listen(port, () => {
console.log(`Server is listening on port: ${port}`);
});
...and here's the react component where I want to render the returned API call data:
import React, { useState, useEffect } from 'react'
import axios from 'axios'
const CompanyInfo = () => {
const [ info, setInfo ] = useState('')
useEffect(() => {
axios.get('/getCompanyInfo')
.then(res => setInfo(res.data))
},[])
return(
<div>
<p> {info.CompanyInfo.CompanyName} </p>
</div>
)
}
export default CompanyInfo
The strange this is that sometimes I have been able to render the API call data in this component, but I can only do it once. If I refresh my page, it crashes, and I have to start the login process again in order to make the API call work.
This graphql api I found on the internet is showing cors error when I call it with fetch or apollo client from frontend, So I searched for a solution and I found out that if I call api from server, cors error will go away so I followed a basic tutorial about express and set up one, then call graphql api in my server/index.js
const express = require("express");
const rp = require("request-promise");
rp("https://.../graphql", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
query: `
query {
heroSearchByName(name: "John") {
name
}
}
`,
}),
})
.then((body) => {
console.log(body); // result
})
.catch((err) => {
console.log(err);
});
const PORT = 4000;
const app = express();
console.log(`Server listening on http://localhost:${PORT} ...`);
app.listen(PORT);
Now I get the data back in my terminal but I don't know how to send those data back to my frontend which is in frontend/App.js to show data on my page. Can someone help me with this ? I am quite new to express and graphql so I might be doing it all wrong. Thanks
The idea is something like this:
Frontend makes a request to the backend application.
Backend fetches the data from the GraphQL API and returns it to the client.
So on your express app just build a route
const express = require("express");
const rp = require("request-promise");
app.post('/fetchData', function (req, res) {
rp("https://.../graphql", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
query: `
query {
heroSearchByName(name: "John") {
name
}
}
`,
}),
})
.then((body) => {
res.send(body)
})
.catch((err) => {
console.log(err);
});
})
const PORT = 4000;
const app = express();
console.log(`Server listening on http://localhost:${PORT} ...`);
app.listen(PORT);
``
I need to hide the secret for direct line channel using an HTML webchat, tried this solution but keeps getting me errors while fetching. I got the secret for direct line channel in Azure portal in process.env
Index.js
const dotenv = require('dotenv');
const path = require('path');
const restify = require('restify');
const bodyParser = require('body-parser');
const request = require('request');
const corsMiddleware = require('restify-cors-middleware');
const { BotFrameworkAdapter, MemoryStorage, ConversationState, UserState } = require('botbuilder');
const { EBOT } = require('./eBot');
const ENV_FILE = path.join(__dirname, '.env');
dotenv.config({ path: ENV_FILE || process.env.directLineSecret });
const cors = corsMiddleware({
origins: ['*']
});
const server = restify.createServer();
server.pre(cors.preflight);
server.use(cors.actual);
server.use(bodyParser.json({
extended: false
}));
server.listen(process.env.port || process.env.PORT || 3978, () => {
console.log(`\n${ server.name } listening to ${ server.url }`);
console.log('\nGet Bot Framework Emulator: https://aka.ms/botframework-emulator');
console.log('\nTo talk to your bot, open the emulator select "Open Bot"');
});
// Generates a Direct Line token
server.post('/directline/token', (req, res) => {
const options = {
method: 'POST',
uri: 'https://directline.botframework.com/v3/directline/tokens/generate',
headers: {
'Authorization': `Bearer ${process.env.directLineSecret}`
}};
request.post(options, (error, response, body) => {
if (!error && response.statusCode < 300) {
res.send({
token: body.token
});
} else {
res.status(500).send('Call to retrieve token from DirectLine failed');
}
});
});
server.post('/api/messages', (req, res) => {
adapter.processActivity(req, res, async (context) => {
await ebot.run(context);
});
});
And webchat.html:
<script src="https://cdn.botframework.com/botframework-webchat/latest/webchat.js"></script>
<script>
(async function () {
const res = await fetch('https://directline.botframework.com/v3/directline/tokens/generate', { method: 'POST' });
const webChatToken = await res.json();
window.WebChat.renderWebChat({
directLine: window.WebChat.createDirectLine({ token: webChatToken })
}, document.getElementById('webchat'));
document.querySelector('#webchat > *').focus();
})().catch(err => console.error(err));
</script>
/// UPDATE
The errors:
** Failed to load resource: the server responded with a status of 403 ()
** webchat.js:2 POST https://directline.botframework.com/v3/directline/conversations 403
** webchat.js:2 Uncaught t {message: "ajax error 403", xhr: XMLHttpRequest, request: {…}, status: 403, responseType: "json", …}
What's the way then ?, what am I missing ?
The issue with your particular implementation is, while you have set up an API for generating and serving a token back to Web Chat, you are failing to actually call that endpoint. Instead of
const res = await fetch('https://directline.botframework.com/v3/directline/tokens/generate', { method: 'POST' });
you should have
const res = await fetch('http://localhost:3978/directline/token', { method: 'POST' });
It is this that will make the call to exchange the Direct Line secret for a token and, in turn, will return the token back to your Web Chat instance.
Solved it, the problem was the way the api token function was made, this is the one that worked in order to retrieve the json response from index.js :
server.post('/directline/token', async function(req, res) {
const result = await fetch('https://directline.botframework.com/v3/directline/tokens/generate', {
method: 'POST',
headers: {
Authorization: 'Bearer ' + process.env.DirectLineSecret
}
});
const token = await result.json();
res.send(token);
});
The one I posted in questions was not sending the token response but a huge request ibject instead. Hope it helps !
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}
/>
);
};```