JavaScript v2

Best Practices and Troubleshootinganchor

Script tag placement and initializationanchor

It is best practice to place your <script> tag as close to the bottom of your HTML document as possible. Typically this means placing it immediately before the closing <body> tag.

braintree.setup() must be called after your form container element is created. If braintree.setup() runs before the container element exists, the UI may not appear.

Optimizing for tablets and phonesanchor

If you intend on using the Drop-in checkout UI or customizing your existing checkout by accepting PayPal, we suggest you include a viewport meta tag in the <head> of your website to ensure injected interfaces, such as lightboxes, display at the proper size on tablets and phones.

  1. HTML
<meta name="viewport" content="width=device-width, initial-scale=1.0" />

The viewport meta tag is responsible for defining how a website behaves when it's rendered on differently sized devices. Be sure to review your website on a tablet or phone after adding the tag to ensure it displays properly.

Comparison of lightboxes with and without the viewport meta tag

Above are examples of a website with the viewport meta tag (left) and without the viewport meta tag (right).

Leverage onReadyanchor

The JavaScript SDK exposes an onReady callback that will fire when your chosen integration is fully loaded and ready to be interacted with. Depending on your checkout experience and flow, you may wish to hide portions of your DOM designated for use with Braintree until this callback is received.

Teardownanchor

In certain scenarios you may need to remove your Braintree.js integration. This is common in single page applications, modal flows, and other situations where state management is a key factor. When calling braintree.setup, you can attach a callback to onReady which will provide an object containing a teardown method.

Invoking teardown will clean up any DOM nodes, event handlers, popups and/or iframes that have been created by the integration. Additionally, teardown accepts a callback which you can use to know when it is safe to proceed.

  1. JavaScript
var checkout;
braintree.setup('CLIENT_TOKEN_FROM_SERVER', 'dropin', {
  onReady: function (integration) {
    checkout = integration;
  }
});

// When you are ready to tear down your integration
checkout.teardown(function () {
  checkout = null;
  // braintree.setup can safely be run again!
});

You can only invoke teardown once per .setup call. If you happen to call this method while another teardown is in progress, you'll receive an error stating Cannot call teardown while in progress. Once completed, subsequent calls to teardown will throw an error with this message: Cannot teardown integration more than once.

Custom UIanchor

If you wish to open the PayPal auth flow using a button other than the one provided by Braintree, you must use a combination of a headless PayPal integration and the paypal.initAuthFlow method returned from the onReady callback.

  1. JavaScript
var checkout;

braintree.setup('CLIENT_TOKEN_FROM_SERVER', 'custom', {
  onReady: function (integration) {
    checkout = integration;
  },
  onPaymentMethodReceived: function (payload) {
    // retrieve nonce from payload.nonce
  },
  paypal: {
    singleUse: true,
    amount: 10.00,
    currency: 'USD',
    locale: 'en_US',
    enableShippingAddress: true,
    headless: true
  }
});

// Add a click event listener to your own PayPal button
// Note: cross-browser compatibility for click handlers and events are up to you
document.querySelector('#my-button-element').addEventListener('click', function (event) {
  event.preventDefault();
  checkout.paypal.initAuthFlow();
}, false);

Using Braintree.js with a Content Security Policyanchor

Content Security Policy is a feature of web browsers that mitigates cross-site scripting and other attacks. By limiting the origins of resources that may be loaded on your page, you can maintain tighter control over any potentially malicious code. While browser support is relatively limited, we recommend considering the implementation of a CSP when available.

If you are using AJAX with CORS (by setting enableCORS to true as discussed in the setup method options), you will need to add the following directives to your policy:

Sandbox Production
script-srcjs.braintreegateway.com
assets.braintreegateway.com
www.paypalobjects.com
c.paypal.com
js.braintreegateway.com
assets.braintreegateway.com
www.paypalobjects.com
c.paypal.com
style-src'unsafe-inline''unsafe-inline'
img-srcassets.braintreegateway.com
checkout.paypal.com
data:
assets.braintreegateway.com
checkout.paypal.com
data:
child-srcassets.braintreegateway.com
c.paypal.com
assets.braintreegateway.com
c.paypal.com
frame-srcassets.braintreegateway.com
c.paypal.com
*.cardinalcommerce.com
assets.braintreegateway.com
c.paypal.com
*.cardinalcommerce.com
connect-srcapi.sandbox.braintreegateway.com
client-analytics.sandbox.braintreegateway.com
*.braintree-api.com
api.braintreegateway.com
client-analytics.braintreegateway.com
*.braintree-api.com

If you're not using AJAX with CORS, you will need to add the following directives to your policy:

Sandbox Production
script-srcjs.braintreegateway.com
assets.braintreegateway.com
api.sandbox.braintreegateway.com
www.paypalobjects.com
client-analytics.sandbox.braintreegateway.com
js.braintreegateway.com
assets.braintreegateway.com
api.braintreegateway.com
www.paypalobjects.com
client-analytics.braintreegateway.com
style-src'unsafe-inline''unsafe-inline'
img-srcassets.braintreegateway.com
checkout.paypal.com
data:
assets.braintreegateway.com
checkout.paypal.com
data:
child-srcassets.braintreegateway.com
c.paypal.com
assets.braintreegateway.com
c.paypal.com
frame-srcassets.braintreegateway.com
c.paypal.com
assets.braintreegateway.com
c.paypal.com
If you are using 3D Secure, you need to set frame-src and form-action to * instead.

Bypass submit handlersanchor

By default, Braintree.js attaches handlers to the submit action of your form. While this feature itself is not configurable, you may find yourself wanting to submit your form without triggering our handlers. This is a common practice when subscribed to the onPaymentMethodReceived callback. When you wish to submit your form, you can invoke its native submit action like so:

  1. JavaScript
var form = document.getElementById('my-form');
HTMLFormElement.prototype.submit.call(form);

If you are using a form that has no button to click, you can create your own event to submit:

  1. JavaScript
var form = document.getElementById('my-form');
var e = document.createEvent('Event');

e.initEvent('submit', true, true);
form.dispatchEvent(e);