Learn about Strong Customer Authentication as implemented in a Square API.
Web Payments SDK

Verify the Buyer When Using a Payment Token

Learn how to add 3D Secure (Strong Customer Authentication, or SCA, in the EEA) to the card payment integration you built using the Quickstart project sample in Take a Card Payment with the Web Payments SDK to integrate the Web Payments SDK into your application.

The steps add code to the application you created from the Quickstart project sample. If you have not created an application using the Quickstart, you need to do so before completing the following steps.

An example of the frontend 3DS code can be found in the GitHub Web Payments SDK Quickstart repository.

Your production application should collect the billing address of the buyer. Although providing an empty billingContact is acceptable, by providing as much billing contact information as possible, you increase the chances of a successful authentication. This example uses an object that is declared with a hard-coded billing address. Your application might collect a billing address at payment time or, if the buyer is a customer on the seller Square account, from the buyer's customer record.

Note

The Web Payments SDK produces a payment token that can be used to make a payment with the presented card or to store the card on file. These operations are represented by two intents: CHARGE to make a payment and STORE to store the card.

The code in the following steps adds the billing contact values needed by SCA (with the payments.verifyBuyer function) to verify the authenticity of the card holder:

  1. Add the following function below the tokenize function in your script tag:

    The function creates a ChargeVerifyBuyerDetails object that provides the buyer and purchase details needed by 3DS. To verify a card to be stored on file, create a StoreVerifyBuyerDetails object instead.

  2. Update the call to handlePaymentMethodSubmission in the cardButton click handler to include a third argument of true.

  3. Update the handlePaymentMethodSubmission function in the DOMContentLoaded eventListener function to have a third parameter shouldVerify and a call to the verifyBuyer function.

Important

SCA should be called for all customer-initiated transactions, including digital wallet payments. If the seller doesn't have SCA called for digital wallet payments, the transactions may be declined due to lack of authentication.

The full version of the handlePaymentMethodSubmission function should look like the following:

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
async function handlePaymentMethodSubmission(
  event,
  paymentMethod,
  shouldVerify = false
) {
  event.preventDefault();

  try {
    // disable the submit button as we await tokenization and make a payment
    // request.
    cardButton.disabled = true;
    const token = await tokenize(paymentMethod);
    let verificationToken;

    if (shouldVerify) {
      verificationToken = await verifyBuyer(
        payments,
        token
      );
    }

    console.debug('Verification Token:', verificationToken);

    //TODO: Add the verification token in Step 2.2
    const paymentResults = await createPayment(token);
    displayPaymentResults('SUCCESS');

    console.debug('Payment Success', paymentResults);
  } catch (e) {
    cardButton.disabled = false;
    displayPaymentResults('FAILURE');
    console.error(e.message);
  }
}

Test the application

  1. Navigate to http://localhost:3000/ in your browser.

  2. Use one of the test cards from the following table with a challenge type of "Modal with Verification Code":

    Brand
    Numbers
    CVVChallenge typeVerification code
    Visa4800 0000 0000 0004111No ChallengeN/A
    Mastercard5222 2200 0000 0005111No ChallengeN/A
    Discover EU6011 0000 0020 1016111No Challenge123456
    Visa EU4310 0000 0020 1019111Modal with
    Verification Code
    123456
    Mastercard5248 4800 0021 0026111Modal with
    Verification Code
    123456
    Mastercard EU5500 0000 0020 1016111Modal with
    Verification Code
    123456
    American Express EU3700 000002 010141111Modal with
    Verification Code
    123456
    Mastercard5333 3300 0000 0008111Modal with Multiple Verification QuestionsChallenge 1: Thomason
    Challenge 2: Select both St Louis & Dallas
    Challenge 3. Smith
    Visa4811 1100 0000 0008111No Challenge with Failed VerificationN/A

After you submit, you see the following window where you enter the verification code:

A graphic showing the SCA cardholder authentication window that appears when the verifyBuyer function is called.

When 3DS has verified the buyer, the verification token is logged to the Developer Dashboard.

Important

Your application should always attempt to create a payment with a verification token when a token is returned. It should also be prepared to respond to a payment failure in a small number of cases where a payment is rejected despite receiving a buyer verification token.

  1. Update the createPayment function to take the verificationToken parameter.

    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
     // verificationToken can be undefined, as it does not apply to all payment
     // methods.
     async function createPayment(token, verificationToken) {
       const bodyParameters = {
         locationId,
         sourceId: token,
       };
    
       if (verificationToken !== undefined) {
         bodyParameters.verificationToken = verificationToken;
       }
    
       const body = JSON.stringify(bodyParameters);
    
       // Same as in the cards example.
       const paymentResponse = await fetch('/payment', {
         method: 'POST',
         headers: {
           'Content-Type': 'application/json',
         },
         body,
       });
    
       if (paymentResponse.ok) {
         return paymentResponse.json();
       }
    
       const errorBody = await paymentResponse.text();
       throw new Error(errorBody);
     }
    
  2. Add the verification token parameter to the createPayment function call in the DOMContentLoaded eventListener.

  3. On your backend, modify your payment object to include a verificationToken. If you are using the Square example server, this is done for you as shown in the following code from server.js:

Test the application

  1. Navigate to http://localhost:3000/ in your browser.

  2. Choose the Pay $1.00 button.

    You see the SCA window. The payment succeeds on successfully completing the challenge.

If you need more assistance, contact Developer Support or ask for help in the Developer Forums.