I have an app that allows a logged in user to upgrade their account by subscribing to a 'basic' or 'premium' subscription. Once they subscribe they can then click on a "Manage Billing" button and it will take them to a Billing Portal where they can cancel, or upgrade their subscription.
The issue that I am running into is that I am trying to make the customer be dynamic. So where it says customer: 'cus_IZvOkC9VtDRXUi', I can instead have something like customer: customer, where customer is a dynamic variable.
router.post('/customer-portal', async (req, res) => {
// const id = req.body.id
// console.log(req.body, 'ID HERE')
// User.findBy({ id })
// .then(found => {
// console.log(found, 'I FOUND YOU')
// })
// .catch(error => {
// console.log(error, 'error here on portal')
// })
// whatever customer is logged in, this needs to be the CUSTOMER line 45 - DYNAMIC
const session = await stripe.billingPortal.sessions.create({
customer: 'cus_IZvOkC9VtDRXUi',
return_url: 'http://localhost:3000/my-profile',
})
res.redirect(session.url)
const sessionURL = session.url
console.log(sessionURL,'this is session')
// console.log(session, 'this is the session')
// console.log(req,'this is req')
// res.status(302).redirect(sessionURL)
// next()
})
The problem is that when I try and send headers (so I can send the ID of the currently logged in user ID from the frontend), the req.body is an empty object and I can't see the ID. See frontend code here:
const state = useSelector(state => state)
const id = state.auth.user.id
const handlePortal = (e) => {
e.preventDefault()
console.log(id, 'JSJDHDHDHDHDHDHDH')
return fetch('http://localhost:5000/api/stripe/customer-portal', {
// mode: 'no-cors',
method: 'post',
// headers: {
// 'Content-Type': 'application/json',
// },
body: JSON.stringify({
id: id
})
})
.then((response) => {
console.log(response, 'this is the response')
const url = response.url
console.log(url, 'URURUIRIRLL')
// express cant force the front-end to redirect.
window.location = url
// return response.json()
})
.catch((error) => {
console.log(error.message, 'There was a dumb error')
})
}
The headers are commented out right now, but as soon as I add them in, I get this error:
What is super weird is this exact setup works when I create a Stripe Customer. I send the ID from the frontend at id: currentUserId. See code below:
const state = useSelector(state => state)
const currentUserId = state.auth.user.id
const handleSubmit = e => {
e.preventDefault()
return fetch(`http://localhost:5000/api/stripe/create-customer/`, {
method: 'post',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: email,
id: currentUserId
})
})
.then((response) => {
console.log(response, 'this is response handlesubmit')
return response.json()
})
.then((result) => {
setCustomer(result.customer)
console.log(result, 'THIS IS RESULT on register CUSTOMER')
})
}
Then on the backend I have my /create-customer endpoint and pull the id by req.body.id, then find the currently logged in user, then add the customer id given by stripe to the user table. This works fine without any CORS issues. See backend endpoint here:
router.post('/create-customer', async (req, res) => {
const id = req.body.id
const customer = await stripe.customers.create({
email: req.body.email,
})
res.send({ customer })
User.findBy({ id })
.then(found => {
User.updateStripeID(id, changes)
.then(changedUser => {
console.log(changedUser, 'changed!', id, changes)
})
.catch(error => {
console.log(error, 'this is stupid')
})
})
.catch(error => {
console.log(error, 'there was an error on catch', error.message)
})
})
So my question is, how do I get this working? Or how do I get my currently logged in user to the backend another way?
Couple things to note:
I do have a CORS extension that I am using in Chrome. The reason is that the my frontend will not even redirect to the Billing Portal and will throw an 'access-control-allow-origin' error. I have tried every solution on every stack overflow page about this. Literally. Spent days trying almost every solution about CORS issues. They do not work and I hope that when the app deploys live it won't have that redirect issue.
If you could not already tell my frontend is React, backend is NodeJS, and I am using Knex/SQLite3 for database tables/migrations/seeds etc.
Any help would be appreciated!