Send Post request in Node js Rest API - node.js

I CAN'T SEND POST REQUEST FROM CLIENT SIDE !
I need to send HTTP Post request in Node js Rest API to the payment gateway.
Post request needs to have headers and body payload. I have frontend and backend separated, I'm using Rest API with express.js and payment gateway needs server to server communication so I can't to do that from client side. Basically when user clicks on payment I need to send call to my backend server then my backend server needs to send request to the payment gateway.
Payment gateway has documentation with only MVC ( Model View Controller ) and they really can't help.
So logic inside controller should be something like this
exports.payment = (req, res, next) => {
const { amount, id, currency } = req.body;
//add headers
//create body paloyad
//send request to https://payment....com/api-key/transaction
//receive response
res.status(200).json({ status: 'success' });
}

There are several ways to do it, like Fetch, however, I prefer using Axios:
const axios = require('axios');
exports.payment = (req, res, next) => {
const { amount, id, currency } = req.body;
//add headers
const options = {
headers: {'X-Custom-Header': 'value'}
};
//create body payload
const body = {
amount: amount
id: id
currency: currency
};
//send request to https://payment....com/api-key/transaction
axios.post('https://payment....com/api-key/transaction', body, options)
.then((response) => {
//receive response
console.log(response);
res.status(200).json({ status: 'success' });
})
.catch((error) => {
console.log(error)
});

Use Axios to send POST requests. Its much easier.
const axios = require('axios')
let config = {
headers: {
header1: value,
}
}
let data = {
'amount': amount,
'id':id,
'currency':currency,
}
axios.post('https://payment....com/api-key/transaction', data,config)
.then(function (response) {
console.log(response);
})

You can use https://github.com/node-fetch/node-fetch
const fetch = require('node-fetch');
const body = {a: 1};
const response = await fetch('https://httpbin.org/post', {
method: 'post',
body: JSON.stringify(body),
headers: {'Content-Type': 'application/json'}
});
const data = await response.json();
console.log(data);

Related

How to hide my API Key in a POST request?

I want to hide my API key when I am making a post request from my browser. I need to input a number plate and send the request to the API and the API responds me with details about it. I have managed to get this working with a GET request to another API by using nodeJS but I can't manage to make it work with a post request. Keep in mind the request needs information from my input field in the browser which is the registration number of the vehicle to send me information back about it.
Here is my function in my browser JS file.
const searchBtn = document.getElementById("search-btn")
function startFetch() {
let plate = document.getElementById("plate").value
let reg = {registrationNumber: `${plate}`}
fetch(`https://driver-vehicle-licensing.api.gov.uk/vehicle-enquiry/v1/vehicles`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': `my key is here`,
},
body: JSON.stringify(reg),
})
.then(response => response.json())
.then(response => {
console.log(response);
})
.catch(err => {
console.log(err);
});
};
searchBtn.addEventListener("click", startFetch);
Any help and method would be appreciated. Thanks in advance.
For anyone in the same boat. I have managed to achieve what I want.
Client side JS file:
function startFetch() {
let plate = document.getElementById("plate").value
let reg = {registrationNumber: plate}
fetch(`http://localhost:3000/v`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(reg),
})
.then(response => response.json())
.then(response => {
console.log(response);
})
.catch(err => {
console.log(err);
});
};
And the backend using Express, NodeJS, body-parser and axios
require("dotenv").config()
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const axios = require('axios');
app.use(bodyParser.json());
app.use(express.static("src"))
//Env vars
const API_URL = process.env.API_URL
const API_KEY = process.env.API_KEY
app.post('/v', (req, res) => {
const body = req.body;
// Make a request to the backend API
axios.post(API_URL, body,
{
headers: {
"Content-Type": "application/json",
'x-api-key': API_KEY
}
}
)
.then((response) => {
// Return the response from the backend API to the client
res.send(response.data);
})
.catch((error) => {
// Handle any errors
res.status(500).send(error);
});
});
app.listen(3000, () => {
console.log('API proxy server is listening on port 3000');
});
You are already sending the body.
A very minor modification to you code:
function startFetch() {
let plate = "abc123";
let reg = { registrationNumber: `${plate}` };
fetch(`https://driver-vehicle-licensing.api.gov.uk/vehicle-enquiry/v1/vehicles`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
"x-api-key": `my key is here`,
},
body: JSON.stringify(reg),
}
);
}
startFetch();
You can see your api-key in the header (though you should never send secret via http):
Then in the body (in chrome they call it payload):

Node.js Paypal how to send other data alongside the trigger

I am attempting to send data alongside the code for paypal to the node.js client, but I am not sure where to send that data alongside it.
Here is the client side paypal code:
paypal.Buttons({
// Order is created on the server and the order id is returned
createOrder: (data, actions) => {
return fetch("/api/orders", {
method: "post",
// use the "body" param to optionally pass additional order information
// like product ids or amount
})
.then((response) => response.json())
.then((order) => order.id);
},
// Finalize the transaction on the server after payer approval
onApprove: (data, actions) => {
return fetch(`/api/orders/${data.orderID}/capture`, {
method: "post",
})
.then((response) => response.json())
.then((orderData) => {
// Successful capture! For dev/demo purposes:
console.log('Capture result', orderData, JSON.stringify(orderData, null, 2));
const transaction = orderData.purchase_units[0].payments.captures[0];
alert(`Transaction ${transaction.status}: ${transaction.id}\n\nSee console for all available details`);
// When ready to go live, remove the alert and show a success message within this page. For example:
// const element = document.getElementById('paypal-button-container');
// element.innerHTML = '<h3>Thank you for your payment!</h3>';
// Or go to another URL: actions.redirect('thank_you.html');
});
}
}).render('#paypal-button-container');
Here is the server side paypal code:
app.post("/api/orders", async (req, res) => {
const order = await createOrder();
res.json(order);
});
// capture payment & store order information or fullfill order
app.post("/api/orders/:orderID/capture", async (req, res) => {
const { orderID } = req.params;
const captureData = await capturePayment(orderID);
// TODO: store payment information such as the transaction ID
res.json(captureData);
});
//////////////////////
// PayPal API helpers
//////////////////////
// use the orders api to create an order
async function createOrder() {
const accessToken = await generateAccessToken();
const url = `${base}/v2/checkout/orders`;
const response = await fetch(url, {
method: "post",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${accessToken}`,
},
body: JSON.stringify({
intent: "CAPTURE",
purchase_units: [
{
amount: {
currency_code: "USD",
value: "100.00",
},
},
],
}),
});
const data = await response.json();
return data;
}
// use the orders api to capture payment for an order
async function capturePayment(orderId) {
const accessToken = await generateAccessToken();
const url = `${base}/v2/checkout/orders/${orderId}/capture`;
const response = await fetch(url, {
method: "post",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${accessToken}`,
},
});
const data = await response.json();
return data;
}
The issue is there is no req.body.stuff anywhere.
The goal I am trying to achieve, is is when the payment is made, I want to send the data of like the string "potato", Before the actual payment goes through on node. Because potato is a client side variable that will then when used in server retrieve the value of the amount to be paid in node.
Where/how do I put this so I can do this?
Thanks.
How to do it is literally explained in the comments of that client-side code:
return fetch("/api/orders", {
method: "post",
// use the "body" param to optionally pass additional order information
// like product ids or amount
})

How do I call a different REST API within a express route?

I have an express.js REST API that I have created with a variety of routes. I'd like to create a route to call another REST API and then return the result. Ideally, it should look something like the following:
router.post('/CreateTicket', cors(corsOptions), function(req, res, next) {
//make a call to another rest api and then res.send the result
}
The REST API route that I am calling is a POST request and will take in a JSON body with the information for the ticket. It then will return a JSON response containing the ticket information and ticket link.
Essentially, I just want to pass req.body as the body of the API call and then res.send() the response of the API call. I was trying to figure out some way to use fetch or requests, but was just getting confused.
Thank you so much for any help that anyone can offer!
I would suggest to use axios if you want to call the third-party API. The simple way of doing is to create an options(config) pass it to the axios object.
npm i axios --save
Axios config
const options = {
'method': 'POST',
'url': 'https://URL',
'headers': {
'Content-Type': 'application/json'
},
data: {
firstName: 'Fred',
lastName: 'Flintstone'
}
};
try {
const result = await axios(options);
console.log(result);
} catch (e) {
console.log(e);
}
In your route file:
const axios = require('axios');
const getData = async (body) => {
const options = {
'method': 'POST',
'url': 'https://URL',
'headers': {
'Content-Type': 'application/json'
},
data: {
body
}
};
try {
const result = await axios(options);
console.log(result);
return result;
} catch (e) {
console.log(e);
}
}
router.post('/CreateTicket', cors(corsOptions), async function(req, res, next) {
//make a call to another rest api and then res.send the result
try {
const response = await getData(req.body);
res.send(response);
} catch (e) {
//wrap your error object and send it
}
}
Note: if you want to pass the data to your own created route you can use res.redirect and it will send the response back. You can check the axios details in the link above.
You would have to use something like axios or http (code originates from link):
const https = require('https')
const options = {
hostname: 'example.com',
port: 443,
path: '/todos',
method: 'GET'
}
const req = https.request(options, res => {
console.log(`statusCode: ${res.statusCode}`)
res.on('data', d => {
return d
})
}

SurveyMonkey API Create a Survey using NodeJS

I created a small server using NodeJS/Express and I'm using node-fetch to interact with SurveyMonkeys API. I currently have two surveys on my account which I can view through their Postman collection. But when I try to use my own endpoints, it doesn't seem to work. The GET request to view all of the surveys returns a status code of "200" but responds with:
{
"size": 0,
"timeout": 0
}
The POST request to create a survey gives me a status code of "400" but returns the same response. Here is my code so far.
const router = require("express").Router();
const fetch = require("node-fetch");
const TOKEN = process.env.SM_ACCESS_TOKEN;
const BASEURL = process.env.SM_BASEURL;
const options = method => ({
headers: {
Authorization: `Bearer ${TOKEN}`,
"Content-Type": "application/json",
method: method
}
});
/*
GET a list of surveys
*/
router.get("/", async (req, res) => {
try {
const surveys = await fetch(`${BASEURL}surveys`, options("GET"));
console.log(surveys);
if (surveys) {
return res.status(200).json(surveys);
}
} catch (err) {
console.log(err);
res.status(500).send({ message: "Server error", err });
}
});
router.post("/create-survey", (req, res) => {
const surveyData = req.body;
fetch(`${BASEURL}surveys`, {
method: "POST",
body: surveyData,
headers: {
Authorization: `bearer ${TOKEN}`,
"Content-Type": "application/json"
}
})
.then(data => {
return res.status(data.status).json(data);
})
.catch(err => console.log(err));
});
module.exports = router;
Additional information:
I am able to complete all of these actions using the POSTMAN collection provided by SurveyMonkey with my Access Token. BASEURL = "https://api.surveymonkey.com/v3/".
ServeyData = { "title": "Some Title" }
Resolved this issue by switching out of node-fetch and instead using axios. Could be the fetch vs xhr request I think.

Send response from server side axios request to React/Redux app

I'm a little new to creating a backend in Node/Express, but I am trying use axios to make HTTP requests. I've set up express routes that will make the necessary request and I know from using Postman that GET request I'm testing does return a response. Where I'm stuck is how to return that data and send it to my React/Redux app to use.
-Server Side-
//Express Route
app.get('/api/recipes', recipeController.getRecipes)
//Controller Function that makes axios request
const axios = require('axios')
const Promise = require('bluebird')
module.exports = {
getRecipes(req, res) {
const url = "https://gw.hellofresh.com/api/recipes/search?country=us&limit=9"
const token = "IUzI1NiIsInR5c"
axios
.get(url, {
"headers": {"Authorization": "Bearer " + token}
})
.then((response) => {
console.log(response)
})
.catch((err) => {
console.log(err)
})
}
}
-Client Side-
I dispatch the following action and make a call using the endpoint I created. However, at this point, I'd get an error status even though on the server side I was able to get a response. I tried playing around using Promises as I read that axios GET requests returns promises, but couldn't wrap my head around on how to implement it.
export const getRecipes = () => {
return (dispatch) => {
axios
.get('/api/recipes')
.then((resp) => {
console.log(resp)
})
.catch((err) => {
console.log(err)
})
}
}
You need to call res.send in the route, to send the data to the client:
module.exports = {
getRecipes(req, res) {
const url = "https://gw.hellofresh.com/api/recipes/search?country=us&limit=9"
const token = "IUzI1NiIsInR5c"
axios
.get(url, {
"headers": {"Authorization": "Bearer " + token}
})
.then(response => {
console.log(response)
res.send(response) // <= send data to the client
})
.catch(err => {
console.log(err)
res.send({ err }) // <= send error
})
}
}

Resources