I am trying to integrate Stripe with Salesforce for one of my clients and trying to use Stripe JS in LWC. The Library is getting loaded fine without any issue and I am able to see the card element in the UI. But when I click on the Make Payment button then nothing is happening.

Note: - I am using Stripe JS v3 - https://js.stripe.com/v3/

Here is the code which is being called in button code

    window.console.log( ' this.cardElement ', this.cardElement );
    let cardToken;
    this.stripe.createToken( this.cardElement ).then( function (result) {

        window.console('result ', result);

        if (result.error) {
            window.console.log( 'result.error ', result.error);
        } else {
            cardToken = result.token;
            window.console.log(' cardToken ', cardToken);
    .catch(function (error) {
        window.console.error( ' Error Occured ', error );              
    window.console.log( ' End ' );

I am able to see the log for card element and End

Here is the code for LWC

<lightning-card  variant="Narrow"  >
    <lightning-spinner alternative-text="Loading" size="small" variant="brand" if:true={isSpinner}></lightning-spinner>
    <h3 class="slds-section-title--divider" >Payment Information</h3>
    <div class="slds-p-around_medium">
        <form method="post" id="payment-form" data-id="payment-form">
            <label for="card-element">Card Details</label>
            <div id="card-element" data-id='card-element' lwc:dom="manual" >
    <div class="slds-p-around_medium">
        <lightning-button variant="brand" label="Make Payment" title="Make Payment" onclick={handleSubmit}></lightning-button>

Let me know if need anything else from my side.

Edit 1 -

Here is the VF code and it's working fine

<apex:page id="paymentPage" > --> <apex:includeScript value="https://js.stripe.com/v3/"/> <apex:includeScript value="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"/>

<script type="text/javascript">
    window.onload = function() {
        var stripe = Stripe('pk_test_xxxxxx');
        var elements = stripe.elements();
        // Create an instance of the card UI component
        var card = elements.create('card');
        card.on('change', function(event) {
            var displayError = document.getElementById('card-errors');
            if (event.error) {
                displayError.textContent = event.error.message;
            } else {
                displayError.textContent = '';
        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', 'hidden');
            hiddenInput.setAttribute('name', 'stripeToken');
            hiddenInput.setAttribute('value', token.id);
            window.console.log(' token ', token );
            // Submit the form
        function createToken() {
            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
        // Create a token when the form is submitted.
        var form = document.getElementById('payment-form');
        form.addEventListener('submit', function(e) {
<form  method="post" id="payment-form">
  <div class="form-row">
    <label for="card-element">
      Credit or debit card
    <div id="card-element">
      <!-- a Stripe Element will be inserted here. -->

    <!-- Used to display form errors -->
    <div id="card-errors" role="alert"></div>

  <input type="submit" class="submit" value="Submit Payment" />

Thanks in advance.


1 Answer 1


This has nothing to do with the locker and more of how stripe JavaScript SDK is designed to work

From the documentation of stripe

The js file should always be loaded directly from https://js.stripe.com, rather than included in a bundle or hosted yourself.

Hence in your vf example it works while when you load the sdk from static resource for LWC it does not work!

There are few workarounds you can try

  1. Go via apex solution using the strip charge apis

  2. Iframe the vf page inside the lwc component and things should work fine! You can use LMS to pass data back and forth

  • Ahh, I missed it. Thank you so much :)
    – Amit Singh
    Mar 26, 2021 at 14:24
  • Option 2 will not work as per docs "Lightning Message Service does not work in Visualforce pages that are included in Lightning Experience via iframes".
    – Dan
    Sep 15, 2021 at 2:38
  • LMS is nothing but a bunch of post messages. You can always use window.postmessages if LMS is not working. Sep 15, 2021 at 2:40

Not the answer you're looking for? Browse other questions tagged .