I am trying to send a JSON Object to Stripe, but I am always receiving an error from the response.
API resolved without sending a response for /api/ctrlpnl/products_submit, this may result in stalled requests.
{
error: {
code: 'parameter_unknown',
doc_url: 'https://stripe.com/docs/error-codes/parameter-unknown',
message: 'Received unknown parameter: {"name":"dasdas"}',
param: '{"name":"dasdas"}',
type: 'invalid_request_error'
}
}
My code is below:
import Stripe from 'stripe';
import { NextApiRequest, NextApiResponse } from 'next';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY, {
apiVersion: '2020-08-27'
});
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method === 'POST') {
try {
const name = { name: req.body.name };
fetch(`${process.env.BASE_URL}/v1/products`, {
method: 'POST',
body: JSON.stringify(name),
headers: {
'Accept': 'application/json',
"content-type": 'application/x-www-form-urlencoded',
Authorization: `Bearer ${process.env.STRIPE_SECRET_KEY}`,
}
}).then((response) => {
return response.json();
}).then(data => {
console.log(data);
res.status(200).json(data)
})
} catch (err) {
res.status(err.statusCode || 500).json(err.message);
}
} else {
res.setHeader('Allow', 'POST');
res.status(405).end('Method Not Allowed');
}
}
The content-type of the fetch is correctly set to application/x-www-form-urlencoded, but the body contains a json. So Stripe is unable to parse the body parameters.
To fix that, you need to replace JSON.stringify by new URLSearchParams:
const name = { name: req.body.name };
fetch(`${process.env.BASE_URL}/v1/products`, {
method: 'POST',
body: new URLSearchParams(name), // ← this will return "name=xxxx"
headers: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Bearer ${process.env.STRIPE_SECRET_KEY}`,
}
});
Note that I recommend using the Stripe library which is much simpler to use: stripe.products.create(name);, especially since you already included it in your code.
Related
// getToken.mjs
import axios from 'axios';
import qs from 'qs';
var data = qs.stringify({
'client_id': 'xxxx-xxx',
'client_secret': 'xxxx-xxx',
'scope': 'https://graph.microsoft.com/.default',
'grant_type': 'client_credentials'
});
const config = {
method: 'get',
url: 'https://login.microsoftonline.com/${tenant_id}/oauth2/v2.0/token',
headers: {
'Content-Type': 'application/x-www-form-urlencoded', },
data : data
};
export let accessToken = axios(config)
.then(function (response) {
console.log((response.data.access_token));
})
.catch(function (error) {
console.log(error);
});
--------- Calling the API in the second script -----
//get response.js
import axios from "axios";
import { accessToken } from "./getToken.mjs";
const config = {
method: 'get',
url: 'https://graph.microsoft.com/v1.0/me/',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': `Bearer ${accessToken}`,
}
};
export let data000 = axios(config).then(function (response) {
console.log(JSON.stringify(response.data));
}).catch(function (error) {
console.log(error);
});
console.log(data000);
On executing the > node response.js ... returns 401, client secret, and id is correct. However, I feel the accessToken is not getting imported and hence the error. How do I fix this?
Try to use POST method to get accessToken.
const config = {
method: 'post',
url: 'https://login.microsoftonline.com/${tenant_id}/oauth2/v2.0/token',
headers: {
'Content-Type': 'application/x-www-form-urlencoded', },
data : data
};
I am trying to fetch a contact in JobNimbus based on their display name. According to their docs under "Retrieve All Contacts", I should be able to do this.
Below is the code they recommend:
var axios = require('axios');
var config = {
method: 'get',
url: 'https://app.jobnimbus.com/api1/contacts',
headers: {
'Authorization': 'bearer <token>',
'Content-Type': 'application/json'
}
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
Below is their request parameters example:
{
"must": [
{
"range": {
"date_created": {
"gte": 1459749600,
"lte": 1459835940
}
}
}
]
}
How do I request a contact based on their display_name?
It explains how to filter your search in the docs here. Just have to include the search criteria in the query params.
var axios = require('axios');
var config = {
method: 'get',
url: 'https://app.jobnimbus.com/api1/contacts?filter={"must":[{"term":{"first_name":"John"}},{"term":{"last_name":"Smith"}}]}
',
headers: {
'Authorization': 'bearer <token>',
'Content-Type': 'application/json'
}
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
I want to send Data with axios to my backend. But req.headers['Authorization'] is undefined. It is not in the header although I send it with axios.
axios:
import axios from 'axios';
const entryGroup = async (privatekey, userid) => {
try {
const options = {
headers: {
'Authorization': `Bearer ${userid}`,
'Accept': 'application/json',
},
body: privatekey
};
return axios.post('http://xxxxx:3000/entrygroup', options).then(res => res.data).catch(e => e);
} catch(e) {
return e;
}
};
export default entryGroup;
Nodejs: (all cors are enabled)
const dbf = require('../../functions/database/index');
module.exports = async (req, res) => {
const { body } = req.body;
console.log(req.headers);
};
Output from req.headers :
{
accept: 'application/json, text/plain, */*',
'content-type': 'application/json;charset=utf-8',
'content-length': '127',
host: 'xxxx:3000',
connection: 'Keep-Alive',
'accept-encoding': 'gzip',
'user-agent': 'okhttp/3.14.9'
}
Post you request like this
import axios from "axios";
const entryGroup = async (privatekey, userid) => {
try {
return axios.post(
"http://xxxxx:3000/entrygroup",
{ body: privatekey },
{
headers: {
Authorization: `Bearer ${userid}`,
Accept: "application/json",
},
}
).then(res => res.data).catch(e => e);
} catch (e) {
return e;
}
};
export default entryGroup;
Then in backend You will get it in
console.log(req.headers)
I am using nodeJS to communicate with an API.
To do that, I am using a post request.
In my code, I use form data to pass the variables, but I get error 400. When I try to put body instead, I get an error saying that my variables are undefined.
This is the API: https://developer.hpe.com/api/simplivity/endpoint?&path=%2Fdatastores
My request:
async function postCreateDatastore(url, username, password, name, clusterID, policyID, size, token) {
console.log (name, clusterID, policyID, size)
var options = {
method: 'POST',
url: url + '/datastores',
headers: {
'Content-Type': 'application/vnd.simplivity.v1.1+json',
'Authorization': 'Bearer ' + token,
},
formdata:
{
name: name,
omnistack_cluster_id: clusterID,
policy_id: policyID,
size: size,
}
};
return new Promise(function (resolve, reject) {
request(options, function (error, response, body) {
if (response.statusCode === 415) {
console.log(body);
resolve(body);
} else {
console.log("passed");
console.log(JSON.parse(body));
resolve(response.statusCode);
}
});
});
}
the answer:
testsimon20K 4a298cf0-ff06-431a-9c86-d8f9947ba0ba ea860974-9152-4884-a607-861222b8da4d 20000
passed
{ exception:
'org.springframework.http.converter.HttpMessageNotReadableException',
path: '/api/datastores',
message:
'Required request body is missing: public org.springframework.http.ResponseEntity<java.lang.Object> com.simplivity.restapi.v1.controller.DatastoreController.createDatastore(javax.servlet.http.HttpServletRequest,com.simplivity.restapi.v1.mo.actions.CreateDatastoreMO) throws org.apache.thrift.TException,org.springframework.web.HttpMediaTypeNotSupportedException,com.simplivity.restapi.exceptions.ObjectNotFoundException,java.text.ParseException,java.io.IOException,com.simplivity.util.exceptions.ThriftConnectorException,com.simplivity.common.exceptions.DataSourceException',
timestamp: '2019-07-04T08:51:49Z',
status: '400' }
thank you for your help!
I advice to use node-fetch to post your data. This package let you use the default fetch function from ES6.
Here is your answer:
//require the node-fetch function
const fetch = require('node-fetch');
async function postCreateDatastore(url, username, password, name, clusterID, policyID, size, token) {
console.log(name, clusterID, policyID, size);
try {
const response = await fetch(`${url}/datastores`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + token,
},
body: JSON.stringify({
name,
omnistack_cluster_id: clusterID,
policy_id: policyID,
size
})
});
const json = await response.json();
console.log(json);
return json;
}
catch(e) {
throw e;
}
}
I want to connect to an external api using some node-fetch code. My code first sends the login details & should receive a token from the api. Then this token is used for all the later communications.
Here is the code :
import fetch from 'node-fetch';
function getTokenForAuth(info) {
try {
var auth_token = '';
fetch(api_url + '/api/api-token/', {
method: 'POST',
body: JSON.stringify(info),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
.then(function(res) {
return res.json();
})
.then(function(json) {
auth_token = json;
})
return auth_token.token;
}
catch (e) {
console.log('[-] Error: Token Not Received');
console.log('[!] Exception: ' + e);
}
}
function getJSONFromRelativeURL(relativeURL, info) {
return fetch(`${api_url}${relativeURL}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Token ' + getTokenForAuth(info)
}
})
.then(function(res) {
console.log(res);
return res.json();
})
.then(function(json) {
console.log(json);
})
}
In the getJSONFromRelativeURL() function's request headers, if I hardcode the token, I get correct results. But if I run the code as it is now, I get an error saying : { detail: 'Invalid token.' }.
I think this is because of async nature of the promise in the fetch function, because of which it sometimes isnt able to send the token in time before the getJSONFromRelativeURL() gets called. I am not sure about this hypothesis & don't know how to correct this.
Your problem is here:
.then(function(json) {
auth_token = json;
})
return auth_token.token;
Your return statement is outside the Promise chain. This means that, at the point you hit return, the fetch request hasn't had a chance to even run yet. You've essentially just told the fetch Promise chain what to do when it does return.
So essentially
I think this is because of async nature of the promise in the fetch function, because of which it sometimes isnt able to send the token in time before the getJSONFromRelativeURL() gets called.
is 100% correct.
What you'll need to do is restructure things a little bit:
function getTokenForAuth(info) {
return fetch(api_url + "/api/api-token/", {
method: "POST",
body: JSON.stringify(info),
headers: {
"Content-Type": "application/json",
Accept: "application/json"
}
}).then(function(res) {
return res.json();
});
}
function getJSONFromRelativeURL(relativeURL, info) {
return getTokenForAuth(info)
.then(function(token) {
return fetch(`${api_url}${relativeURL}`, {
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `Token ${token}`
}
});
})
.then(function(res) {
console.log(res);
return res.json();
})
.then(function(json) {
console.log(json);
});
}
Have not tested it but it looks something like the following. For error handling use .catch(()=>{}) at the end of each chain.
function getTokenForAuth(info) {
var auth_token = '';
return fetch(api_url + '/api/api-token/', {
method: 'POST',
body: JSON.stringify(info),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
})
.then(function(res) {
return res.json();
})
}
function getJSONFromRelativeURL(relativeURL, info, token) {
return fetch(`${api_url}${relativeURL}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Token ' + token
}
})
.then(function(res) {
console.log(res);
return res.json();
})
.then(function(json) {
console.log(json);
})
}
getTokenForAuth(info)
.then((token)=>{
return getJSONFromRelativeURL(relativeURL, info, token)
})