I am in the process of integrating the Stripe API and am very close, but for some reason, I keep getting this weird error:
If I change the code to ‘Content-Type’: ‘application/x-www-form-urlencoded’, instead of ‘application/json’, I get this error:
Here is my code on the frontend:
onToken = async (token) => {
console.log('onToken', token)
await fetch('https://api.stripe.com', {
method: 'POST',
headers: {
'Authorization': `Bearer ${secKey}`,
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
stripeToken: token.id,
}),
})
.then(res => res.json())
.then(json => {
console.log('json>>>>', json)
})
}
And the backend:
router.post('https://api.stripe.com', (req, res, next) => {
const stripeToken = req.body.stripeToken
stripe.charges.create({
amount: 1000,
currency: "usd",
description: "Example charge",
source: stripeToken,
}, (err, charge) => {
console.log('charge>>', charge)
if (err) {
res.send({
success: false,
message: 'Error'
})
} else {
res.send({
success: true,
message: 'Success'
})
}
})
})
looks like your error is on the client side, can you console the post (req.body) on your back end ? Are you using bodyparser
middleware?
I do have body parser, but I don’t even think it is going through to the backend as no console logs come up. This is my current error with the current frontend code:
onToken = async (token) => {
console.log('onToken', token)
await fetch('https://api.stripe.com/v1/charges', {
method: 'POST',
headers: {
'Authorization': `Bearer ${secKey}`,
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
},
body: JSON.stringify({
stripeToken: token.id,
}),
})
.then(res => res.json())
.then(json => {
console.log('json>>>>', json)
})
}
I believe it has to do with Stripe needing x-www-form-urlencoded, but I need to bring back JSON.
it’s hard to troubleshoot without seeing the whole code, but I understand it could be proprietary, and I have never interfaced with the stripe api, although it looks straight forward. Maybe someone else more familiar with the stripe api could see potential sources of error with the snippets of code you posted.
Yeah, I feel stupid not being able to get this. It does seem straightforward but I’m struggling.
It’s because I’m not hitting the route properly. But I’m not sure what to make it.
maybe you should hit the token
route ?, it seems the stripe api has several routes to hit but since you are using a token…
https://stripe.com/docs/api/tokens
just a guess here…
@kerafyrm02, I don’t see jquery being used anywhere in the snippets provided, where do you see it?
It was the same error in SO I linked and the problem turned out to be loading jQuery after the checkout.js file. So it’s possible checkout.js relies on jQuery to be loaded first.
Look at [vnguyen] solution further down page where he answers his own question.
yeah but it is clear that the author of that SO question was using jquery on the client, where as there is no indication of such in this case
Right. I didn’t fully read the OPs original statement. I assumed checkout.js was generated by Stripe and had a dependency on jQuery (which would have been bad anyways).
Hmm… maybe I’ll create a basic instance of this problem. I’m not familiar with Stripe. I’ve always used Authorize.net
Ok so I made a quick example:
Your body is only submitting a token.id
<form>
<input type="text" name="amount">
<input type="hidden" name="currency" value="usd">
<input type="hidden" name="source" value="tok_visa">
<input type="hidden" name="receipt_email" value="myemail@example.com">
<input type="submit" value="Send Payment">
</form>
Granted I tested this with just HTML but you’re missing source and you’ll likely need a receipt_email too.
I used javascript’s FormData to submit my example.
https://hackernoon.com/stripe-api-reactjs-and-express-bc446bf08301
I tried to follow this, but I’m not sure what’s going on here either. When I make the frontend call: “localhost:3000/stripe”, I get the frontend url, then the backend, then the route and it can’t find it obviously.
EX: “http:localhost:3001/http:localhost:3000/stripe”
With the example you had you’re just missing two fields.
Also use FormData().
const getElement = (element) => document.querySelector(element);
const handleSubmitFormSubmit = (evt) => {
evt.preventDefault();
const formData = new FormData(evt.target);
const data = new URLSearchParams(formData);
fetch('https://api.stripe.com/v1/charges', {
method: 'post',
headers: {
'Authorization': `Bearer YOUR_TOKEN_HERE`,
'Content-Type': 'application/x-www-form-urlencoded'
},
body: data
})
.then (res => res.text())
.then (res => console.log(res));
};
const initApp = () => {
getElement('form')
.addEventListener('submit', handleSubmitFormSubmit);
};
initApp();
Tested and works.
1 Like
I need it to go through the backend, though.
I attempted a fake charge here, seems to be going thru
You can test it with with the usual npm install / yarn, if you don’t have nodemon then either change the script to start with node or install nodemon (I have it globally installed) and yarn dev
should start it.
Basically I used 2 routes, a tokenization route, to get the token and then a charge route to post the charge with the token I retrieved, I suppose you can combine these somehow if you want to on the back end. Also, to do the fake tests, you have to give stripe your phone number, other wise you have to use their own script (Stripe.js) on the client side, I opted for the former.
FYI, the api wasn’t as straightforward as I thought at first…, or maybe I just didn’t know what I was doing, good exercise anyhow, I have always wanted to know how stripe was used, now I have a somewhat rudimentary idea.
1 Like
Actually went ahead and refactored it to use just one /charge
route as you had it and handle token generation on the back end with one object sent from the client split between purchase and card info.
1 Like
I will absolutely take a look at this when I can. Thank you so much! Still a junior here obviously.