Integrate Fastlane
DocsCurrentLast updated: July 25th 2024, @ 2:23:55 pm
Availability
Fastlane is available:
- In the US only.
- For both desktop and mobile.
Prerequisites
- If you're processing payments on legacy PayPal APIs, you'll need to upgrade to Orders v2.
- Make sure you've completed the steps in Getting started.
- You must process card payments with PayPal.
- You must present PayPal as a payment option.
- You must collect a billing address during checkout.
1. Integrate front-end
Set up your client side to integrate Fastlane.
Initialize the SDK through the following script tag on your HTML page.
1<script2 src="https://www.paypal.com/sdk/js?client-id=<CLIENT_ID>&components=buttons,fastlane"3 data-sdk-client-token="<SDK_CLIENT_TOKEN>"4 data-client-metadata-id="<CM_ID>">5</script>
Fastlane is initialized with a call to paypal.Fastlane. A configuration object must be passed during initialization.
The follwing fields are required to initialize the SDK:
client-iddata-sdk-client-tokenfrom setting up your server.data-client-metadata-id. For sandbox testing, you can pass a unique value of your choice in this field.
1// instantiates the Fastlane module2const fastlane = await window.paypal.Fastlane({3 // For more details about available configuraton parameters, see the custom integration section.4});567// Convenience parameters for calling later on8const { identity, profile } = fastlane;
To specify the locale in which the Fastlane components should be rendered, you can set the locale after initializing the fastlane component.
1fastlane.setLocale("en_us"); // en_us is the default value
Fastlane supports the following languages:
en_us- English, defaultes_us- Spanishfr_us- Frenchzh_us- Mandarin
Because the email address will be shared with PayPal, it is crucial to inform the payer. We recommend that you display the Fastlane watermark below the email field.
After collecting the email address, we need to determine whether the email is associated with a Fastlane profile or if it belongs to a PayPal member. Use the following code snippet to look up the customer's email.
1const {2 customerContextId3} = await identity.lookupCustomerByEmail(document.getElementById("email").value);
If the user is identified to have a Fastlane profile, they need to authenticate before Fastlane retrieves their saved payment and address information. The user is presented with a screen to authenticate themselves by entering a one-time password sent to their registered mobile number.
1const {2 customerContextId3} = await identity.lookupCustomerByEmail(document.getElementById("email").value);45//this variable will turn to True if user authenticates successfully with OTP6//will remain False by default78 let renderFastlaneMemberExperience = false;910if (customerContextId) {11 // Email is associated with a Fastlane member or a PayPal member,12 // send customerContextId to trigger the authentication flow.13 const {14 authenticationState,15 profileData16 } = await identity.triggerAuthenticationFlow(customerContextId);
The triggerAuthenticationFlow() method returns an AuthenticatedCustomerResult object. Use the authenticationState property in the AuthenticatedCustomerResult object to check if the payer has authenticated.
On authentication:
- The Fastlane member's card details and default shipping address are returned with the
profileDataobject contents. - Th
renderFastlaneMemberExperienceis set toTrue.
Render the same experience as you would for a guest payer if a Fastlane member fails or declines to authenticate.
1if (authenticationState === "succeeded") {2 // Fastlane member successfully authenticated themselves3 // profileData contains their profile details4 renderFastlaneMemberExperience = true;5 const name = profileData.name;6 const shippingAddress = profileData.shippingAddress;7 const card = profileData.card;8 } else {9 // Member failed or cancelled to authenticate. Treat them as a guest payer10 renderFastlaneMemberExperience = false;11 }12} else {13 // No profile found with this email address. This is a guest payer14 renderFastlaneMemberExperience = false;15}
This step is not required for:
- Fastlane members without a shipping address.
- Fastlane members with a shipping address in a region you don't support.
- Guest payers.
For Fastlane members with a shipping address, you'll need to render
- Shipping address returned from profile data on authenication.
- Fastlane watermark.
- Fastlane by PayPal logo.
- Change address button that invokes
showShippingAddressSelector(). This helps the payer change or add a new address as needed.
If the user addes a new address to their Fastlane profile, send the new address in the Orders v2 server-side request.
1if (renderFastlaneMemberExperience) {23 if (profileData.shippingAddress) {4 // render shipping address from the profile5 const changeAddressButton = document.getElementById("your-change-address-button");6 changeAddressButton.addEventListener("click", async () => {7 const {8 selectedAddress,9 selectionChanged10 } = await profile.showShippingAddressSelector();11 if (selectionChanged) {12 // selectedAddress contains the new address13 } else {14 // selection modal was dismissed without selection15 }16 });17 } else {18 // render your shipping address form19 }20} else {21 // render your shipping address form22}
Fastlane offers two different integration patterns to accept payments; quick start and flexible.
The quick start payment integration loads a pre-built template form to collect payments. It's lighter integration effort. The quick start integration is PCI DSS compliant, ensuring that customer payment information is handled securely.
The pre-built payment UI component automatically renders the following:
- Selected card for the Fastlane member.
- "Change card" link which allows payers to change the selection or add a new card.
- Card fields for guest users or for Fastlane members that don't have a card in their profile.
- Billing address fields.
1<!-- Div container for the Payment Component -->2<div id="payment-container"></div>3<!-- Submit Button -->4<button id="submit-button">Submit Order</button>
1const shippingAddress = {2 firstName: "Jen",3 lastName: "Smith",4 company: "Braintree",5 streetAddress: "1 E 1st St",6 extendedAddress: "5th Floor",7 locality: "Bartlett",8 region: "IL", // must be sent in 2-letter format9 postalCode: "60103",10 countryCodeAlpha2: "US",11 phoneNumber: "14155551212"12}1314const options = {15 fields: {16 phoneNumber: {17 // Example of how to prefill the phone number field in the FastlanePaymentComponent18 prefill: "4026607986"19 }20 },21 styles: {22 root: { //specify styles here23 backgroundColorPrimary: "#ffffff"24 }25 }26};2728const fastlanePaymentComponent = await fastlane.FastlanePaymentComponent({29 options,30 shippingAddress31 });32 await fastlanePaymentComponent.render("#payment-container");3334// event listener when the user clicks to place the order35const submitButton = document.getElementById("submit-button");36submitButton.addEventListener("click", async ()=> {37 const { id } = await fastlanePaymentComponent.getPaymentToken();3839 // Send the paymentToken and previously captured device data to server40 // to complete checkout41});
After you receive the paymentTokenId from the paymentToken object, send the paymentTokenId to your server to create a transaction with it.
2. Integrate back end
On your server, create an order by calling the Orders API and passing the single use token, along with the item details and the shipping address.
Provide detailed item descriptions and product images for each item to:
- Create a better user experience for email communications.
- Streamline any potential dispute resolution
1curl -v -k -X POST 'https://api-m.sandbox.paypal.com/v2/checkout/orders' \2 -H 'PayPal-Request-Id: UNIQUE_ID' \3 -H 'Authorization: Bearer PAYPAL_ACCESS_TOKEN' \4 -H 'Content-Type: application/json' \5 -H 'PayPal-Client-Metadata-Id: <CM_ID>' \6 -d '{7 "intent": "CAPTURE",8 "payment_source": {9 "card": {10 "single_use_token": "1h371660pr490622k" //paymentToken from the client11 }12 },13 "purchase_units": [14 {15 "amount": {16 "currency_code": "USD",17 "value": "50.00",18 "breakdown": {19 "item_total": {20 "currency_code": "USD",21 "value": "40.00"22 },23 "shipping": {24 "currency_code": "USD",25 "value": "10.00"26 }27 }28 },29 "items": [30 {31 "name": "Coffee",32 "description": "1 lb Kona Island Beans",33 "sku": "sku03",34 "unit_amount": {35 "currency_code": "USD",36 "value": "40.00"37 },38 "quantity": "1",39 "category": "PHYSICAL_GOODS",40 "image_url": "https://example.com/static/images/items/1/kona_coffee_beans.jpg",41 "url": "https://example.com/items/1/kona_coffee_beans",42 "upc": {43 "type": "UPC-A",44 "code": "987654321015"45 }46 }47 ],48 "shipping": {49 "type": "SHIPPING",50 "name": {51 "full_name": "Lawrence David"52 },53 "address": {54 "address_line_1": "585 Moreno Ave",55 "admin_area_2": "Los Angeles",56 "admin_area_1": "CA", //must be sent in 2-letter format57 "postal_code": "90049",58 "country_code": "US"59 },60 "phone_number": {61 "country_code": "1",62 "national_number": "5555555555"63 }64 }65 }66 ]67}'
Store pick-up: If the buyer is picking up item from a store-front, ensure the shipping method is set to PICKUP_IN_STORE. This ensures that buyer profiles aren't created with the address of your store as their shipping address.
Vaulting: If you want to save the paymentToken returned by the Fastlane SDK at the time of transaction, you can do so only when using the store_in_vault attribute in the request to v2/orders on your server. This will return a vault ID which can be saved and used for future transaction. See the Orders v2 documentation for more details.
3. Custom integration
This optional section contains reference types you can use to customize your Fastlane integration.
window.paypal.Fastlane(options);
1interface FastlaneOptions {2 shippingAddressOptions: AddressOptions,3 cardOptions: CardOptions,4 styles: StyleOptions5}6/*7 * To restrict the use of Fastlane to specific countries and/or regions, set8 * allowedLocations to an array containing the countries/regions where Fastlane9 * should be allowed.10 *11 * To allow all regions within a particular country, specify only the country's12 * ISO 3166-1 alpha-2 country code.13 *14 * To allow only specific regions in a country, specify the country's15 * ISO 3166-1 alpha-2 country code, followed by a colon (":"), followed by the16 * name of the region.17 *18 * Examples:19 * - [ "US" ] = Allow all regions within the United States20 * - [ "US:CA", "US:AZ" ] = Allow in California in Arizona, but nowhere else21 * - [ "US:CA", "US:AZ", "FR" ] = Allow in California, Arizona, and France,22 * but nowhere else23 */24interface AddressOptions {25 // default: empty array = all locations allowed26 allowedLocations: [AddressLocationEnum];27}28Enum AddressLocationEnum {29 {ISO-country-code}30 {ISO-country-code}:{ISO-region-code}31}32interface CardOptions {33 // default: empty array = all brands allowed34 allowedBrands: [CardBrandEnum];35}36Enum CardBrandEnum {37 VISA38 MASTERCARD39 AMEX40 DINERS41 DISCOVER42 JCB43 CHINA_UNION_PAY44 MAESTRO45 ELO46 MIR47 HIPER48 HIPERCARD49}
1type create = (options: FastlaneOptions) => Fastlane;
1interface Fastlane {2 identity {3 lookupCustomerByEmail: (email: string) => LookupCustomerResult,4 triggerAuthenticationFlow: (customerContextId: string, options: AuthenticationFlowOptions) => AuthenticatedCustomerResult5 }6 profile {7 showShippingAddressSelector: () => ShowShippingAddressSelectorResult,8 showCardSelector: () => ShowCardSelectorResult,9 }10 setLocale: (locale: string) => void, // options: en_us, es_us, fr_us, zh_us11 FastlaneCardComponent: (options: FastlaneCardComponentOptions) => FastlaneCardComponent,12 FastlanePaymentComponent: (options: FastlanePaymentComponentOptions) => FastlanePaymentComponent,13 FastlaneWatermarkComponent: (options: FastlaneWatermarkOptions) => FastlaneWatermarkComponent14}
The LookupCustomerResult object type is returned from the identity.lookupCustomerByEmail(email) method.
1interface LookupCustomerResult {2 customerContextId: string3}
1interface FastlaneWatermarkOptions {2 includeAdditionalInfo: boolean3}4interface FastlaneWatermarkComponent {5 render: (container) => null6}
The AuthenticatedCustomerResult object type is returned from the identity.triggerAuthenticationFlow() call.
1interface AuthenticatedCustomerResult {2 authenticationState: 'succeeded'|'failed'|'canceled'|'not_found';3 profileData: ProfileData;4}5interface ProfileData {6 name: Name;7 shippingAddress: Shipping;8 card: PaymentToken;9}10interface Name = {11 firstName: string;12 lastName: string;13 fullName: string;14};15interface Phone = {16 nationalNumber: string;17 countryCode: string;18};19interface Address = {20 addressLine1: string,21 addressLine2: string,22 adminArea1: string,23 adminArea2: string;24 postalCode: string,25 countryCode: string26 phone: Phone;27};28interface Shipping = {29 name: Name;30 address: Address;31 companyName: string;32}33interface BillingAddress = Address;34interface PaymentToken {35 id: string; // This is the payment paymentToken36 paymentSource: PaymentSource;37}38interface PaymentSource {39 card: CardPaymentSource;40}41interface CardPaymentSource {42 brand: string;43 expiry: string; // "YYYY-MM"44 lastDigits: string; // "1111"45 name: string;46 billingAddress: Address;47}
1interface ShowShippingAddressSelectorResult {2 selectionChanged: boolean;3 selectedAddress: Address;4}5interface ShowCardSelectorResult {6 selectionChanged: boolean;7 selectedCard: PaymentToken;8}
The FastlaneCardComponent uses hosted card fields. The resulting interface is a subset of the card fields interface.
The instance of a FastlaneCardComponent can be created using:
1const fastlaneCardComponent = await fastlane.FastlaneCardComponent({...})2fastlaneCardComponent.render("#card-container")
FastlaneCardComponent reference types:
1type FastlaneCardComponent = (options: FastlaneCardComponentOptions) => FastlaneCardComponent;2 interface FastlaneCardComponent {3 render: (container) => FastlaneCardComponent;4 getPaymentToken: async (options: PaymentTokenOptions) => PaymentToken;5 }6 interface FastlaneCardComponentOptions {7 styles: StyleOptions;8 fields: {Field};9 }10 interface Field {11 placeholder: string;12 prefill: string;13 enabled: boolean;14 }15 interface PaymentTokenOptions {16 billingAddress: Address;17 cardholderName: Name;18 }
You can configure the card fields in the FastlaneCardComponent or FastlanePaymentComponent when initializing the components:
1const styles: {};2const fields: {3 number: {4 placeholder: "Number",5 },6 phoneNumber: {7 prefill: "555-555-5555"8 }9 }10}1112fastlane.FastlaneCardComponent({13 styles,14 fields15}).render(elem);16fastlane.FastlanePaymentComponent({17 styles,18 fields19}).render(elem);
Available fields:
| Name | Type | Attributes | Description |
|---|---|---|---|
number | field | <optional> | A field for card number. |
expirationDate | field | <optional> | A field for expiration date in MM/YYYY or MM/YY format. This should not be used with the expirationMonth and expirationYear properties. |
expirationMonth | field | <optional> | A field for expiration month in MM format. This should be used with the expirationYear property. |
expirationYear | field | <optional> | A field for expiration year in YYYY or YY format. This should be used with the expirationMonth property. |
cvv | field | <optional> | A field for 3 or 4 digit card verification code (like CVV or CID). If you wish to create a CVV-only payment token to verify a card already stored in your Vault, omit all other fields to only collect CVV. |
postalCode | field | <optional> | A field for postal or region code. |
cardholderName | field | <optional> | A field for the cardholder name on the payer's credit card. |
phoneNumber | field | <optional> | A field for the cardholder name on the payer's credit card. |
Colors can be any value that CSS allows in hex values, RGB, RGBA, and color names.
1interface StyleOptions {2 root: {3 backgroundColor: string,4 errorColor: string,5 fontFamily: string,6 textColorBase: string,7 fontSizeBase: string,8 padding: string,9 primaryColor: string,10 },11 input: {12 backgroundColor: string,13 borderRadius: string,14 borderColor: string,15 borderWidth: string,16 textColorBase: string,17 focusBorderColor: string,18 },19}
When styling the Fastlane components to match the look and feel of your checkout page, here are some guidelines to provide an accessible and transparent experience to your payer.
Ensure that there is adequate contrast between the backgroundColor and textColor to ensure that all text, especially the legal text under the opt-in, is clear and legible. If the contrast ratio between the two is not 4.5:1, PayPal will automatically set the to the default values in the following table.
Ensure that there is adequate contrast between the borderColor, which drives the consent toggle coloring and the backgroundColor.
| Value | Description | Default | Guidance and Thresholds |
|---|---|---|---|
root.backgroundColor | the background color of the components. | #ffffff | May be any valid CSS color. No transparency allowed. |
root.errorColor | The color of errors in the components. | #D9360B | May be any valid CSS color. No transparency allowed. |
root.fontFamily | The font family used throughout the UI. | PayPal Open | Must be one of the following:
|
root.fontSizeBase | The base font size. Increasing this value will change the text size of all text within the UI components. | 16px, 13px min, 24px max | |
root.textColorBase | The text color used across all text outside of inputs. | #01080D | May be any valid CSS color. No transparency allowed. |
root.padding | The padding between content and borders | 4px, 0px min, 10px max | |
root.primaryColor | This value sets the default for the checkbox for billing address, and the link for the "change", the toggle primary color, and the legal links for privacy and terms. | #0057FF | May be any valid CSS color. No transparency allowed. |
input.backgroundColor | the background color of the inputs within the components. | #ffffff | May be any valid CSS color. No transparency allowed. |
input.borderRadius | The border radius used for the email field. | 0.25em, 0px min, 32px max | |
input.borderColor | The border color of the email field. | #DADDDD | May be any valid CSS color. No transparency allowed. |
input.focusBorderColor | The border color of the email field when focused. | #0057FF | May be any valid CSS color. No transparency allowed. |
input.borderWidth | The width of the input borders | 1px, 5px max | Default size is 1px. |
input.textColorBase | The text color used for text within input fields. | #01080D | May be any valid CSS color. No transparency allowed. |
Use the following image URLs to load card assets. These enable users to see the branded image of their card.
The following table lists the required data to create a Fastlane profile, how you can pass the information, and which takes priority.
| Data Property | 1st Priority to collect the information | 2nd Priority if applicable |
|---|---|---|
| Phone Number | UI | N/A |
| UI – Guest Lookup | N/A | |
| Billing Address | API | UI – Tokenize. Require first name, last name, street, city, state, zip, country |
| Shipping Address | API | UI – Tokenize |
| First Name | Derived from Billing Address First Name | N/A |
| Last Name | Derived from Billing Address Last Name | N/A |
4. Test integration
You'll need to test your integration for guest payers and Fastlane members, with and without the consent toggle on. Testing will vary depending on whether your integration is quick start or flexible.
Guest payers enter an email not associated with a PayPal account or Fastlane profile. Make sure you have the following before you start testing the guest payer flow:
- New email address: Provide a new email address which is not associated with a sandbox Fastlane account.
- Ensure opt-in toggle is ON: Go through the checkout process using one of the test card numbers. Be sure that the opt-in toggle is on.
- Phone number for sandbox: Enter any valid phone number. No SMS is sent in sandbox mode.
When you complete the transaction with the consent toggle on, a Fastlane profile is created. Use that profile to test transactions as a Fastlane member.
| User flow | Result |
|---|---|
The FastlanePaymentComponent renders card fields and the consent toggle. The buyer turns the consent toggle off and completes the order. | The payment is completed successfully and no Fastlane profile is created. |
| User flow | Result |
|---|---|
The FastlanePaymentComponent renders card fields and the consent toggle. The buyer completes the order with the consent toggle on. | The payment is completed successfully and a Fastlane profile is created for the email the guest entered. |
A Fastlane member enters a recognized email at checkout.
| Scenario | User flow | Result |
|---|---|---|
| Happy path | The one-time password (OTP) flow is triggered to authenticate the buyer. The buyer's shipping address and card information are populated after OTP entry. | The buyer completes the order. |
| OTP failed or cancelled | The OTP flow is triggered to authenticate the buyer. Cancel the OTP by exiting or entering an incorrect code. | The FastlanePaymentComponent should render the card fields with no consent toggle. The buyer completes the order. |
| New address | The OTP flow is triggered to authenticate the buyer. The buyer's shipping address and card information are populated after OTP entry. Select the change address link to invoke the address selector UI. Select Add new address and enter a new address in the address selector UI. | The buyer completes the order. A new address is added to the buyer's Fastlane profile. |
| New card | The OTP flow is triggered to authenticate the buyer. The buyer's shipping address and card information are populated after OTP entry. Select the change card link to invoke the card selector UI. Select Add new card and enter a new card in the card selector UI. | The buyer completes the order. A new card is added to the buyer's Fastlane profile. |
| Change address | The OTP flow is triggered to authenticate the buyer. The buyer's shipping address and card information are populated after OTP entry. Select the change address link to invoke the address selector UI via showAddressSelector(). Select another address from the list. | The buyer completes the order with changed address. |
| Change card | The OTP flow is triggered to authenticate the buyer. The buyer's shipping address and card information are populated after OTP entry. Select the change card link to invoke the card selector UI via showCardSelector(). Select another card from the list. | The buyer completes the order with selected card. |
| No card or unsupported card | The OTP flow is triggered to authenticate the buyer. The buyer's shipping address and card information are populated after OTP entry. The payment component renders card fields to capture a new card. | The buyer completes the order. A new card is added to the buyer's Fastlane profile. |
| No address or address in unsupported region | The OTP flow is triggered to authenticate the buyer. No address is returned in the profile object. The shipping address collection form is rendered. Enter a new address. The card is populated after OTP entry. | The buyer completes the order. A new shipping address is added to the buyer's Fastlane profile. |
PayPal members that choose not to save their profile will be treated as guest users.
PayPal members that choose to save their profile will be treated as returning Fastlane members for future transactions.
PayPal members do not require any additional handling within your integration because our client SDK handles this use case for you in the following ways:
- After performing the
lookupCustomerByEmailmethod, we return acustomerContextIdas if this were a Fastlane member. - When you call the
triggerAuthenticationFlowmethod, our SDK displays a call to action to the buyer explaining that they can create a Fastlane profile populated with information from their PayPal account with one click. - If the consumer clicks yes, PayPal returns
profileDataexactly as we would for a Fastlane member. - If the consumer closes the dialog, PayPal returns an empty
profileDataobject and you would handle this as you would any Fastlane guest member.
Use the following test card numbers for sandbox transactions:
| Brand | Card number |
|---|---|
| Visa | 4005519200000004 |
| Visa | 4012000033330026 |
| Visa | 4012000077777777 |
| Mastercard | 5555 5555 5555 4444 |
| American Express | 378282246310005 |
| Error condition | How to handle |
|---|---|
| Authorization error while initializing Fastlane | This error indicates that your merchant account and your client credentials may not be fully provisioned for Fastlane. Talk to your account team for assistance. |
| Fastlane member doesn't have cards or addresses | Add a new card or address to the buyer's Fastlane profile. Complete the order. The payment should be completed successfully with the new card. |
FastlaneCardComponent.getPaymentToken() does not return a payment token | Ensure that you are passing the required parameters formatted appropriately to the method. |
The following methods return undefined:
| Fastlane has been disabled from within the PayPal dashboard. |
If Fastlane has been disabled by the merchant, the Fastlane client SDK will revert to the guest experience without the ability to opt-in to creating a Fastlane profile. This ensures there is no interruption to your buyers.
In the event of Fastlane being disabled from within the PayPal developer portal or PayPal account settings, note that the following methods will return undefined:
identity.triggerAuthenticationFlow()profile.showShippingAddressSelector()profile.showCardSelector()
Yes, the paymentToken that is returned on the client can only be saved when you create a transaction on your server. PayPal only supports vaulting when using the store_in_vault attribute of the create order request.
Fastlane does not support a flow where a customer or payment_method is created prior to a transaction.
A paymentToken is valid for 3 hours from the time of issuance
When you initially call window.paypal.fastlane.create(), you have the option of passing in a list of allowed locations using the addressOptions object.
Call the triggerAuthenticationFlow() method every time the checkout page is reloaded. There is internal logic within our SDK that determines whether we require the payer to authenticate via OTP again or restore the session. In either case, the method returns the authenticatedCustomerResult. This also includes a new paymentToken.
Fastlane is only available to payers in the US. If you are located outside of the US, you will need to use a VPN when testing in order to test the payer flows.
5. Go live
If you have fulfilled the requirements for accepting card payments via Fastlane for your business account, review Move your app to production to learn how to test and go live.
If this is your first time testing in a live environment, follow these steps:
- Log into the PayPal Developer Dashboard with your PayPal business account.
- Complete production onboarding so you can process card payments with your live PayPal business account.
Select Advanced Credit and Debit Card Payments on your REST app. The merchant will be signed up for advanced credit and debit after onboarding through Partner Referral API.