1

I'm trying to create an LWC that calls Stripe's API. Stripe has a js library, but they say: it should always be loaded directly from https://js.stripe.com:

Of course, steps 1 & 2 of LWC docs on using 3rd party libraries are...

  1. Download the library from the third-party library's site.
  2. Upload the library to your Salesforce organization as a static resource, which is a Lightning Web Components content security policy requirement.

Not sure how to resolve this conflict. I tried...

import stripeLib from "https://js.stripe.com/v3/";

...but that gives me a VSCode error.

Not sure how to proceed. Any ideas?

1

I was able to get the Stripe card input to work, but NOT able to get the stripe.createPaymentMethod method to respond.

I believe this is due to locker service or CORS.

Failing Solution

Steps:

  1. I started by downloading the JavaScript: https://js.stripe.com/v3/

  2. Added it as a Static Resource called stripe

  3. create LWC:

LWC JavaScript

import { LightningElement } from "lwc";
import { loadScript } from "lightning/platformResourceLoader";
import StripeJS from "@salesforce/resourceUrl/stripe";

export default class StripeTest extends LightningElement {
    initialised = false;
    stripe;
    cardElement;

    async renderedCallback() {
        if (this.initialised) {
            return;
        }
        this.initialised = true;

        await Promise.all([loadScript(this, StripeJS)]).catch(error => console.error(error));

        const cardWrapper = this.template.querySelector("div.cardWrapper");

        // setup Stripe.js and Elements
        this.stripe = Stripe("pk_test_XXXXXXXXXXXXXXXXXXXXXXXXXXXX");
        console.log(this.stripe);
        const elements = this.stripe.elements();

        // setup card Element
        this.cardElement = elements.create("card", {});
        this.cardElement.mount(cardWrapper);
    }

    async handlePay() {
        const payload = await this.stripe.createPaymentMethod({
            type: "card",
            card: this.cardElement
        }); // THIS DOES NOT WORK
        console.log("[PaymentMethod]", payload); // THIS NEVER RUNS
    }
}

LWC template

<template>
    <div class="cardWrapper" lwc:dom="manual"></div>
    <button onclick={handlePay}>Pay</button>
</template>

Working Solution

In the end I used a Visualforce Page, example below:

<apex:page applyBodyTag="false" applyHtmlTag="false" showHeader="false" sidebar="false" standardStylesheets="false" lightningStyleSheets="true">
    <html>
    <head>
        <script type="text/javascript" src="//js.stripe.com/v3/"></script>
        <apex:slds />
    </head>
    <body>
        <script>
            window.onload = onLoad;
            async function onLoad() {

                const cardWrapper = document.querySelector("div.cardWrapper");
                const button = document.querySelector("button");
                const stripe = await Stripe('pk_test_XXXXXXXXXXXXXXXXXXXX');
                const elements = stripe.elements();
                this.cardElement = elements.create("card", {});
                this.cardElement.mount(cardWrapper);
                button.addEventListener('click', async () => {
                    const payload = await stripe.createPaymentMethod({
                        type: 'card',
                        card: cardElement,
                    });
                    console.log('[PaymentMethod]', payload);
                }, false);
            }
        </script>
        <div class="slds-scope">
            <div class="slds-p-around_medium">
                <div class="cardWrapper"></div>
            </div>
            <button class="slds-button slds-button_brand">Pay</button>
        </div>
    </body>
    </html>
</apex:page>
0

You need to use the names of static resource with resource loader in LWC.

Like

import myResource from '@salesforce/resourceUrl/static_reource_name';

Then you need to load the script.

loadScript(self, myResource): Promise.

Here is the final code look like.

import { loadScript, loadStyle } from 'lightning/platformResourceLoader';
import myResource from '@salesforce/resourceUrl/static_reource_name';

export default class Demo extends LightningElement {
    libInitialized = false;

    renderedCallback() {
        if (this.libInitialized) {
            return;
        }
        this.libInitialized = true;

        Promise.all([
            loadScript(this, myResource + '/v3/filename.js'),
            loadScript(this, myResource + '/v3/filename2.js'), // if needed
        ])
            .then(() => {
                // do your stuff when library is loaded successfully.
            })
            .catch(error => {
                // handle the error
            });
    }
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.