#huncsuga_code

1 messages · Page 1 of 1 (latest)

agile rampartBOT
#

👋 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.

young barn
#

if so, but the error still happens, could you share the code where you've done that?

frigid delta
#

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');
young barn
#

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?

frigid delta
#

Unfortunately I can’t share a public link — this is only running locally right now (not deployed to any cloud environment).

young barn
#

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

frigid delta
#

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.

young barn
#

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)?

agile rampartBOT
frigid delta
#

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' };
}

steady zealot
#

👋 taking over for my colleague. Let me catch up.

#

so basically what you're saying is that this is not Stripe related

agile rampartBOT