'Stripe not working with error 'Uncaught (in promise) Error: We could not retrieve data from the specified Element.'

I am trying to use Stripe.js following https://stripe.com/docs/stripe-js/elements/quickstart

I made html, css, javascript just same as sample of that url.

But when I click 'Submit Payment' Button, it always shows console error and not working.

(index):1 Uncaught (in promise) Error: We could not retrieve data from the specified Element.
              Please make sure the Element you are attempting to use is still mounted.
    at new t ((index):1)
    at e._handleMessage ((index):1)
    at e._handleMessage ((index):1)
    at (index):1

Please let me know why this happens.



Solution 1:[1]

Please try this. It works.

<html>
    <head>
        <style>
            /**
            * The CSS shown here will not be introduced in the Quickstart guide, but shows
            * how you can use CSS to style your Element's container.
            */
            .StripeElement {
            box-sizing: border-box;

            height: 40px;

            padding: 10px 12px;

            border: 1px solid transparent;
            border-radius: 4px;
            background-color: white;

            box-shadow: 0 1px 3px 0 #e6ebf1;
            -webkit-transition: box-shadow 150ms ease;
            transition: box-shadow 150ms ease;
            }

            .StripeElement--focus {
            box-shadow: 0 1px 3px 0 #cfd7df;
            }

            .StripeElement--invalid {
            border-color: #fa755a;
            }

            .StripeElement--webkit-autofill {
            background-color: #fefde5 !important;
            }
        </style>
    </head>
    <body>
        <script src="https://js.stripe.com/v3/"></script>

        <form action="/charge" method="post" id="payment-form">
            <div class="form-row">
            <label for="card-element">
                Credit or debit card
            </label>
            <div id="card-element">
                <!-- A Stripe Element will be inserted here. -->
            </div>
        
            <!-- Used to display form errors. -->
            <div id="card-errors" role="alert"></div>
            </div>
        
            <button>Submit Payment</button>
        </form>
            
        <script>
            // Create a Stripe client.
            var stripe = Stripe('pk_test_XzLQCcuHS0Qc5xPIARiG8aNU');

            // Create an instance of Elements.
            var elements = stripe.elements();

            // Custom styling can be passed to options when creating an Element.
            // (Note that this demo uses a wider set of styles than the guide below.)
            var style = {
                base: {
                    color: '#32325d',
                    fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
                    fontSmoothing: 'antialiased',
                    fontSize: '16px',
                    '::placeholder': {
                    color: '#aab7c4'
                    }
                },
                invalid: {
                    color: '#fa755a',
                    iconColor: '#fa755a'
                }
            };

            // Create an instance of the card Element.
            var card = elements.create('card', {style: style});

            // Add an instance of the card Element into the `card-element` <div>.
            card.mount('#card-element');

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

            // Handle form submission.
            var form = document.getElementById('payment-form');
            form.addEventListener('submit', function(event) {
                event.preventDefault();

                stripe.createToken(card).then(function(result) {
                    if (result.error) {
                    // Inform the user if there was an error.
                    var errorElement = document.getElementById('card-errors');
                    errorElement.textContent = result.error.message;
                    } else {
                    // Send the token to your server.
                    stripeTokenHandler(result.token);
                    }
                });
            });

            // Submit the form with the token ID.
            function stripeTokenHandler(token) {
                // 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', 'text');
                // hiddenInput.setAttribute('name', 'stripeToken');
                // hiddenInput.setAttribute('value', token.id);
                // form.appendChild(hiddenInput);
                alert('Success! Got token: ' + token.id);

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

Note that both the fix and the cause is the call:

stripe.createToken(card)

I mean, this happens if we try to submit with wrong create prefixed method, and while for above createToken works, it may not for other stripe-elements and/or API configurations.

Solution 2:[2]

I've had this problem when switching between mobile and desktop screen sizes - the cutoff size where Stripe only displays the last 4 digits of the card number. If I refresh the page in the new resolution it works.

If this description fits your problem you might be able to mount the element again after the size change, or you'll have to recreate it.

Solution 3:[3]

If you're seeing this in React code, these links might help: https://github.com/stripe/react-stripe-elements/issues/55#issuecomment-326707827 https://github.com/stripe/react-stripe-elements#troubleshooting

Essentially the stripe elements in react use the higher order component pattern. If a HOC that uses shouldComponentUpdate wraps the injectStripe function, create token won't be able to find the ref to stripe elements. Make injectStripe the outer most HOC

Example:

  connect()(injectStripe(YourComponent))
  Becomes
  injectStripe(connect()(YourComponent))

Solution 4:[4]

Disclaimer: I know this question has been answered, but I had the same issue with duplicate scripts inclusions due to merging. Since this is the first page I got when looking up my problem I felt that this would be a good place to leave this information.

A) If it is functioning and the token is created (console.log or check stripe dashboard), please be sure to check that Stripe.js was not included twice.

B) If you are using Angular (an analogy probably exists for React), I had a very easy time implementing stripe through the use of the ngx-stripe module.

Feel free to ask more specific questions. I've had to implement the base one from quick-start which was overall hell.

Solution 5:[5]

If you work in your local dev environment and your HTTP connection is not secure (not HTTPS), then you need to include Stripe JS without https:

Solution 6:[6]

Took me a few days to figure out, but in my case I was displaying the Stripe credit card element in a modal (Angular 11) that was using the Angular Shadow DOM encapsulation. Removing the Shadow DOM encapsulation solved this problem.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Top-Master
Solution 2 T Pringle
Solution 3
Solution 4
Solution 5 Stanislav
Solution 6 Russ