0

I have a client requirement to integrate Braintree payments UI in Salesforce Customer Community. The two options are either use drop-in UI or hosted fields. I ran into serious security problems when trying to add drop-in UI inside a LWC.

Has anyone else tried this successfully?

I got rid of the security errors by adding CSP trusted sites. Not the component is loading ok, but the dropin UI is not appearing

Below are fragments from my code. I get DIV and passed that to braintree.dropon.create(). But I don't see anything in UI and there are no errors in Console

LWC.html

<template>
    <div id="dropin-container"></div>
    <button id="submit-button">Request payment method</button>
</template>

LWC.js

import { LightningElement, track, wire } from "lwc";
import { NavigationMixin } from "lightning/navigation";
import braintreejs from "@salesforce/resourceUrl/BraintreeJS";

export default class Resources extends NavigationMixin(LightningElement) {
    @track resources = [];
    @track showResources = false;


renderedCallback() {
    loadScript(this, braintreejs + "/dropin.min.js");
    loadScript(this, braintreejs + "/jquery-3.2.1.min.js");

    var button = this.template.querySelector('button');
    var div = this.template.querySelector('div');
    // console.log(JSON.stringify(div.id));
    braintree.dropin.create({
        authorization: 'CLIENT_TOKEN',
        container: '#'+div.id
    }, function (createErr, instance) {
        button.addEventListener('click', function () {
            console.log('inside');
            instance.requestPaymentMethod(function (requestPaymentMethodErr, payload) {
            // Submit payload.nonce to your server
            });
        });
    });
}
0

2 Answers 2

2

You should use connectedCallback instead of renderedCallback, you need to use lwc:dom="manual" to allow manual manipulation, and you need to wait for your scripts to load (either Promise.all or via await).

loaded = false;
connectedCallback() {
    if (loaded) {
        return;
    }
    Promise.all([
        loadScript(this, braintreejs + "/dropin.min.js"),
        loadScript(this, braintreejs + "/jquery-3.2.1.min.js")
    ]).then(() => {
        this.loaded = true;
        var button = this.template.querySelector('button');
        var div = this.template.querySelector('div');
        // console.log(JSON.stringify(div.id));
        braintree.dropin.create({
            authorization: 'CLIENT_TOKEN',
            container: '#' + div.id
        }, function (createErr, instance) {
            button.addEventListener('click', function () {
                console.log('inside');
                instance.requestPaymentMethod(function (requestPaymentMethodErr, payload) {
                    // Submit payload.nonce to your server
                });
            });
        });
    });
}

<template>
    <div lwc:dom="manual" id="dropin-container"></div>
    <button id="submit-button">Request payment method</button>
</template>
1
  • I tried it but didn't work as well. I don't see any error in the console and nothing gets rendered in the UI
    – Shiran
    Jun 17, 2020 at 0:58
0

I ended up doing this using a Visualforce page and integrate that VF page into a LWC using iframe. Works pretty well.

1
  • Can you please share the code snippet for Visualforce.
    – Anant
    Mar 11, 2022 at 16:07

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