#MartinSkywalker
1 messages · Page 1 of 1 (latest)
Hello, can you provide your stripe code where you are running in to this error?
Martin Guitar Artist - Experience the psychedelic soundscapes of Martin Guitar Artist, the independent artist that trades in Psychedelic Rock.
in my website on click the button
yes
i send you dm
link
Unfortunately this server is too busy for me to click through the site. Can you show me your code for the API call you are making when you get this error?
yes i sent you my code by private message you can download it
please help
when you click on the button it is not rendering the checkout
Back on this thread. Checking in to this call now...
in my opinion I think there is probably something wrong with checkout.js
import { useEffect, useState } from "react";
import { useStripe, useElements } from "@stripe/react-stripe-js";
import { PaymentElement } from "@stripe/react-stripe-js";
export default function CheckoutForm() {
const stripe = useStripe();
const elements = useElements();
const [message, setMessage] = useState(null);
const [isProcessing, setIsProcessing] = useState(false);
const handleSubmit = async (e) => {
e.preventDefault();
if (!stripe || !elements) {
// Stripe.js has not yet loaded.
// Make sure to disable form submission until Stripe.js has loaded.
return;
}
setIsProcessing(true);
const { error } = await stripe.confirmPayment({
elements,
confirmParams: {
// Make sure to change this to your payment completion page
return_url: `${window.location.origin}/completion`,
},
});
if (error.type === "card_error" || error.type === "validation_error") {
setMessage(error.message);
} else {
setMessage("An unexpected error occured.");
}
setIsProcessing(false);
};
return (
<form id="payment-form" onSubmit={handleSubmit}>
<PaymentElement id="payment-element" />
<button disabled={isProcessing || !stripe || !elements} id="submit">
<span id="button-text">
{isProcessing ? "Processing ... " : "Pay now"}
</span>
</button>
{/* Show any error or success messages */}
{message && <div id="payment-message">{message}</div>}
</form>
);
}
or in Payment.js
import { useEffect, useState } from "react";
import { loadStripe } from "@stripe/stripe-js";
import { Elements } from "@stripe/react-stripe-js";
import CheckoutForm from "../Home/CheckoutForm";
function Payment(props) {
const [stripePromise, setStripePromise] = useState(null);
const [clientSecret, setClientSecret] = useState("");
useEffect(() => {
fetch("/config").then(async (r) => {
const { publishableKey } = await r.json();
setStripePromise(loadStripe(publishableKey));
});
}, []);
useEffect(() => {
fetch("/create-payment-intent", {
method: "POST",
body: JSON.stringify({}),
}).then(async (result) => {
var { clientSecret } = await result.json();
setClientSecret(clientSecret);
});
}, []);
return (
<>
<div className="Payment">
{clientSecret && stripePromise && (
<Elements stripe={stripePromise} options={{ clientSecret }}>
<CheckoutForm />
</Elements>
)}
</div>
</>
);
}
export default Payment;
Have you debugged to see what specific line is getting this error? Apologies, still had to bounce around to other threads for a bit
I'm not finding the error, I need your support I sent you the files, can you help me?
Do you have a version of your page that doesn't have minified javascript code?
I think the best way of narrowing this down is to single step through what is happening when that button is clicked
yes I sent you the complete files via drive
I mean a live version where we can put breakpoints in and debug
This currently doesn't look like a Stripe error and I'm not able to guess what line of code has that error unfortunately
Stepping through a live version should help clear this up quickly though
do you want access to my server via ssh?
No, I cannot do debugging at that level for you.
I sent you the files without minification just download and run you will be able to debug
Unfortunately I can't set up a test site with that code at the moment
I can help look in to this if you can help narrow the scope of what we are looking at, but at the moment this is too big an ask
no one can help me?
it's very simple, you just have to render the checkout and it's not there for some reason
I can help but spinning up a test version of your site is too much to do here, especially when this server is this busy, and especially when you can tweak things to make this a lot easier on both of us
I don't understand everything I can tell you to help me I went through it but I don't know how can you help me?
So I now see that I can actually step through the code on your site. Still trying to figure out what raises this error
ok thank you very much for your help, any questions I'm here
Hi there 👋 based on the code that you provided earlier, it looks like you're trying to parse the responses to these fetches as JSON:
fetch("/config").then(async (r) => {
const { publishableKey } = await r.json();
setStripePromise(loadStripe(publishableKey));
});
}, []);
useEffect(() => {
fetch("/create-payment-intent", {
method: "POST",
body: JSON.stringify({}),
}).then(async (result) => {
var { clientSecret } = await result.json();
setClientSecret(clientSecret);
});```
but those endpoints seem to be returning HTML rather than JSON:
Have you added additional logging to your code so you can trace exactly what is happening and at what point your code stops behaving as you expect?
here it stops behaving normally and does not display the checkout
{ showItem ? (
<Payment />
): (
<div> </div>
)}
the button call is correct because when I put an html <h1>Stripe checkout </h1>it appears but the checkout that brings via JS does not
How did you determine that? Those contents don't seem to align with the contents of the error messages shown in the console.
the button call is correct because when I put an html <h1>Stripe checkout </h1>it appears but the checkout that brings via JS does not
return (
<>
<div className="Payment">
<h1>Checkout Stripe</h1>
{clientSecret && stripePromise && (
<Elements stripe={stripePromise} options={{ clientSecret }}>
<CheckoutForm />
</Elements>
)}
</div>
</>
);
example
I'm not sure what you mean by that.
The contents of the error messages seem to directly align with the contents of the body of the requests that I shared. What I believe is happening is your endpoints (/create-payment-intent and /config) are responding to your fetch requests by providing HTML, but your code is expecting to be provided JSON data so when it tries to parse the response contents an error is encountered because the HTML contents cannot be parsed as JSON.
what can I do? I followed a youtube tutorial but when I implement it in my code it doesn't work..
You need to update the two portions of your code so they are aligned with regards to how they are expecting/providing data. You can modify your endpoints so that they respond with JSON data as your current code is expecting, or you can update the code that was shared here so that it is expecting and can handle HTML responses.
If this flow only needs to process payments, isn't customer-specific, and you don't need more advanced features on top of it, then Payment Links may be an easier alternative for this.
https://stripe.com/docs/payments/payment-links
They allow you create a link from your Stripe dashboard, which you can embed into your site/page that will redirect your customers to a Checkout Session when they access it.
I need the checkout to be on my page because I'm going to redirect to a completion page on my website where they can listen and download the songs.
where exactly do you think i should change the code?
Payment Links support this capability, they allow you to provide a URL for your customers to be redirected to upon checkout completion.
You can find that configuration in the After payment section during the Payment Link creation process.
That depends on how you want to approach the problem, and is a decision that you're best suited to make as the code owner.
yes but I want the payment to be made on my page, the payment link is made outside of it on the stripe site in another url
Gotcha.
I just want the payment to work on my page I don't want anything complex
Gotcha, so to do this without leaving your page, then you will need to build a Payment Element integration or work to debug your current one.
Our guide for building that process can be found here:
https://stripe.com/docs/payments/accept-a-payment?platform=web&ui=elements&client=react
I understand, if you could help me to fix what is ready it would be better, can you give me a tip on how I can do this?
Based on what I'm seeing you'll want to change one of the two places that I mentioned previously. Currently your React code is expecting JSON, and your endpoints are responding with HTML instead. You will need to update one of those pieces so that the two ends of that process are aligned on the structure of the data that they'll use to communicate with each other.
would i have to use json.stringify on the entire Home function that is exporting my react content which contains html?
I'm not sure Home function you're referring to, so I'm not sure.
Off-hand though, I don't think will work. I don't recall exactly, but I suspect calling JSON.stringify() for a string containing HTML the function will either error because it doesn't know how to parse the data, or return a JSON object that contains a single string which is still the full HTML that your code isn't designed to handle.
I understand, better to change the code here?
useEffect(() => {
fetch("/config").then(async (r) => {
const { publishableKey } = await r.json();
setStripePromise(loadStripe(publishableKey));
});
}, []);
useEffect(() => {
fetch("/create-payment-intent", {
method: "POST",
body: JSON.stringify({}),
}).then(async(result) => {
var { clientSecret } = await result.json();
setClientSecret(clientSecret);
});
I'm not sure which end is better to update, that's something that you would be better suited to judge as you own and know the code.
I don't know which parts of the code you're more confident are working as you want, and which pieces you understand more thoroughly and are comfortable modifying. If I was in your position I would be updating the /config and /create-payment-intent endpoints.
instead of receiving body: JSON.stringify({}),
I would change to receive the html content, I think it can work then?
req.body
No, those endpoints are the ones serving the HTML content, so I suggest you update what they respond with rather than what they are expecting to receive.
here? const { publishableKey } = await r.json(); await r.json this wrong?
No, that's the code that controls how to handle the response from your endpoints. I'm talking about updating the code that is running at those endpoints.
What does the code for your endpoints look like?
my body index
on show this is return
return (
<>
<div className="Payment">
{clientSecret && stripePromise && (
<Elements stripe={stripePromise} options={{ clientSecret }}>
<CheckoutForm />
</Elements>
)}
</div>
</>
);
finally this is the checkoutform
import { useEffect, useState } from "react";
import { useStripe, useElements } from "@stripe/react-stripe-js";
import { PaymentElement } from "@stripe/react-stripe-js";
export default function CheckoutForm() {
const stripe = useStripe();
const elements = useElements();
const [message, setMessage] = useState(null);
const [isProcessing, setIsProcessing] = useState(false);
const handleSubmit = async (e) => {
e.preventDefault();
if (!stripe || !elements) {
// Stripe.js has not yet loaded.
// Make sure to disable form submission until Stripe.js has loaded.
return;
}
setIsProcessing(true);
const { error } = await stripe.confirmPayment({
elements,
confirmParams: {
// Make sure to change this to your payment completion page
return_url: `${window.location.origin}/completion`,
},
});
if (error.type === "card_error" || error.type === "validation_error") {
setMessage(error.message);
} else {
setMessage("An unexpected error occured.");
}
setIsProcessing(false);
};
return (
<form id="payment-form" onSubmit={handleSubmit}>
<PaymentElement id="payment-element" />
<button disabled={isProcessing || !stripe || !elements} id="submit">
<span id="button-text">
{isProcessing ? "Processing ... " : "Pay now"}
</span>
</button>
{/* Show any error or success messages */}
{message && <div id="payment-message">{message}</div>}
</form>
);
}
Do you have endpoints built that are being hit when you make the fetch requests to /config and /create-payment-intent? They would be running on your backend-server.
I hit the following URLs, and the response to each one appears to be indentical:
https://martinguitarartist.com/create-payment-intent
https://martinguitarartist.com/config
https://martinguitarartist.com/
All of those seem to serve your page. The request to /config does not appear to be returning your publishable key as you're expecting it to, and /create-payment-intent is not returning the the client secret of a Payment Intent.
Martin Guitar Artist - Experience the psychedelic soundscapes of Martin Guitar Artist, the independent artist that trades in Psychedelic Rock.
Martin Guitar Artist - Experience the psychedelic soundscapes of Martin Guitar Artist, the independent artist that trades in Psychedelic Rock.
Martin Guitar Artist - Experience the psychedelic soundscapes of Martin Guitar Artist, the independent artist that trades in Psychedelic Rock.
this is my back end
const express = require("express");
const app = express();
const { resolve } = require("path");
// Replace if using a different env file or config
const env = require("dotenv").config({ path: "./.env" });
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY, {
apiVersion: "2022-08-01",
});
app.use(express.static(process.env.STATIC_DIR));
app.get("/", (req, res) => {
const path = resolve(process.env.STATIC_DIR + "/index.html");
res.sendFile(path);
});
app.get("/config", (req, res) => {
res.send({
publishableKey: process.env.STRIPE_PUBLISHABLE_KEY,
});
});
app.post("/create-payment-intent", async (req, res) => {
try {
const paymentIntent = await stripe.paymentIntents.create({
currency: "USD",
amount: 2,
automatic_payment_methods: { enabled: true },
});
// Send publishable key and PaymentIntent details to client
res.send({
clientSecret: paymentIntent.client_secret,
});
} catch (e) {
return res.status(400).send({
error: {
message: e.message,
},
});
}
});
app.listen(5252, () =>
console.log(Node server listening at http://localhost:5252)
);
because in my routes all links redirect to home
// import components
import { Home } from '../pages/Home/index';
import Payment from '../pages/Home/Payment';
import Completion from '../pages/Home/Completion';
const Routes = [
{ path: '/', exact: true, component: Home, Payment },
{ path: '/completion', exact: true, component: Completion},
//Pages error redirect home
{ path: '*', component: Home, Payment }
];
export { Routes };
can't i make this redirect * to home?
I'm not certain, but I don't think so. I think that is what is causing your requests to your backend endpoints to be routed to your home page instead.
Is it right that I just remove them? or do I have to add them here in the route too?
I'm not sure, we're pretty far from how Stripe functions at this point so my familiarity with what is being discussed is dropping. When I'm debugging I tend to prefer small incremental changes rather than changing a lot of things at once. I would suggest starting by removing your wildcard entry and see what the results of that are.
ready now other pages will no longer redirect to home, but the error still persists
Yup, I'm still seeing that those endpoints are responding with your page.
true the strangest that turn green are answering right
Is your Node/Express server actually running where your site is able to access it?
Is it being hosted on a different domain than your React code?
Martin Guitar Artist - Experience the psychedelic soundscapes of Martin Guitar Artist, the independent artist that trades in Psychedelic Rock.
dont
only the different ports
I was able to curl the http://martinguitarartist.com:5252/config successfully, and the response seems to include the publishable key as your code is expecting. I receive an error when trying to hit http://martinguitarartist.com:5252/create-payment-intent though.
Have you tried providing the full path for those endpoints in your fetch() statements?
So instead of:
fetch("/config")
what happens when you use:
fetch("http://martinguitarartist.com:5252/config")
yes, the key appears with config, and the create-payment-intent cannot get
Yup, your /create-payment-intent endpoint was configured to reject GET requests and only accept POST requests:
app.post("/create-payment-intent", async (req, res) => {
all well?
Huh?
all well? with the backend get and post? see something wrong?
app.get("/", (req, res) => {
const path = resolve(process.env.STATIC_DIR + "/index.html");
res.sendFile(path);
});
It's fine, you just need to make sure you're making the right type of request based on what the endpoint is expecting to receive.
the problem it is reading as html and it can't bring the checkout =/
function Payment(props) {
const [stripePromise, setStripePromise] = useState(null);
const [clientSecret, setClientSecret] = useState("");
useEffect(() => {
fetch("/config").then(async (r) => {
const { publishableKey } = await r.json();
setStripePromise(loadStripe(publishableKey));
});
}, []);
useEffect(() => {
fetch("/create-payment-intent", {
method: "POST",
body: JSON.stringify({}),
}).then(async (result) => {
var { clientSecret } = await result.json();
setClientSecret(clientSecret);
});
}, []);
What is reading as HTML? I thought you said providing the exact path caused the endpoints to begin responding with non-HTML content.
Those fetch statements are the same as what you've been sharing. Did you try making the change I suggested?
I say the button when you press it does not bring the checkout,
I haven't made any changes here yet, what would be more appropriate?
So you didn't try this?
Did you then change it back? Your most recent snippet does not include that change.
i im sorry now i understand one second building
look again
now change error in console log and network
function Payment(props) {
const [stripePromise, setStripePromise] = useState(null);
const [clientSecret, setClientSecret] = useState("");
useEffect(() => {
fetch("http://martinguitarartist.com:5252/config").then(async (r) => {
const { publishableKey } = await r.json();
setStripePromise(loadStripe(publishableKey));
});
}, []);
useEffect(() => {
fetch("/create-payment-intent", {
method: "POST",
body: JSON.stringify({}),
}).then(async (result) => {
var { clientSecret } = await result.json();
setClientSecret(clientSecret);
});
}, []);
after config is " but discord dont learn
Looks like your site is making that fetch request over HTTPS rather than HTTP, and that your backend is not yet configured to server HTTPS requests.
I understand how can I resolve this https issue? is it with the server? creating htaccess?
can you guide me on this please??
or in the fetch it would have to be https:// instead of http:// ?
Hey toby had to step out but I can try to help. Unfortunately we aren't really sure what the best path forward is here for you. This is entirely in your code and on your server so you're in the position to figure that out.
Have you considered hiring a developer here? They may be able to help you code these things and troubleshoot this kind of error.
I'm sorry but I can't do that, I have to solve everything myself the site I built everything myself
I'm trying to help with server support
Can you tell me anything else that might help?
Unfortunately we don't really have good advice there. This is pretty far outside the realm of a Stripe error. This does seem to be a more generic error though so you may have luck if you take this to Stack Overflow with info on this error and how that endpoint is configured on your server
I went back to this code, the get works but it doesn't bring the checkout, can you help me with something?
function Payment(props) {
const [stripePromise, setStripePromise] = useState(null);
const [clientSecret, setClientSecret] = useState("");
useEffect(() => {
fetch("/config").then(async (r) => {
const { publishableKey } = await r.json();
setStripePromise(loadStripe(publishableKey));
});
}, []);
useEffect(() => {
fetch("/create-payment-intent", {
method: "POST",
body: JSON.stringify({}),
}).then(async (result) => {
var { clientSecret } = await result.json();
setClientSecret(clientSecret);
});
}, []);
Can you get the Payment to show up otherwise?
Like if you make a page that is just that and provide the clientSecret right off the bat, does it seem the same error?
anything wrong in this checkout form?
import { useEffect, useState } from "react";
import { useStripe, useElements } from "@stripe/react-stripe-js";
import { PaymentElement } from "@stripe/react-stripe-js";
export default function CheckoutForm() {
const stripe = useStripe();
const elements = useElements();
const [message, setMessage] = useState(null);
const [isProcessing, setIsProcessing] = useState(false);
const handleSubmit = async (e) => {
e.preventDefault();
if (!stripe || !elements) {
// Stripe.js has not yet loaded.
// Make sure to disable form submission until Stripe.js has loaded.
return;
}
setIsProcessing(true);
const { error } = await stripe.confirmPayment({
elements,
confirmParams: {
// Make sure to change this to your payment completion page
return_url: `${window.location.origin}/completion`,
},
});
if (error.type === "card_error" || error.type === "validation_error") {
setMessage(error.message);
} else {
setMessage("An unexpected error occured.");
}
setIsProcessing(false);
};
return (
<form id="payment-form" onSubmit={handleSubmit}>
<PaymentElement id="payment-element" />
<button disabled={isProcessing || !stripe || !elements} id="submit">
<span id="button-text">
{isProcessing ? "Processing ... " : "Pay now"}
</span>
</button>
{/* Show any error or success messages */}
{message && <div id="payment-message">{message}</div>}
</form>
);
}
It this is a Stripe error I can help but if this is still generic react stuff we can't really help
Similar question, can you make a page that is just the Checkout form and does it show up then?
I can try on a page without any content to bring only the checkout
I think that would definitely be helpful in narrowing down the problme
It is a great debugging technique in general. Cut out all of the code that you can while still getting the issue
yes it is true, i will try here
Martin Guitar Artist - Experience the psychedelic soundscapes of Martin Guitar Artist, the independent artist that trades in Psychedelic Rock.
dont works only bring Payment
That page has the same problem as you started with, your front and back-ends are not successfully communicating with each other.
yes bro not in homepage error
I'm not sure what this means.
if you have any more suggestions please let me know
I don't really, your code is breaking before it can even initialize Stripe. Based on what I'm seeing currently that is because your frontend code is expecting to receive JSON data, but your fetch requests aren't pointing to your backend (since you reverted the change I suggested) and are once again receiving your frontend site instead of getting a response from your backend server. You'll need to debug how you have built your ends to communicate with each other before you can successfully build a Stripe integration on top of that.