#jojilede-setupintent-confirmation
1 messages ยท Page 1 of 1 (latest)
jojilede-setupintent-confirmation
Hey @compact pilot you say you create a SetupIntent, but the error says "No such payment_intent" which tells me you must be calling the wrong method likely client-side
can you share your exact code?
ok, sure:
api/payment/create-setup-intent.ts:
import Stripe from 'stripe';
const stripe = new Stripe(process.env.NEXT_PUBLIC_STRIPE_SECRET_KEY_TEST, {
apiVersion: '2022-11-15',
});
export default async function createSetupIntent(req, res) {
try {
const setupIntent = await stripe.setupIntents.create({
customer: req.body.customerId,
payment_method_types: req.body.payment_method_types,
usage: 'off_session'
});
res.json({client_secret: setupIntent.client_secret});
} catch (err) {
res.status(500).json({statusCode: 500, message: err.message});
}
}
okay so that creates a SetupIntent
component using it:
useEffect( () => {
(async () => {
const response = await axios.post('/api/payment/create-setup-intent', {
body: {
customerId: loggedUserData.GetLoggedUser?.UserProfile?.StripeCustomerId,
},
payment_method_types: ['bancontact', 'card', 'ideal']
});
setClientSecret(response.data.client_secret)
})();
}, [])
return (
<Layout>
{
clientSecret && (
<Elements
stripe={props.stripePromise}
options={{
clientSecret,
appearance:
{
theme: 'flat',
variables: {
colorPrimary: '#0570de',
colorBackground: '#ffffff',
colorText: '#30313d',
colorDanger: '#df1b41',
fontFamily: 'Ideal Sans, system-ui, sans-serif',
spacingUnit: '2px',
borderRadius: '4px',
}
}
}} >
<CheckoutForm />
</Elements>
)
}
</Layout>
CheckoutForm:
import {useStripe, useElements, PaymentElement} from '@stripe/react-stripe-js';
const CheckoutForm = () => {
const stripe = useStripe();
const elements = useElements();
const handleSubmit = async (event: React.FormEvent<HTMLFormElement>) => {
// We don't want to let default form submission happen here,
// which would refresh the page.
event.preventDefault();
if (!stripe || !elements) {
// Stripe.js has not yet loaded.
// Make sure to disable form submission until Stripe.js has loaded.
return;
}
const result = await stripe.confirmPayment({
//`Elements` instance that was used to create the Payment Element
elements,
confirmParams: {
return_url: "/customer-payments",
},
});
if (result.error) {
// Show error to your customer (for example, payment details incomplete)
console.log(result.error.message);
} else {
// Your customer will be redirected to your `return_url`. For some payment
// methods like iDEAL, your customer will be redirected to an intermediate
// site first to authorize the payment, then redirected to the `return_url`.
}
};
return (
<form onSubmit={handleSubmit}>
<PaymentElement />
<button disabled={!stripe}>Submit</button>
</form>
)
};
export default CheckoutForm;
okay so here you call confirmPayment() but you created a SetupIntent so you want confirmSetup instead https://stripe.com/docs/js/setup_intents/confirm_setup I think
haha! checking now
do I just replace the confirmPayment with confirmSetup? and the rest is the same?
mostly yes
I wish it "just worked" with one method so that you never had to think about it. One day!
nice! it gave me new error now can you help me again?
If you share the exact error and relevant details yes ๐
thanks,:
{
"code": "url_invalid",
"doc_url": "https://stripe.com/docs/error-codes/url-invalid",
"message": "Not a valid URL",
"param": "return_url",
"request_log_url": "https://dashboard.stripe.com/test/logs/req_QmD5ysJSeOJVET?t=1673635271",
"setup_intent": {
"id": "seti_1MPsBQDTISXyBnp6m1p7PviB",
"object": "setup_intent",
"cancellation_reason": null,
"client_secret": "seti_1MPsBQDTISXyBnp6m1p7PviB_secret_NACawQYkDVh5Gu4RVFBQKRS4yjGqioQ",
"created": 1673635256,
"description": null,
"last_setup_error": null,
"livemode": false,
"next_action": null,
"payment_method": null,
"payment_method_types": [
"bancontact",
"card",
"ideal"
],
"status": "requires_payment_method",
"usage": "off_session"
},
"type": "invalid_request_error"
}
got that preview return.
btw the return_url: "/customer-payments"
and it's the same as to where this url is
that feels fairly self explanatory right?
I mean /aaaa is not a URL. A URL is https://stripe.com/aaaa
basically you have to be explicit and pass a full URL, you can't just pass a relative URL
yeah common misunderstanding ๐
so now I had to create an env variable for localhost like usual or you have other recommendation?
I don't really understand what that could mean
you could use window.location.hostname for example and append the route?
I was just explaining and typing that as option and you beat me into it haha
๐
so it will really do a full page reload.
it's a full page redirect yes
I see, it's ok tho ๐ Thanks for helping! you're one of my favorite.
LOL thank you. We'll see if that lasts as you talk to more people on my team :p
haha! I don't want to eat more of your time. Thank you so much!
Have a great rest of the day!