Accelerated checkout for Braintree
Last updated: Sept 24th, 5:42pm
Note: Accelerated checkout is a limited release solution. Features may change between limited release and general availability.
This integration guide specifies how a partner or merchant can integrate accelerated checkout version 0.6 using the Braintree SDK into their site.
How it works
The following diagram depicts the integration changes required to enable the accelerated checkout experience.
Server-side setup
Generate access token
To instantiate the Braintree client SDK and the Connect components, generate an access token using a server-side call, then pass the token into the SDK.
For help on generating an access token, see Set Up Your Server.
Add *.paypal.com to your Content Security Policy
Important: Skip this step if you are using hosted card fields.
A Content Security Policy mitigates cross-site scripting and other attacks in your web browser. By limiting the origins of resources that are loaded on your page, you can maintain tighter control over any potentially malicious code. While browser support is relatively limited, implement a CSP when available. For a list of supported browsers, see Can I use - Content Security Policy.
Add the following directive to your policy, in addition to Braintree's directives:
frame-src
- Sandbox:
*.paypal.com
- Live:
*.paypal.com
Client-side integration
1. Initialize Connect Component and Braintree Data Collector
Connect is initialized by calling braintree.connect.create
and by passing a configuration object. Pass the device data when initializing Connect to prevent fraudulent access to Connect profiles.
To collect device data, instantiate the Braintree client and the Braintree data collector, passing the results of those methods into the configuration object that is passed into braintree.connect.create
.
Note: Update the script tags using Braintree SDK modules to use version 3.95.0-connect-alpha.11
.
Sample code: HTML
1<script src="https://assets.braintreegateway.com/web/3.95.0-connect-alpha.12/js/client.min.js"></script>2<script src="https://assets.braintreegateway.com/web/3.95.0-connect-alpha.12/js/connect.min.js"></script>3<script src="https://assets.braintreegateway.com/web/3.95.0-connect-alpha.12/js/data-collector.min.js"></script>
Sample code: JavaScript
1const clientInstance = await braintree.client.create({2 authorization: "<YOUR CLIENT TOKEN>"3});4const dataCollectorInstance = await braintree.dataCollector.create({5 client,6 riskCorrelationId: "<SESSION ID>"7});8const deviceData = dataCollectorInstance.deviceData;9// See Reference Types > Style Options for a full set of supported styles10const styles = {11 input: {12 "borderRadius": "15px"13 },14 toggle: {15 colorPrimary: "darkorange",16 colorSecondary: "#222222"17 },18 text: {19 body: {20 color: "#222222",21 fontSize: "12px"22 }23 }24};25const connect = await braintree.connect.create({26 authorization: "<YOUR CLIENT TOKEN>",27 client: clientInstance,28 deviceData: deviceData,29 styles: styles30});31const identity = connect.identity;32const profile = connect.profile;
If you are adding Connect to your existing Braintree integration, and you are already initializing braintree.client
and braintree.dataCollector
, you can reuse the same instance of those objects.
If you are sending analytics events using the PayPal Analytics API, pass the same value to riskCorrelationId
as the one you pass under tracking_visit_id
so that the events across the API and SDK can be correlated.
The connect
namespace contains a map of Connect features names to their corresponding UI Components and functions.
To set up your integration to work with the Braintree sandbox account, see Testing your integration.
Specify locale
Set the locale after initializing the Connect component to specify the locale in which the Connect components should be rendered. Connect supports the following languages:
en_us
(default)es_us
fr_us
zh_us
Sample code - Specifying the locale
1connect.setLocale("en_us");
2. Look up payer by email
Collect the email address from the payer so that you can determine if the payer has a store account or is a PayPal or Connect member. Because you'll share the payer's email address with PayPal, inform the payer about it by displaying the Connect watermark below the email input field.
Sample code: HTML watermark
1<input type="text" id="email" />2<!-- add a div where the watermark will be rendered -->3<div id="watermark-container"></div>
Sample code: JavaScript watermark
1const connectWatermark = ConnectWatermark({includeAdditionalInfo: true}).render('#watermark-container');
After collecting the email address, call identity.lookupCustomerByEmail(PAYER_EMAIL)
to determine whether the email is associated with a Connect profile or belongs to a PayPal member.
Sample code: Look up payer
1const {2 customerContextId3} = await identity.lookupCustomerByEmail(document.getElementById("email").value);4if (customerContextId) {5 // Email is associated with a Connect profile or a PayPal member6} else {7 // No profile found for this email address. This is a guest payer8}
If the payer is logged into a store account, continue to render the existing checkout flow for logged-in users. For store guest members, render the accelerated checkout flow.
3. Show accelerated checkout flow
The checkout flow varies based on whether the payer has a Connect profile. Guest users – those who do not have a Connect profile –can create a Connect profile as part of the checkout flow. Remembered users – those with a Connect profile – can select a card and address from their profile for faster checkout.
This section of the integration guide is split into guest payers and Connect payers.
Guest payers
For guest payers, collect shipping and payment information as part of the checkout flow.
The ConnectCardComponent
is a ready-made payment UI that offers a quick and easy way to securely accept payments. The payer can choose to create a Connect profile after they complete the transaction. You can customize the styling of the component to match the style on your site.
Sample code: Creating a div container for the payment element
1<!-- Div container for the payment component -->2<div id="payment-container"></div>3<!-- Submit button -->4<button id="submit-button">Submit Order</button>
Sample Code: Look Up Payer
1const submitButton = document.getElementById("submit-button");2const fields = {3 phoneNumber: {4 prefill: "1234567890"5 },6 cardholderName: {} // optionally pass this to show the card holder name7 };8const connectCardComponent = await connect9 .ConnectCardComponent({ fields })10 .render("#payment-container");11// event listener when the customer clicks to place the order12submitButton.addEventListener("click", async () => {13 const { nonce } = await connectCardComponent.tokenize({14 billingAddress: {15 streetAddress: "2211 North 1st St",16 locality: "San Jose",17 region: "CA",18 postalCode: "95131",19 countryCodeAlpha2: "US" // you can also use the countryCodeAlpha320 // or countryCodeNumeric formats21 }22 });23 // Send the nonce and previously captured device data to server24 // to complete checkout25});
To complete the transaction, send the nonce
to your server and create a transaction with it.
Connect payers
Authenticate Connect payers to retrieve their profile information.
To trigger the authentication, you need to pass the customerContextId
that is returned from the lookupCustomerByEmail(email)
call to triggerAuthenticationFlow()
.
Triggering the authentication presents the payer with a screen to authenticate themselves by entering a one-time password that is sent to their registered mobile phone number.
Sample code: Authentication
1const {2 authenticationState,3 profileData4} = await identity.triggerAuthenticationFlow(customerContextId);5if (authenticationState === "succeeded") {6 const name = profileData.name;7 const shippingAddress = profileData.shippingAddress;8 const card = profileData.card;9} else {10 // authentication failed or canceled by the customer11};
The triggerAuthenticationFlow()
method returns AuthenticatedCustomerResult
. You can use the authenticationState
in the response to determine if the payer has successfully authenticated themselves. The returned object contains the payer’s name, default shipping address and default card.
If the payer fails authentication or declines to authenticate, you render the guest flow instead. After the payer is authenticated, retrieve their shipping address and payment methods.
Shipping addresses
The merchant is expected to render the shipping address from the profile on the page. The payer may have more than one shipping address in their profile, or may want to enter a new one. Render a button to allow the payer to change the shippping address.
Call the profile.showShippingAddressSelector()
method when the payer selects the ‘Change Shipping Address’ button. This presents the payer with a list of their addresses for them to pick from (and enables them to enter a new one). When the payer makes a selection, the method returns the selected address. If they cancel without changing the selection, selectionChanged
is set to false
, and selectedAddress
is set to null
.
Sample code: Change address
1<!-- Change address button -->2<button id="change-address-button">Change Address</button>
1const changeAddressButton = document.getElementById("change-address-button");2changeAddressButton.addEventListener("click", async () => {3 const {4 selectionChanged,5 selectedAddress6 } = await profile.showShippingAddressSelector();7 if (selectionChanged) {8 // selectedAddress contains the new address9 } else {10 // selection modal was dismissed without selection11 }12});
Payment
The merchant is expected to render the card from the profile on the page.
The payer may have more than one card on their profile, or may want to enter a new one. Render a button to allow the payer to change the card.
Call the profile.showCardSelector()
method when the payer clicks on the changeCardButton
. This presents the payer with a list of their cards for them to pick from (and enables them to enter a new one). When the payer makes a selection, the method returns the selected card. If they cancel without changing the selection, selectionChanged
is set to false
, and selectedCard
is set to null
.
Sample code: Change payment method
1changeCardButton.addEventListener('click', async ()=> {2 const { selectionChanged, selectedCard } = await profile.showCardSelector();3 if (selectionChanged) {4 // selectedCard contains the new card5 } else {6 // selection modal was dismissed without selection7 }8})
The card object contains a nonce representing the card. To complete the order, send the nonce to your server and create an order with it.
4. Create transaction
On your server, you need to create a transaction using either the Braintree GraphQL API or one of the server-side SDKs. While creating the transaction, ensure to pass the device data to ensure higher authorization rates.
5. Test integration
To test your integration in the sandbox environment, set the following local storage variable before initializing the Connect component:
1changeCardButton.addEventListener('click', async ()=> {2window.localStorage.setItem("axoEnv", "sandbox");