3D Secure for Fastlane

Last updated: Dec 4th, 4:27pm

Use Fastlane's 3D Secure (3DS) to authenticate cardholders through card issuers. 3DS reduces fraud for supported cards and improves transaction performance. For more details, see 3D Secure authentication.

Fastlane provides two options for performing 3DS:

  • Orders v2 API: Run 3DS one time for each transaction when you integrate 3DS using the 3DS Orders v2 API. If the customer closes the modal or fails authentication, the Orders v2 API cannot issue a new challenge. Process the payment, request a new card, or complete another 3DS verification with the JavaScript SDK 3DS component.
  • PayPal JavaScript SDK 3DS component: Use this component to complete 3DS verification. If you do not receive results, repeat 3DS verification, request a different card, or use Orders v2 to process the transaction.


How it works

Follow these steps to make a 3DS call.

  1. Generate an access token.
  2. Render the checkout page to collect payment information.
  3. Verify the credit card amount.
  4. Authenticate the customer if required by the issuer or local regulations.

If authentication succeeds or is not required, process the payment with the returned payment token or save the payment method for future transactions.

3DS with JavaScript SDK

Use PayPal’s JavaScript SDK or perform a server-side call with the Orders v2 API to support 3DS.


Generate access token

Generate an access token to authenticate PayPal API requests.


Request

    1curl -s -X POST "https://api-m.sandbox.paypal.com/v1/oauth2/token" \
    2 -u CLIENT_ID:CLIENT_SECRET \
    3 -H "Content-Type: application/x-www-form-urlencoded" \
    4 -d "grant_type=client_credentials" \
    5 -d "response_type=client_token" \
    6 -d "intent=sdk_init" \
    7 -d "domains[]=example.com,example2.com"

    Modify the code

    1. Get your client ID and secret from your Developer Dashboard.
    2. Copy the sample code. Replace CLIENT_ID with your client ID.
    3. Replace CLIENT_SECRET with your client secret.
    4. Replace example.com,example2.com with your domains.
    5. Provide the root domain name only.

    Response

      1{
      2 "scope": "https://uri.paypal.com/services/invoicing https://uri.paypal.com/services/disputes/read-buyer https://uri.paypal.com/services/payments/realtimepayment https://uri.paypal.com/services/disputes/update-seller https://uri.paypal.com/services/payments/payment/authcapture openid https://uri.paypal.com/services/disputes/read-seller https://uri.paypal.com/services/payments/refund https://api-m.paypal.com/v1/vault/credit-card https://api-m.paypal.com/v1/payments/.* https://uri.paypal.com/payments/payouts https://api-m.paypal.com/v1/vault/credit-card/.* https://uri.paypal.com/services/subscriptions https://uri.paypal.com/services/applications/webhooks",
      3 "access_token": "<access_token>",
      4 "token_type": "Bearer",
      5 "app_id": "<APP-ID>",
      6 "expires_in": 31668,
      7 "nonce": "<NONCE_FROM_FASTLANE_INTEGRATION>"
      8}

      Initialize PayPal JavaScript SDK and Fastlane

      Add the SDK script tag.

        1<script>
        2 src="https://www.paypal.com/sdk/js?client-id=<CLIENT_ID>>&components=buttons,fastlane,three-domain-secure"
        3 data-sdk-client-token="<SDK_CLIENT_TOKEN>"
        4</script>

        Load the Fastlane component.

          1// instantiates the Fastlane module
          2const fastlane = await window.paypal.Fastlane({ });
          3// Convenience parameters for calling later on
          4const { identity,
          5 profile,
          6 FastlaneCardComponent,
          7 FastlaneWatermarkComponent,
          8 } = fastlane;
          9 fastlane.setLocale('en_us'); // Sets customer's country and language

          Check 3DS eligibility

          Initialize 3DS after receiving the payment token and order amount.

            1// Check eligibility
            2const threeDomainSecureComponent = window.paypal.ThreeDomainSecureClient;

            After you receive a payment token and the order amount, verify your eligibility.

              1const threeDomainSecureParameters = {
              2 amount: '12.00',
              3 currency: 'USD',
              4 nonce: NONCE_FROM_FASTLANE_INTEGRATION,
              5 threeDSRequested: SCA_ALWAYS | SCA_WHEN_REQUIRED in the eligibility API request, otherwise defaults to SCA_WHEN_REQUIRED
              6 transactionContext: {
              7 experience_context: {
              8 brand_name: "YourBrandName",
              9 locale: "en-US",
              10 return_url: "https://example.com/returnUrl",
              11 cancel_url: "https://example.com/cancelUrl",
              12 },
              13 // Optional
              14 transaction_context: {
              15 soft_descriptor: "Card verification hold",
              16 },
              17 },
              18};
              19const isThreeDomainSecureEligible = await threeDomainSecureComponent.isEligible(
              20 threeDomainSecureParameters,
              21);

              Customer attempts 3DS authentication

              When the customer selects the submit button, trigger the authentication step and handle the result.

                1const submitButton = document.getElementById("submit-button");
                2submitButton.addEventListener("click", async () => {
                3 if (isThreeDomainSecureEligible) {
                4 const {
                5 liabilityShift, // "no", "unknown", "possible"
                6 authenticationState, // "success", "cancelled", "errored"
                7 nonce, //Enriched nonce or the original nonce
                8 } = await threeDomainSecureComponent.show();
                9 if (authenticationState === "success") {
                10 // Check the liability shift and decide on continuing the transaction
                11 } else {
                12 // Cancelled or errored, merchant can choose to send the customer back to 3DS or submit a payment and or vault the payment token.
                13 }
                14 }
                15})


                Client-side response parameters

                The JavaScript SDK returns the following parameters after authentication.

                Parameter Value Description Action
                liabilityShift POSSIBLE Liability might shift to issuer Continue with authorization
                liabilityShift NO Liability stays with merchant Do not continue with authorization
                liabilityShift UNKNOWN Authentication system unavailable Do not continue, request cardholder retry
                authenticationState success Customer successfully authenticated No action needed
                authenticationState cancelled Customer cancelled the authentication No action needed
                authenticationState errored Error occurred during authentication No action needed

                Process the payment using the Orders v2 API to validate the endrollmentStatus of the user.

                3DS with Orders v2 API

                After Fastlane generates a payment token and the customer places the order, call the Orders v2 API to check 3DS eligibility.

                Use the returned URL to redirect the customer for authentication. Use the following API call for single-step 3DS verification.

                  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 client
                  11 "attributes": {
                  12 "verification": {
                  13 "method": "SCA_WHEN_REQUIRED"
                  14 }
                  15 }
                  16 }
                  17 },
                  18 "experience_context": {
                  19 "brand_name": "YourBrandName",
                  20 "locale": "en-US",
                  21 "return_url": "https://example.com/returnUrl",
                  22 "cancel_url": "https://example.com/cancelUrl"
                  23 },
                  24 "transaction_context": {
                  25 "soft_descriptor": "Card verification hold"
                  26 },
                  27 "purchase_units": [
                  28 {
                  29 "amount": {
                  30 "currency_code": "USD",
                  31 "value": "50.00",
                  32 "breakdown": {
                  33 "item_total": {
                  34 "currency_code": "USD",
                  35 "value": "40.00"
                  36 },
                  37 "shipping": {
                  38 "currency_code": "USD",
                  39 "value": "10.00"
                  40 }
                  41 }
                  42 },
                  43 "items": [
                  44 {
                  45 "name": "Coffee",
                  46 "description": "1 lb Kona Island Beans",
                  47 "sku": "sku03",
                  48 "unit_amount": {
                  49 "currency_code": "USD",
                  50 "value": "40.00"
                  51 },
                  52 "quantity": "1",
                  53 "category": "PHYSICAL_GOODS",
                  54 "image_url": "https://example.com/static/images/items/1/kona_coffee_beans.jpg",
                  55 "url": "https://example.com/items/1/kona_coffee_beans",
                  56 "upc": {
                  57 "type": "UPC-A",
                  58 "code": "987654321015"
                  59 }
                  60 }
                  61 ],
                  62 "shipping": {
                  63 "type": "SHIPPING",
                  64 "name": {
                  65 "full_name": "<FULL_NAME>"
                  66 },
                  67 "address": {
                  68 "address_line_1": "123 Main St.",
                  69 "admin_area_2": "Anytown",
                  70 "admin_area_1": "CA", //must be sent in 2-letter format
                  71 "postal_code": "12345",
                  72 "country_code": "US"
                  73 },
                  74 "phone_number": {
                  75 "country_code": "1",
                  76 "national_number": "5555555555"
                  77 }
                  78 }
                  79 }
                  80 ]
                  81}'


                  Redirect customer for authentication

                  Redirect the buyer to the rel: payer-action HATEOAS link before authorizing or capturing the order. Add redirect_url as a query parameter, so PayPal returns the payer to your checkout page after authentication. The following is a sample URL: https://example.com/webapp/myshop?action=verify&flow=3ds&cart_id=ORDER-ID&redirect_uri=MERCHANT-LANDING-PAGE.

                  Verify 3DS status

                  After the customer returns, check the verification status of the order by passing the order ID in a GET call to /v2/checkout/orders/{id}. A successful call returns an HTTP 200 response with the following content.

                  1. Request
                  2. Response
                  1curl -v -X GET https://api-m.sandbox.paypal.com/v2/checkout/orders/ORDER_ID \
                  2-H 'Authorization: Bearer Bearer <Access-Token>'

                  Server-side response parameters

                  When using the Orders v2 API, you receive comprehensive 3DS parameters on the server side.


                  LiabilityShift

                  Parameter Value Description Action
                  LiabilityShift POSSIBLE Liability may shift to the issuer Continue with authorization
                  LiabilityShift NO Liability stays with the merchant Do not continue with authorization
                  LiabilityShift UNKNOWN Authentication system unavailable Request cardholder retry


                  EnrollmentStatus

                  Parameter Value Description Action
                  EnrollmentStatus Y Card and bank ready for 3DS Proceed with authentication
                  EnrollmentStatus N Not ready for 3DS Do not proceed with authentication
                  EnrollmentStatus U System unavailable Request cardholder retry
                  EnrollmentStatus B System bypassed authentication Proceed with order


                  Authentication_Status

                  Parameter Value Description Action
                  Authentication_Status Y Successful authentication No action needed
                  Authentication_Status N Failed authentication No action needed
                  Authentication_Status R Rejected authentication No action needed
                  Authentication_Status A Attempted authentication No action needed
                  Authentication_Status U Unable to complete No action needed
                  Authentication_Status C Challenge required No action needed


                  Parameter availability

                  The Orders v2 API provides all three parameters on the server side, LiabilityShift, EnrollmentStatus, and Authentication_Status. The JavaScript SDK provides only liabilityShift and authenticationState. It does not provide EnrollmentStatus.

                  Parameter Orders v2 API JavaScript SDK
                  liabilityShift Yes Yes
                  enrollmentStatus Yes No
                  authenticationState Yes Yes


                  Complete the transaction

                  After 3DS authentication, you can complete the transaction using one of two methods: processing the payment or saving the payment method.


                  Process payment

                  You can capture the payment using a single-step or multi-step API request.

                  • In a single-step flow, after the 3DS contingency is resolved during the create order response, call the authorize order and capture order endpoints with empty payloads.
                  • In a multi-step flow, if the 3DS contingency occurs during an authorize order or capture order request, resolve the contingency, then call those endpoints again with empty payloads.


                  Save payment method

                  To save the customer’s payment method for future use after 3DS authentication, use the Payment Method Tokens v3 API.

                  • To process the current payment and vault the payment method for future transactions, use the single payment with vault option.
                  • To save the payment method without processing an immediate payment, use the vault-only option.

                  Capture the payment

                  After successful 3DS authentication, capture the authorized payment using the Orders v2 API capture endpoint.

                  1. Capture request (Server-side)
                  2. Capture response
                  1curl -v -X POST https://api-m.sandbox.paypal.com/v2/checkout/orders/{order_id}/capture \
                  2 -H 'Authorization: Bearer PAYPAL_ACCESS_TOKEN' \
                  3 -H 'Content-Type: application/json' \
                  4 -H 'PayPal-Request-Id: UNIQUE_REQUEST_ID'


                  Handle capture status

                  Check the capture status in the response to determine next steps.

                  Status Description Action
                  COMPLETED Payment successfully captured Fulfill the order and provide goods or services
                  DECLINED Payment declined by issue Notify the customer to use a different payment method
                  PENDING Payment under review Do not ship until the status is COMPLETED
                  FAILED Capture failed Review the error details and retry if appropriate


                  Ensure all fulfillment or follow-up actions align with the current status of the payment capture response from the Orders v2 API.

                  Payment integration samples

                  The following code samples demonstrate how to initiate payment requests and manage payment methods using the Orders v2 API and Payment Method Tokens API.

                  1. Payment
                  2. Save payment method
                  3. Vault
                  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: YOUR_CMID' \
                  6 -d '{
                  7 "intent": "CAPTURE",
                  8 "payment_source": {
                  9 "card": {
                  10 "single_use_token": "1h371660pr490622k" // Payment token from the client
                  11 }
                  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 pound of coffee 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/coffee_beans.jpg",
                  41 "url": "https://example.com/items/1/coffee_beans",
                  42 "upc": {
                  43 "type": "UPC-A",
                  44 "code": "987654321015"
                  45 }
                  46 }
                  47 ],
                  48 "shipping": {
                  49 "type": "SHIPPING",
                  50 "name": {
                  51 "full_name": "Firstname Lastname"
                  52 },
                  53 "address": {
                  54 "address_line_1": "123 Main St.",
                  55 "admin_area_2": "Anytown",
                  56 "admin_area_1": "CA", // Must be sent in 2-letter format
                  57 "postal_code": "12345",
                  58 "country_code": "US"
                  59 },
                  60 "phone_number": {
                  61 "country_code": "1",
                  62 "national_number": "5555555555"
                  63 }
                  64 }
                  65 }
                  66 ]
                  67}'


                  Sandbox testing

                  To trigger 3DS in Sandbox, add a valid BIN test card to your Fastlane profile. Use the following recommended test card.

                  Card network Card number Expiration date CVV
                  Mastercard
                  5186459910794125 Any future date 123