【问题标题】:I'm getting an unmounted Element error when trying to set up a Payment Intent with Stripe尝试使用 Stripe 设置付款意图时出现未安装元素错误
【发布时间】:2024-01-11 03:29:01
【问题描述】:

我正在尝试使用 Stripe 和 Laravel Cashier (V10) 设置付款意图,但出现以下错误:

We could not retrieve data from the specified Element. Please make sure the Element you are attempting to use is still mounted.

我只能假设由于某种原因该元素正在从 DOM 中删除,但我不知道为什么。

<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name') }}</title>
    <link rel="shortcut icon" href="/assets/img/favicon.png">


    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>

    <!-- Fonts -->
    <link rel="dns-prefetch" href="//fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css?family=Roboto&display=swap" rel="stylesheet">

    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
<div id="app">
    <main>

        <div class="h-screen flex flex-col">
            <div class="bg-white text-text text-xs border-b border-trim h-16 font-light flex items-center
            px-5 justify-between">
                <div class="w-1/3 flex text-primary">
                    <button class="focus:outline-none">
                        <a href="/home">
                            <i class="fas fa-home fa-2x"></i>
                        </a>
                    </button>
                </div>
                <div class="w-1/3 flex justify-center py-2">
                    <img style="height: 40px" src="{{ asset('assets/img/Logo.svg') }}" alt="">
                </div>
                <div class="w-1/3 flex text-primary justify-end">
                    <shar-nav-dropdown></shar-nav-dropdown>
                </div>
            </div>
            <div class="flex flex-col flex-grow w-full bg-background p-2 md:p-12 md:px-48 items-center">
                <div class="flex flex-col items-center mt-6 md:mt-0 justify-start md:justify-center w-full px-6 md:px-0 md:w-1/2 h-full">
                    <div class="text-xl md:text-4xl font-thin text-primary mb-6">
                        Enter your payment details to activate your <span class="capitalize font-bold">{{$plan}}</span> plan.
                    </div>

                    <form onsubmit="submitForm(this)" id="payment-form" class="w-full">
                    @csrf

                    <!-- Stripe Elements Placeholder -->
                        <div id="card-element" class="border border-trim w-full rounded border-backgroundAccent bg-white focus:border-primary mb-3 outline-none
                                       px-4 py-2 text-black placeholder-text text-sm">
                        </div>

                        <!-- Used to display form errors. -->
                        <div id="card-errors" role="alert" class="-mt-2 text-sm text-error mb-3"></div>
                        <input type="hidden" name="plan" value="{{ $plan }}"/>

                        <!-- Pay button. -->
                        <button id="card-button" type="submit" class="w-full py-2 bg-primary rounded text-white hover:bg-primaryAlt focus:outline-none text-sm"
                                data-secret="{{
                            $intent->client_secret }}">
                            Securely Pay
                        </button>
                    </form>
                </div>
            </div>
        </div>
    </main>
</div>
</body>
<script src="https://js.stripe.com/v3/"></script>

<script>
    const stripe = Stripe('{{ env("STRIPE_KEY") }}'); // Create a Stripe client.
    const elements = stripe.elements(); // Create an instance of Elements.
    const cardElement = elements.create('card'); // Create an instance of the card Element.
    const cardButton = document.getElementById('card-button');
    const clientSecret = cardButton.dataset.secret;
    cardElement.mount('#card-element'); // Add an instance of the card Element into the `card-element` <div>.

    // Handle real-time validation errors from the card Element.
    cardElement.addEventListener('change', function (event) {
        var displayError = document.getElementById('card-errors');
        if (event.error) {
            displayError.textContent = event.error.message;
        } else {
            displayError.textContent = '';
        }
    });

    // Handle form submission
    const form = document.getElementById('payment-form');

    function submitForm() {
        stripe.confirmCardSetup(
            clientSecret,
            {
                payment_method: {
                    card: cardElement,
                    // billing_details: {name: cardholderName.value}
                }
            }
        ).then(function (result) {
            console.log(result);
            if (result.error) {
                // Inform the user if there was an error.
                var errorElement = document.getElementById('card-errors');
                errorElement.textContent = result.error.message;
            } else {
                console.log(result);
                // Send the token to your server.
                stripeTokenHandler(result.setupIntent.payment_method);
            }
        });
    }

    // Submit the form with the token ID.
    function stripeTokenHandler(paymentMethod) {
        console.log('Handling...');
        // Insert the token ID into the form so it gets submitted to the server
        var form = document.getElementById('payment-form');
        var hiddenInput = document.createElement('input');
        hiddenInput.setAttribute('type', 'hidden');
        hiddenInput.setAttribute('name', 'paymentMethod');
        hiddenInput.setAttribute('value', paymentMethod);
        form.appendChild(hiddenInput);

        // Submit the form
        form.submit();
    }
</script>
</html>

submitForm() 中的cardElement 好像找不到了。如果我打开 Chrome 开发工具并输入 cardElement 我可以看到该对象,但如果我在函数顶部添加一个 console.log(cardElement) 则似乎打印了一个空对象。这可能与我使用&lt;form onsubmit="submitForm()"&gt; 的事实有关吗?也许它在分配之前正在评估?

任何帮助将不胜感激!

【问题讨论】:

  • 您是否从错误中获得了更多信息,例如错误是由哪个元素和哪一行产生的?
  • 道歉,补充。

标签: javascript laravel stripe-payments laravel-cashier


【解决方案1】:

这是由于 Vue 组件将自身附加到根 div。删除解决了它。

【讨论】:

    最近更新 更多