#huncsuga_code
1 messages · Page 1 of 1 (latest)
👋 Welcome to your new thread!
⏲️ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.
⏱️ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.
🔗 This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1422867643366641684
📝 Have more to share? Add more details, code, screenshots, videos, etc. below.
hi there! can you confirm whether you've already mounted the Payment Element to a DOM node as described here:
if so, but the error still happens, could you share the code where you've done that?
form:
<form
x-data="stripeCheckoutForm({
stripePublicKey: @js($this->stripePublicKey),
amount: @js($this->total),
currency: @js($this->currency)
})"
id="payment-form"
<div id="payment-element"></div>
<div id="error-message"></div>
</form>
js:
const options = {
mode: 'payment',
amount: data.amount,
currency: data.currency,
paymentMethodCreation: 'manual',
paymentMethodTypes: ['card'],
};
const options = window.StripeFormOptions(data);
const paymentElementOptions = window.StripePaymentElementOptions();
const appearance = window.StripeAppearance();
this.elements = this.stripe.elements({
...options,
appearance,
});
this.paymentElement = this.elements.create('payment', paymentElementOptions);
this.paymentElement.mount('#payment-element');
thanks, looking into this now
hmm, not seeing any problems there
are you able to share a link to the page you're testing this on, so we can reproduce the issue on our side and debug further?
Unfortunately I can’t share a public link — this is only running locally right now (not deployed to any cloud environment).
no problem! still looking into this
checking your code again, code, I see that the elements.submit and the createConfirmationToken are being called directly when the element is created/mounted
these calls should be done later (.e.g in a click handler), and not directly after mounting the element, since the idea is for the confirmation token to be created when the customer provides their payment details to the payment element
The init
init() {
this.stripe = Stripe(data.stripePublicKey);
window.addEventListener('stripe-card:submit', async (e) => {
const res = await this.submitStripe();
if (res?.ok) {
window.dispatchEvent(new CustomEvent('stripe-card:ok', {
detail: { token: res.token }
}));
}
});
const options = window.StripeFormOptions(data);
const paymentElementOptions = window.StripePaymentElementOptions();
const appearance = window.StripeAppearance();
this.elements = this.stripe.elements({
...options,
appearance,
});
this.paymentElement = this.elements.create('payment', paymentElementOptions);
this.paymentElement.mount('#payment-element');
},
The click handler:
async submitStripe() {
try {
const billing = await $wire.fetchBillingDetails();
if (!billing || Object.keys(billing).length === 0) {
this.showError('Billing details are missing');
return { ok: false, message: 'Billing details are missing' };
}
const { error: submitError } = await this.elements.submit();
console.log('cool');
if (submitError) {
this.showError(submitError.message);
return { ok: false, message: submitError.message };
}
console.log('cool2');
const { error, confirmationToken } = await this.stripe.createConfirmationToken({
elements: this.elements,
params: {
payment_method_data: {
billing_details: {
name: 'TEST',
email: 'test@gmail.com',
address: {
country: 'RO',
postal_code: '535600',
state: 'HARGHITA',
city: 'TEST city',
line1: 'Some street 123',
},
}
}
}
});
console.log('error', error);
if (error) {
this.showError(error.message);
return { ok: false, message: error.message };
}
return { ok: true, token: confirmationToken.id };
} catch (error) {
this.showError(error?.message);
return { ok: false, message: error?.message };
}
},
Both elements.submit and createConfirmationToken are being called inside a click handler, not on mount.
ok thanks for clarifying
we're still looking into this
I'm afraid it's not really possible for us to reproduce with just the code you've shared
could you please share a complete minimal project, or a hosted endpoint (with non minified JS so that we can debug)?
I think I’ve found the problem — it’s inside this if block. When this condition is present, something breaks for some reason:
const billing = await $wire.fetchBillingDetails();
if (!billing || Object.keys(billing).length === 0) {
this.showError('Billing details are missing');
return { ok: false, message: 'Billing details are missing' };
}
👋 taking over for my colleague. Let me catch up.
so basically what you're saying is that this is not Stripe related