Learn how to take card payments in a web client with the Web Payments SDK.
Web Payments SDK

Take a Card Payment with the Web Payments SDK

Use the Web Payments SDK Quickstart sample project to set up a web application that is integrated with the Square Web Payments SDK for taking payments.

The following video demonstrates how to build an end-to-end payment flow. For a detailed overview of building with the card payment method, see the following sections in this topic.

To accept a card payment from a buyer, you need a web client where the buyer enters payment card information and a backend that takes a payment with the card. The SDK produces a secure one-time-use payment token based on the card. Your web client sends the payment token to your backend where the payment is taken. In summary, a payment is taken with these steps:

  1. Generate a payment token. Use the Web Payments SDK client library to render a card entry form and generate a payment token that your web client sends to your backend server.

  2. Create a payment with the token. On your backend, use the Square Payments API to create a payment.

This topic shows you where to add HTML and JavaScript to your web client to integrate the Web Payments SDK and take a payment on your backend.

You can find a full example of the Card payment code in GitHub.

Did you know?

  • You should complete this example using the GitHub project before you attempt to integrate the Web Payments SDK into your project.

  • This topic assumes that you have migrated from SqPaymentForm to the Web Payments SDK. If you haven't yet migrated, see Migrate to the Web Payments SDK before continuing this topic.

The following shows the Card payment method rendered in a web page:

A graphic showing the Web Payments SDK card payment method rendered on a web page.

To request the buyer to provide contact information and other additional information for the payment, you can add additional payment form fields.

Start by cloning the quickstart project template into a folder on your computer.

Test the application

The project template is not initially integrated with the SDK and does not render the card payment form.

  1. Follow the GitHub repo README instructions to get the development server running.

  2. Open a browser to http://localhost:3000 to verify that the server is running.

    Your web page looks like the following page:

    A graphic showing the default Quickstart web page that confirms that the sample is running.

Success

If your web page renders as shown in the previous image, you are ready to write the code that adds the Card payment method to the page.

The walkthrough asks you to update the code in these project files:

  • The public/index.html file is an empty static HTML page where you add the Web Payments SDK and application logic.

  • The public/app.css file is the stylesheet that contains some preset styles to help with the page layout.

  • The top-level server.js file contains the server call to the CreatePayment endpoint for charging the payment source. The quickstart application must include server.js to make the server call; otherwise, the application can't create a payment. The quickstart project also includes tests in the server.tests.js file.

    Important

    The value in server.js line 45 sets the currency for the quickstart to US dollars. If your default test account is based in another country, be sure to update server.js with the currency code for your country before you run the quickstart.

Get the web client ready to accept a payment card and send the resulting token to the server component of the quickstart application.

You need your Sandbox credentials because the quickstart application is configured to send requests to the Square Sandbox instead of your production Square account.

  1. Open the Developer Dashboard and click the plus symbol under "Applications" to create a new application.

  2. Open the application and choose the Credentials page.

  3. Set the Developer Dashboard mode to Sandbox to get a Sandbox application ID.

  4. Copy the Sandbox Application ID and Sandbox Access Token.

  5. Choose the Locations page and copy the Sandbox location ID.

  6. Paste the application ID, location ID, and Sandbox access token into a temporary text file.

Important

The Sandbox access token is a secure secret. Do not share it with anyone or upload it to the cloud.

An animation showing the process for getting application credentials in the Developer Dashboard.

The quickstart server code calls the CreatePayment endpoint and needs to be updated to use your Sandbox access token.

  1. In the project root folder, create a copy of the .env.example file and name it .env.sandbox.

    Did you know?

    The dotenv library is used to manage secrets that should not be made public. The .env.sandbox file should never be committed.

  2. Open the copied file to edit.

  3. Define SQUARE_ACCESS_TOKEN with your Sandbox access token from the Developer Dashboard.

  4. Restart your server for the Sandbox test environment (npm run dev) to use this new value.

You need a Sandbox application ID and Sandbox location ID in the following steps. You should paste these values into a text file or leave the Developer Dashboard open in another browser tab so that you can copy the values as needed.

  1. Replace the body of public/index.html with this HTML:

    This HTML adds an element (<div id="card-container" >) that the Web Payments SDK attaches the card element to and adds a button that starts the tokenization process.

    Did you know?

    The SDK also enables the Apple Pay, Google Pay, ACH (bank transfer), Square gift card, and Cash App Pay payment methods.

The following JavaScript instantiates the SDK, provides the Card payment object, attaches it to the page, and generates the payment token:

  1. Add an empty <script> tag to the <head> of index.html after <script type="text/javascript" src="https://sandbox.web.squarecdn.com/v1/square.js"></script>.

  2. Add the following global constants inside the <script> tag, substituting the IDs from the Developer Dashboard for the placeholder ({YOUR_SANDBOX_APPLICATION_ID} and {YOUR_SANDBOX_LOCATION_ID}) values.

  3. Add the following code inside the <script> tag:

The code does the following:

  1. Initializes the Web Payments SDK by calling Square.payments(appId, locationId).

  2. Initializes the Card payment method by calling the Payments .card() method and attaching the payment method to the page DOM by calling the Card .attach() method.

Note

The Card payment method of the Web Payments SDK automatically infers whether to display the postal code and copy (ZIP code, postal code, or postcode) based on the issuing country of the buyer's credit card. Depending on the card that's used, the SDK automatically removes the postal code if the card's issuing country does not require the postal code for the payment.

Test the application

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

    A graphic showing the Quickstart web page after all walkthrough steps are completed and a Pay $1.00 button.

Success

You should now be able to see the payment card input rendered on your page.

Did you know?

If you need to clear the contents of the card entry fields for the buyer, call card.destroy() to destroy the object and then call the initializeCard(payments) function again to initialize and attach the card to your application DOM.

Before you can take a payment, you need to configure your developer credentials, which can be found in the Developer Dashboard.

Note

This example uses the Square Sandbox to accept a payment. You should use the Sandbox test card values. However, if you choose to use your own payment card, the Sandbox does not charge it.

  1. Add the following code after the initializeCard function inside the <script> tag:

    • 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
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
     // Call this function to send a payment token, buyer name, and other details
     // to the project server code so that a payment can be created with 
     // Payments API
     async function createPayment(token) {
       const body = JSON.stringify({
         locationId,
         sourceId: token,
       });
       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);
     }
    
     // This function tokenizes a payment method. 
     // The ‘error’ thrown from this async function denotes a failed tokenization,
     // which is due to buyer error (such as an expired card). It is up to the
     // developer to handle the error and provide the buyer the chance to fix
     // their mistakes.
     async function tokenize(paymentMethod) {
       const tokenResult = await paymentMethod.tokenize();
       if (tokenResult.status === 'OK') {
         return tokenResult.token;
       } else {
         let errorMessage = `Tokenization failed-status: ${tokenResult.status}`;
         if (tokenResult.errors) {
           errorMessage += ` and errors: ${JSON.stringify(
             tokenResult.errors
           )}`;
         }
         throw new Error(errorMessage);
       }
     }
    
     // Helper method for displaying the Payment Status on the screen.
     // status is either SUCCESS or FAILURE;
     function displayPaymentResults(status) {
       const statusContainer = document.getElementById(
         'payment-status-container'
       );
       if (status === 'SUCCESS') {
         statusContainer.classList.remove('is-failure');
         statusContainer.classList.add('is-success');
       } else {
         statusContainer.classList.remove('is-success');
         statusContainer.classList.add('is-failure');
       }
    
       statusContainer.style.visibility = 'visible';
     }    
    
  2. Add the following code to the DOMContentLoaded event listener in step 4.3 by replacing // Step 5.2: create card payment with the following code:

The complete DOMContentLoaded Event Listener should look like the following code:

  • 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
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
document.addEventListener('DOMContentLoaded', async function () {
  if (!window.Square) {
    throw new Error('Square.js failed to load properly');
  }

  const payments = window.Square.payments(appId, locationId);
  let card;
  try {
    card = await initializeCard(payments);
  } catch (e) {
    console.error('Initializing Card failed', e);
    return;
  }

  // Checkpoint 2.
  async function handlePaymentMethodSubmission(event, paymentMethod) {
    event.preventDefault();

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

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

  const cardButton = document.getElementById(
    'card-button'
  );
  cardButton.addEventListener('click', async function (event) {
    await handlePaymentMethodSubmission(event, card);
  });
});

The code does the following:

  1. Binds the Card tokenization to the trigger event, which is clicking the Pay button in this case.

  2. Submits the tokenized card information and payment token by calling the CreatePayment endpoint on the backend.

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

  2. Input the card number 5105 1051 0510 5100 from the Sandbox Test Values. Any CVV or postal code works.

  3. Choose the Pay $1.00 button.

    An animation showing the behavior of the card entry payment method for the Web Payments SDK as credit card information is being added and the Pay $1.00 button is being selected.

Checkpoint 3: You should see a green check mark and Payment successful on the page. The payment is credited to your developer test account. The next section shows how to find the payment in the Sandbox Seller Dashboard.

Look at your Developer Dashboard for a debug log of the payment information.

Did you know?

You can use any value from the Sandbox Test Values provided by Square.

The payment is credited to the Sandbox test account whose access token is used in the application that you just built. To see the payment in the Sandbox Seller Dashboard, go to the Developer Dashboard.

  1. Choose Open on the default test account to access the Sandbox Seller Dashboard.

  2. Choose Transactions.

    An animation showing how to open the Seller Dashboard and view a transaction from the Developer Dashboard.

You can see a complete code example in the Web Payments Quickstart in GitHub.

This section explains how to deploy your application in production with the following tasks:

  • Replace your Sandbox access token and application ID with production values.

  • Update your code to make API calls to Square production endpoints.

Important

Your account must be activated to accept payments. Be sure to activate your account before continuing this walkthrough. If the Developer Dashboard Credentials page indicates that your account is not activated, follow the steps to activate it.

Deployment tasks include:

  1. Get production application credentials. In the "Get Sandbox application credentials" section, you obtained Sandbox credentials. Follow the steps to open the Developer Dashboard, but this time choose Production mode and copy the production application ID and access token.

  2. Update script references. In the ADD SCRIPT REFERENCES section, you added script references in index.html. Update the domain string in the JavaScript reference from sandbox.web.squarecdn.com/v1/square.js to web.squarecdn.com/v1/square.js.

  3. Provide your production application ID. The Web Payments SDK requires a valid application ID to return a payment token. In the "Provide your application ID" section, you provided a Sandbox application ID. Update the code by providing your production application ID.

  4. Configure your backend server to use a production access token. In the "Configure the backend with your access token" section, you provided a Sandbox access token. Replace it with the production access token.

If you want to test the application in a production environment (squareup.com), you must use an actual payment card. Note that Square actually charges payment cards in production. Therefore, if you must test in production, charge minimum amounts.

Now that you are taking payments with credit and debit cards, you can add additional payment methods or customize the appearance of the Card payment method.

To add security to a payment method, you can add the 3D Secure security protocol layer to the application. 3D Secure integrates Strong Customer Authentication (SCA) to verify the identity of the payment card holder by using the verifyBuyer function.

With card information, you can also save card information to file with the Cards API.

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