2

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?

2 Answers 2

2

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

You must log in to answer this question.

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