#arnaud5356
1 messages · Page 1 of 1 (latest)
Hi, let me help you with this.
What do you mean by "subscription"? Like Stripe pricing? If so, I don't know, it's best to ask Stripe Support: https://support.stripe.com/?contact=true
Also, if you build a new integration I strongly recommend to use Payment Element instead of card: https://stripe.com/docs/payments/accept-a-payment?platform=web&ui=elements
Really ? But Why ? Im working on a Create React App project
And Im located in France
I already have this in my stripe.js :
exports.createPaymentIntent = functions.https.onRequest(async (req, res) => {
try {
// Extrayez le nom du titulaire de la carte et l'adresse e-mail du corps de la demande
const { cardholderName, email, totalAmount } = req.body;
console.log("Total amount received from front-end:", totalAmount); // Vérifiez que la valeur est correcte ici
// Créez un PaymentIntent avec Stripe
const paymentIntent = await stripe.paymentIntents.create({
amount: totalAmount, // Montant en cents (par exemple, 10,00 $)
currency: "eur",
payment_method: "pm_card_visa",
billing_details: {
name: cardholderName,
email: email,
// Autres informations de facturation si nécessaire
},
});
res.json({ clientSecret: paymentIntent.client_secret });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
This doesn't matter. The Card Element is much more limited, and Payment Element supports all the available payment method types out of the box and allows you to control it from the Dashboard. You can follow the guide I shared above to understand it better.
It shouldn't be a complex change.
ok Im gonna check it out but I admit its hard to understand for me (Im junior dev lol)
I can help you. What parts are not clear exactly?
I mean you are basically saying I should replace this :
<CardElement
options={{
style: {
base: {
fontSize: "14px",
},
},
}}
/>
By this :
<PaymentElement />
<button>Submit</button>
</form>
That correct ?
I don't know how your rest of the code looks, so it's hard to say. Yes, that's one of the changes. Just try to go carefully through the guide and let me know if any of the parts are not clear.
Well, its pretty straight forward.
I have a stripe.js file which look like this :
const functions = require("firebase-functions");
const admin = require("firebase-admin");
const stripe = require("stripe")(
"sk_test_VALUE_OF_MY_KEY"
);
admin.initializeApp();
exports.createPaymentIntent = functions.https.onRequest(async (req, res) => {
try {
// Extrayez le nom du titulaire de la carte et l'adresse e-mail du corps de la demande
const { cardholderName, email, totalAmount } = req.body;
console.log("Total amount received from front-end:", totalAmount); // Vérifiez que la valeur est correcte ici
// Créez un PaymentIntent avec Stripe
const paymentIntent = await stripe.paymentIntents.create({
amount: totalAmount, // Montant en cents (par exemple, 10,00 $)
currency: "eur",
payment_method: "pm_card_visa",
billing_details: {
name: cardholderName,
email: email,
// Autres informations de facturation si nécessaire
},
});
res.json({ clientSecret: paymentIntent.client_secret });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
And then my child component look like that :
Is that ok in your mind ?
Ive tried payments successfully on my dashboard in test mode
I think this is functional, right ?
I deleted it since it contained your publishable key.
oh yes sorry
I can't review all of your code right now, sorry. But I can help with specific things you wish to understand better, or that are not working.
For example I've just tried to replace my CardElement with PaymentElement, and I have this error :
ERROR
In order to create a payment element, you must pass a clientSecret or mode when creating the Elements group.
and in my parent component I have this :
<Elements stripe={stripePromise}>
<CheckOutForm cartItems={cartItems} />
</Elements>
In the guide you will see where you should place the client_secret: https://stripe.com/docs/payments/accept-a-payment?platform=web&ui=elements#add-and-configure-the-elements-provider-to-your-payment-page
ok thx
well I dont understand because in my parent component I already have
stripe={stripePromise}
Which corresponds to
const stripePromise = loadStripe(
"pk_test_VALUE_OF_MY_KEY"
);
I know it requires an unexpected effort from you, but it's better to invest in this now, than having to migrate when your app grows bigger.
That's your account publishable key. And the client secret is related to the specific PaymentIntent, you have to create it on the backend: https://stripe.com/docs/payments/accept-a-payment?platform=web&ui=elements#retrieve-the-client-secret
well thats a problem because I dont use a backend in my project !
I only use firebase to store my products, which means I dont use Express or any other backend...
So I might just keep my CardElement that was working in the first place
How can your app work without a backend?
Your app is using this backend code and is already creating a PaymentIntent, and even sending the client_secret.
I just upload my products from firebase on my frontend, and thats it
So essentially, you need to just retrieve the client_secret on your frontend and use it in the correct place.
well ok. this is my file stripe.js where there is my clientsecret :
admin.initializeApp();
exports.createPaymentIntent = functions.https.onRequest(async (req, res) => {
try {
// Extrayez le nom du titulaire de la carte et l'adresse e-mail du corps de la demande
const { cardholderName, email, totalAmount } = req.body;
console.log("Total amount received from front-end:", totalAmount); // Vérifiez que la valeur est correcte ici
// Créez un PaymentIntent avec Stripe
const paymentIntent = await stripe.paymentIntents.create({
amount: totalAmount, // Montant en cents (par exemple, 10,00 $)
currency: "eur",
payment_method: "pm_card_visa",
billing_details: {
name: cardholderName,
email: email,
// Autres informations de facturation si nécessaire
},
});
res.json({ clientSecret: paymentIntent.client_secret });
} catch (error) {
res.status(500).json({ error: error.message });
}
});
This is backend code (given you use the secret key), and it might be firebase function, not express. It doesn't matter.
I need to recover my clientsecret and I pass it to the Elements ?
or into PaymentElement ?
like this ?
client_secret = {client_secret}
The guide explains this.
If I'd understand the guide I woudnt be asking to you lol
I recommend you to step away from your own code for a moment, give it a read, and you will have a much better understanding of the flow.
I think this is what Im looking for maybe ?
// Retrieve the "payment_intent_client_secret" query parameter appended to
// your return_url by Stripe.js
const clientSecret = new URLSearchParams(window.location.search).get(
'payment_intent_client_secret'
);
As I shared before, the clientSecret goes into the options attribute of the Elements component: https://stripe.com/docs/payments/accept-a-payment?platform=web&ui=elements#add-and-configure-the-elements-provider-to-your-payment-page
Yes, here's where you retrieve the clientSecret on your frontend.
<Elements stripe={stripePromise} options={{clientSecret: '{{CLIENT_SECRET}}'}}>
mmm well ok thx Im gonna study the documentation but I find it complicated as my CardElement seems to already be working, why should I use PaymentElement ?
OK thanks you 😉
as my CardElement seems to already be working, why should I use PaymentElement ?
Please can you tell me why
what do I gain from using PaymentElement instead of CardElement ?
ok because it accept google pay and apple pay right ?
Payment Element is the current standard integration as supports all the available payment method types, you can also control it via the Dashboard. Card Element is legacy, and is only supported for existing integrations. If you're building a new integration, it's a waste of future resources to use the card element, as you will need perform the migration anyway in the future, when it will be much more costly.
Well ok, Im ok to try to change it for PaymentElement.
But please, when you say this :
<Elements stripe={stripePromise} options={{clientSecret: '{{CLIENT_SECRET}}'}}>
Can you just give me the lines of code I should had into my composant to retrieve my client secret without using express, because in the documentation there is this :
const express = require('express');
const app = express();
app.get('/secret', async (req, res) => {
const intent = // ... Fetch or create the PaymentIntent
res.json({client_secret: intent.client_secret});
});
app.listen(3000, () => {
console.log('Running on port 3000');
});
And as you know I am NOT using Express ...
You are already all set on your backend, so you just need to correctly use the fetched data on your frontend.
Okay, so basically Ill need to had something like this to my parent component :
const [clientSecret, setClientSecret] = useState("");
useEffect(() => {
const fetchClientSecret = async () => {
// Remplace 'YOUR_FUNCTION_URL' par l'URL de ta fonction cloud
const response = await fetch('https://us-central1-your-project-id.cloudfunctions.net/your-function-name');
const data = await response.json();
setClientSecret(data.clientSecret);
};
fetchClientSecret();
}, []);
And then Ill juste had the clientSecret prop to my child component right ?
Oh, I actually think you might be using the deferred PaymentIntent flow: https://stripe.com/docs/payments/accept-a-payment-deferred?platform=web&type=payment