#yen6305
1 messages ยท Page 1 of 1 (latest)
๐ happy to help
would you mind sharing an example? a Payment Intent ID, a screenshot and your code
Yeah ofcourse
create-payment-intent.js:
// The Payment intent API tracks a payment from creation through checkout, and triggers additional authentication steps when required.
import axios from 'axios'; // Import Axios
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);
const fetchCartData = async (cartKey) => {
try {
const response = await axios.get(
`${process.env.NEXT_PUBLIC_WP_API_URL}/wp-json/cocart/v2/cart?cart_key=${cartKey}`
);
return response.data;
} catch (error) {
throw new Error("Error fetching cart data: " + error.message);
}
};
export default async function handler(req, res) {
const { cartKey, metadata } = req.body;
if (!cartKey) {
throw new Error("Cart key is missing.");
}
// Fetch the cart data using the CoCart Lite API
const cartData = await fetchCartData(cartKey);
// Calculate the total amount based on line items in the cart data (items is seen as a line item)
// Line item is an item that has been placed in a cart. In this case only the SSG - Striking Strings Glissando is in the cart with a quantity.
const totalAmount = cartData.items.reduce((accumulator, item) => {
const quantity = item.quantity.value;
const price = parseFloat(item.price);
return accumulator + quantity * price;
}, 0);
const paymentIntent = await stripe.paymentIntents.create({
amount: totalAmount,
currency: "eur",
payment_method_types: ['ideal', 'card', 'paypal'],
// capture_method: 'manual',
// automatic_payment_methods: {
// enabled: true,
// },
metadata: metadata,
});
res.send({
clientSecret: paymentIntent.client_secret,
paymentIntentId: paymentIntent.id,
});
};
checkout.js:
import React, { useContext, useState, useEffect } from 'react';
import { CartContext } from '../components/Context/CartContext';
import Layout from '../components/layout';
import { Container } from 'react-bootstrap';
import CheckoutContainer from '../components/Checkout/CheckoutContainer/CheckoutContainer';
import { loadStripe } from '@stripe/stripe-js';
import { Elements } from '@stripe/react-stripe-js';
const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY);
export default function Checkout() {
const [cart, setCart ] = useContext(CartContext);
const [grandTotal, setGrandTotal] = useState(0);
const [grandTotalFetched, setGrandTotalFetched] = useState(false); // New state variable
useEffect(() => {
if (cart && cart.items) {
// Calculate grand total
const newGrandTotal = cart.items.reduce(
(total, item) => total + item.quantity * item.price,
0
);
setGrandTotal(newGrandTotal);
}
}, [cart]);
if(!grandTotal) {
return;
}
const appearance = {
theme: 'stripe',
};
const options = {
// clientSecret,
appearance,
mode: 'payment',
amount: grandTotal,
currency: 'eur',
paymentMethodTypes: ['ideal', 'card', 'paypal'],
};
return (
<Layout>
<Container>
<Elements options={options} stripe={stripePromise}>
<CheckoutContainer />
</Elements>
</Container>
</Layout>
)
}
I am using the PaymentElement
you're passing payment_method_types: ['ideal', 'card', 'paypal'],
Yeah i put it back
so it's normal to have them in this order
But i just changed the order
And it doesn't work
Yeah but my client requested to change the order
Is there a way to change it?
to handle this better
Okay, i've tried it but it still doesn't work:
import React, { useContext, useState, useEffect } from 'react';
import { CartContext } from '../components/Context/CartContext';
import Layout from '../components/layout';
import { Container } from 'react-bootstrap';
import CheckoutContainer from '../components/Checkout/CheckoutContainer/CheckoutContainer';
import { loadStripe } from '@stripe/stripe-js';
import { Elements } from '@stripe/react-stripe-js';
const stripePromise = loadStripe(process.env.NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY);
export default function Checkout() {
const [cart, setCart ] = useContext(CartContext);
const [grandTotal, setGrandTotal] = useState(0);
const [grandTotalFetched, setGrandTotalFetched] = useState(false); // New state variable
useEffect(() => {
if (cart && cart.items) {
// Calculate grand total
const newGrandTotal = cart.items.reduce(
(total, item) => total + item.quantity * item.price,
0
);
setGrandTotal(newGrandTotal);
}
}, [cart]);
if(!grandTotal) {
return;
}
const appearance = {
theme: 'stripe',
};
const options = {
// clientSecret,
appearance,
mode: 'payment',
amount: grandTotal,
currency: 'eur',
paymentMethodTypes: ['card', 'ideal', 'paypal'],
paymentMethodOrder: ['card', 'ideal', 'paypal'],
};
return (
<Layout>
<Container>
<Elements options={options} stripe={stripePromise}>
<CheckoutContainer />
</Elements>
</Container>
</Layout>
)
}
don't add paymentMethodTypes
I removed paymentMethodTypes and now only the 'card' is visible
it removed ideal and paypal
const options = {
// clientSecret,
appearance,
mode: 'payment',
amount: grandTotal,
currency: 'eur',
// paymentMethodTypes: ['card', 'ideal', 'paypal'],
paymentMethodOrder: ['card', 'ideal', 'paypal'],
};
Oh you're using the deferred flow?
Yes
my bad
No my bad I forgot to tell u
I should have known, it's just super busy on discord today
Hi there ๐ jumping in as my teammate needs to step away soon. I'm going to try to reproduce this on my test site, but in the meantime, do you have a publicly accessible site where you're testing this that you can share?
paymentMethodOrder is the right field to be using for that.
Oh, maybe they're defined in the wrong spot.
Hi, I do have a publicly accessible site but its not working properly right now, so I can't show it
The wrong spot?
Yeah, I think so. I'm a little less familiar with React, but it looks like you're passing those as options to the Elements instance, but they need to be passed to the Payment Element instance instead.
I'm not seeing the Payment Element in the code that you shared, so I'm guessing it's inside of your CheckoutContainer?
You'll want to pass paymentMethodOptions as part of the options that are passed to the PaymentElement:
https://stripe.com/docs/stripe-js/react#element-components