Square Payment Form

Walkthrough: Integrate Square Payments In a Website

This topic provides a walkthrough with step-by-step instructions to set up a simple website integrated with Square for payments. We’ll keep the exercise simple and build a basic form that just takes a credit card on a web page as shown:

PaymentForm

At the end of the exercise, we provide links to topics that explain how you can add other payment sources, such as digital wallets, to your website.

Processing payments in a website using Square is a 2-step process:

  1. Generate a secure single use token (nonce). You use the Square SqPaymentForm client-side library to accept credit card and digital wallet payment information and generate a secure, one-time use token (nonce).

  2. Charge the payment source using the nonce. You use the Connect V2 Payments API to charge the payment source that the nonce represents.


You follow this process to set up a website. You then test the setup by taking a payment. We also show you how to review the payment in the Seller dashboard. At the end, we explain a variation of the payment form called single-element payment form.

Before you begin, note the following:

  • The walkthrough uses a Node.js web server project template that we provide. We chose Node.js because it is easy to set up and test. After finishing this walkthrough, you can explore similar examples in other languages we provide on GitHub. For more information, see connect-api-examples.

  • We use the v2 Sandbox (beta) environment for testing. In the sandbox, you don’t charge your real credit card, instead use a fake card Square provides for Sandbox testing. After taking a payment, we show you how the payment appears in the Sandbox Seller Dashboard.

  • If you are new to Square payment forms, you should follow the step-by-step instructions. A complete sample is available on GitHub for download if you want to check the code in your project at the end of this walkthrough.

Get ready
Permalink Get a link to this section

To prepare for this walkthrough, you do 3 things:

  • Install Node.js and npm (a Node.js package manager).

  • Get your application credentials from Square’s Developer Dashboard.

  • Download the project template created for this exercise

Install Node.js and npm
Permalink Get a link to this section

When you install Node.js, you also get npm. For instructions, see Node.js.

Get sandbox application credentials
Permalink Get a link to this section

We use the v2 Sandbox (beta) environment for testing. Therefore, you use your sandbox credentials.

  1. Open the Developer Dashboard and select an application. The Credentials page for the selected app is shown.

  2. Set the dashboard mode to Production Settings for a production application ID or Sandbox Settings for a sandbox application ID (used in testing).

  3. Copy the Application ID and the Sandbox Access Token in the Credentials section of the page.


Developer Dashboard in Sandbox Settings mode

image-test sandbox-01@2x

You use application ID to obtain a nonce in step 1, and the personal access token to take a payment using the Payments API in step 2.

Download project template
Permalink Get a link to this section

For this exercise, you start with a predefined project template to set up your initial web server. Do the following:

  1. Download or clone the Node.js project template.

    • Download the zip and unzip the content to a local directory.

    • Clone the GitHub repository to a local directory.

      Note

      Cloned and downloaded projects create different directory names:

      • Cloned: Sqpaymentform-nodejs-starterkit

      • Downloaded: Sqpaymentform-nodejs-starterkit-master

      • Downloaded full sample: Sqpaymentform-nodejs-starterkit-sample

  2. Bring up a command line.

  3. Change to the project directory.

  4. Review the following files in the project directory:

    • index.html is an empty static HTML page where you'll embed SqPaymentForm.

    • mysqpaymentform.css is a sample CSS file (stylesheet) to customize the look of the card entry fields on the page.

    • server.js contains the server-side component that will charge the payment source (Step 2).

  5. Run the following commands:

    • Install dependencies:

      npm install
      
    • Start the server:

      npm start
      
  6. Verify the node server is running. Open a browser window and enter http://localhost:3000. You should see the following: PaymentFormLocatHost3000V3

Now you are ready to build a web page that embeds the SqPaymentForm.

Step 1: Generate a secure single use token (nonce)
Permalink Get a link to this section

In this step, you will do the following:

  • Build a web page with SqPaymentForm embedded in it.

  • Test the page by submitting card information and verifying that you get a nonce.

1.1: Embed SqPaymentForm in a static web page
Permalink Get a link to this section

In this step, you add the following components to the index.html page:

  • Required CSS and JS references.

  • A <div/> with credit card fields.

  • A <script/>. The script manages the SqPaymentForm object and user interaction using a JavaScript initializing block and <div/> tags in the form.

1.1.1: Add script references
Permalink Get a link to this section

Open index.html and add the following references in the <head/> section.

<!-- link to the SqPaymentForm library -->
<script type="text/javascript" src="https://js.squareupsandbox.com/v2/paymentform">
</script>

<!-- link to the local custom styles for SqPaymentForm -->
<link rel="stylesheet" type="text/css" href="mysqpaymentform.css">

Note the following about these references:

  • js.squareupsandbox.com/v2/paymentform is the Square JavaScript library used in testing the payment form in the v2 Sandbox (beta).

  • mysqpaymentform.css is the file provided as part of the project you downloaded.

1.1.2: Add an HTML div
Permalink Get a link to this section

Add the following HTML <div/> in the <body/> section of the same index.html.


   <div id="form-container">
     <div id="sq-card-number"></div>
     <div class="third" id="sq-expiration-date"></div>
     <div class="third" id="sq-cvv"></div>
     <div class="third" id="sq-postal-code"></div>
     <button id="sq-creditcard" class="button-credit-card" onclick="onGetCardNonce(event)">Pay $1.00</button>
   </div> <!-- end #form-container --> 
   <!-- TODO: Add script from step 1.1.3 -->

In the form, note the following:

  • Each credit card field is an empty <div/> with an id. SqPaymentForm will replace each <div/> with an input element that runs securely on Square’s domain. This allows the form to take credit card input while keeping your code outside of PCI scope.

  • The onclick event handler (onGetCardNonce) calls the SqPaymentForm.requestCardNonce library function to get a nonce.

1.1.3: Add JavaScript to index.html
Permalink Get a link to this section

In this section, you provide code to the HTML page to configure and initialize the SqPaymentForm object. We add the <script/> in the because SqPaymentForm can be initialized only after the DOM is fully loaded.

Copy and paste the following code after the <!-- TODO: Add script from step 1.1.3 --> in index.html:

   <script type="text/javascript">
     // Create and initialize a payment form object
     const paymentForm = new SqPaymentForm({
       // Initialize the payment form elements
       
       //TODO: Replace with your sandbox application ID
       applicationId: "REPLACE_WITH_APPLICATION_ID",
       inputClass: 'sq-input',
       autoBuild: false,
       // Customize the CSS for SqPaymentForm iframe elements
       inputStyles: [{
           fontSize: '16px',
           lineHeight: '24px',
           padding: '16px',
           placeholderColor: '#a0a0a0',
           backgroundColor: 'transparent',
       }],
       // Initialize the credit card placeholders
       cardNumber: {
           elementId: 'sq-card-number',
           placeholder: 'Card Number'
       },
       cvv: {
           elementId: 'sq-cvv',
           placeholder: 'CVV'
       },
       expirationDate: {
           elementId: 'sq-expiration-date',
           placeholder: 'MM/YY'
       },
       postalCode: {
           elementId: 'sq-postal-code',
           placeholder: 'Postal'
       },
       // SqPaymentForm callback functions
       callbacks: {
           /*
           * callback function: cardNonceResponseReceived
           * Triggered when: SqPaymentForm completes a card nonce request
           */
           cardNonceResponseReceived: function (errors, nonce, cardData) {
           if (errors) {
               // Log errors from nonce generation to the browser developer console.
               console.error('Encountered errors:');
               errors.forEach(function (error) {
                   console.error('  ' + error.message);
               });
               alert('Encountered errors, check browser developer console for more details');
               return;
           }
              alert(`The generated nonce is:\n${nonce}`);
              //TODO: Replace alert with code in step 2.1
           }
       }
     });
     //TODO: paste code from step 1.1.4
   </script>

In the JavaScript code, note the following:

  • The callback cardNonceResponseReceived alerts the user that a nonce is generated and returned by the SqPaymentForm object. In step 2.1, The nonce will be POSTed to a server-side component to charge the payment source. The server-side component is reviewed in Step 2.

1.1.4: Add javascript to handle "Pay $1.00" button click event “onclick”
Permalink Get a link to this section

In this section, you add a callback function to handle the pay button click event. The event handler calls requestCardNonce to get the payment card nonce from the SqPaymentForm object.

Copy and paste into index.html after //TODO: paste code from step 1.1.4

     //TODO: paste code from step 1.1.5
     // onGetCardNonce is triggered when the "Pay $1.00" button is clicked
     function onGetCardNonce(event) {
       // Don't submit the form until SqPaymentForm returns with a nonce
       event.preventDefault();
       // Request a nonce from the SqPaymentForm object
       paymentForm.requestCardNonce();
     }

1.1.5: Add javascript to build the form
Permalink Get a link to this section

In this section you add JavaScript to force the SqPaymentForm object to render the payment form in the page.

Copy and paste after //TODO: paste code from step 1.1.5

     paymentForm.build();

1.2: Provide your application ID
Permalink Get a link to this section

For SqPaymentForm to load successfully, open index.html and find //TODO: Replace with your sandbox application ID. Provide your Sandbox Application ID. SqPaymentForm requires a valid Application ID to return a nonce.

// TODO: Replace with your sandbox application ID
applicationId = "REPLACE_WITH_APPLICATION_ID";

1.3: Test the payment form and verify the secure token (nonce)
Permalink Get a link to this section

Do the following to test the payment form:

  1. Save all the files.

  2. Start the npm server, if it is not running:

    npm start
    
  3. Open a browser window and open the payment form on localhost by keying in - http://localhost:3000 at the address bar.

  4. Fill the form with the following sandbox test credit card from the test values set, and click Pay $1.00.

    • Card Number: 4111 1111 1111 1111

    • MM/YY: 12/21 (you provide any month and year that is in the future)

    • CVV: 111

    • Postal: 11111 (you can provide any postal code).

    This is one of the test cards Square provides for use in the v2 Sandbox (beta) environment.

  5. Verify that you get a nonce as shown in the following example screenshot:

PaymentFormTestNonceRcvdv2

How did this work? (Application Flow Summary)
Permalink Get a link to this section

In this section, you don't perform actions. Instead, the section explains how the code you developed in step 1 works. You can read or skip ahead to step 2 to charge the payment source.

When the page loads, it renders the payment form defined in the index.html file. The page also downloads and executes the SqPaymentForm Javascript library. This is a library that provides the SqPaymentForm object. For more information about the library, see SqPaymentForm data model.

Embedded JavaScript. This code does two things:

  • Initializes the SqPaymentForm with configuration fields and callback functions.

    Each credit card input form field requires a corresponding configuration field. For example, the SqPaymentForm initialization defines the card number input as shown in this inputTarget field.

     cardNumber: {
       elementId: 'sq-card-number',
       placeholder: 'Card Number'
     }
    

    It maps the SqPaymentForm.cardNumber configuration field to corresponding form field sq-card-number.

    The SqPaymentForm initialization also includes callback implementations, for example the SqPaymentForm.cardNonceResponseReceived. The callback executes after SqPaymentForm completes a request for a nonce.

  • Provides code for the event handler onGetCardNonce that executes after you click Pay $1.00.


After the payment form is built, it replaces DOM elements with iframes. The iframes take the buyer-entered credit card information and call the requestCardNonce function to get a nonce. This allows you to take payments through Square.

After a buyer enters their information in the form and clicks Pay $1.00, the onGetCardNonce event handler executes. This code generates a nonce by calling the SqPaymentForm.requestCardNonce function and passes the nonce back to the client by calling the SqPaymentForm.cardNonceResponseRecieved callback. The client displays an alert box with generated nonce.

Step 2: Charge the Payment Source Using the Nonce
Permalink Get a link to this section

index.html sends the nonce to Server.js by using the fetch API. Server.js uses it to create a payment. This server-side component uses the Square Node.js SDK library to call the Connect V2 Payments API to charge the payment source using the nonce. In step 2, you will add the fetch code to index.html and update server.js with your personal access token.

2.1: Add javascript to send the nonce to the backend
Permalink Get a link to this section

In this section, you make a final change to index.html. You will replace the alert that notifies on nonce received with code that actually sends the nonce to server.js.

Copy and paste the following code into index.html in place of "//TODO: Replace alert with code in step 2.1".

              fetch('process-payment', {
                method: 'POST',
                headers: {
                  'Accept': 'application/json',
                  'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                  nonce: nonce
                })
              })
              .catch(err => {
                alert('Network error: ' + err);
              })
              .then(response => {
                if (!response.ok) {
                  return response.text().then(errorInfo => Promise.reject(errorInfo));
                }
                return response.text();
              })
              .then(data => {
                console.log(JSON.stringify(data));
                alert('Payment complete successfully!\nCheck browser developer console for more details');
              })
              .catch(err => {
                console.error(err);
                alert('Payment failed to complete!\nCheck browser developer console for more details');
              });

  

2.2: Configure backend with your access token
Permalink Get a link to this section

The JavaScript code in server.js is already complete but it is not set with your sandbox personal access token. In this step, you replace the placeholder with your token.

  1. Open server.js.

  2. Update the file by providing your personal access token. Again, reminder, we are using sandbox credentials.

    accessToken = 'REPLACE_WITH_ACCESS_TOKEN';
    
  3. Review the following code fragments:

    • You create a PaymentsApi object and call the CreatePayment endpoint to charge the payment source.

      app.post('/process-payment', async (req, res) => {
         const request_params = req.body;
      
         // length of idempotency_key should be less than 45
         const idempotency_key = crypto.randomBytes(22).toString('hex');
      
         // Charge the customer's card
         const payments_api = new squareConnect.PaymentsApi();
         const request_body = {
           source_id: request_params.nonce,
           amount_money: {
             amount: 100, // $1.00 charge
             currency: 'USD'
           },
           idempotency_key: idempotency_key
         };
      
         try {
           const response = await payments_api.createPayment(request_body);
           res.status(200).json({
             'title': 'Payment Successful',
             'result': response
           });
         } catch(error) {
           res.status(500).json({
             'title': 'Payment Failure',
             'result': error.response.text
           });
         }
       });
      
    • The requestBody specifies the amount to charge and the nonce value.

      const requestBody = {
         source_id: request_params.nonce,
         amount_money: {
             amount: 100, // $1.00 charge
             currency: 'USD'
         },
         idempotency_key: idempotency_key
      }
      

2.3: Test the payment flow from client to server
Permalink Get a link to this section

This time you will generate a nonce and also charge the payment source using the generated nonce.

  1. Open a browser window and enter - http://localhost:3000.

  2. Provide card information.

    Card Number: 4111 1111 1111 1111

    MM/YY: 12/21 (you provide any month and year that is in the future)

    CVV: 111

    Postal: 11111 (you can provide any postal code).

  3. Click Pay $1.00. Upon receiving the Payments.CreatePayment endpoint request, Square processes the payment and returns response. A sample response fragment is shown:

        {
         "title":"Payment Successful",
         "result":{
             "payment": {
                 "id": "YNvVT...",
                 "created_at": "2018-10-17T20:33:59.603Z",
                 "updated_at": "2018-10-17T20:34:00.012Z",
                 "amount_money": {
                   "amount": 100,
                   "currency": "USD"
                 },
                 "status": "COMPLETED",
                 "source_type": "CARD",
                 "card_details": {
                   "status": "CAPTURED",
                   "card": {
                       "card_brand": "VISA",
                       "last_4": "1111",
                       "exp_month": 12,
                       "exp_year": 2021,
                       "fingerprint": "sq-1-9PP0tWf..."
                   },
                   "entry_method": "KEYED",
                   "cvv_status": "CVV_ACCEPTED",
                   "avs_status": "AVS_ACCEPTED",
                   "auth_result_code": "VVp3sH"
                 },
                 "reference_id": "123456"
             }
         }
        }
    
  1. Review payment in the sandbox seller sandboard. The payment is credited to the sandbox test account whose OAuth token is used in the app that you just built. To see the payment in the sandbox seller dashboard, go back to the Developer Dashboard.

    1. Click Launch on the default test account to access the sandbox seller dashboard.

      image-test sandbox-02@2x

    2. Click Transactions.

      image-payment form sandbox-03@2x

Build a single-element payment form (Beta)
Permalink Get a link to this section

The SqPaymentForm library offers two ways to configure a payment form in your website as shown:

PaymentForm-two-config-options

  • Multi-element payment form. You build the payment form with DOM elements, one for each of the card data item (card number, expiry date, CVV value, and postal code). You map each of the DOM elements to the corresponding SqPaymentForm configuration inputTarget. This is the payment form you built in the preceding walkthrough.

  • Build a single-element payment form. The SqPaymentForm library also provides the card configuration field to build a single-element payment form. The single form element can take all the card information. This can simplify coding:

    • Instead of defining the four DOM elements for taking card information you define only one DOM element and map it to the card configuration field.

    • The card configuration field provides a default CSS configuration. For example, you don't need much of the CSS work you did in the preceding exercise. The default style of the single-element form can be customized to conform to payment page styles. See Customize the Appearance of the Single-element Payment Form to learn about styling the single-element form.

    Using the card element is an alternative to building a payment form if you don't need the flexibility of individually placed payment card fields.

Let us update the walkthrough to use the card configuration element. Follow the steps to update files you created in step 1.2, where you added code to embed SqPaymentForm in a static web page.

  1. index.html. Update elements inside the <div id=”form-container”> as follows:

    1. Replace the following DOM placeholders:

     <div id="sq-card-number"></div>
     <div class="third" id="sq-expiration-date"></div>
     <div class="third" id="sq-cvv"></div>
     <div class="third" id="sq-postal-code"></div>
    

    with <div id="sq-card"></div>.

    1. Replace the JavaScript code that defined following payment card form fields:

          // Initialize the credit card placeholders
          cardNumber: {
              elementId: 'sq-card-number',
              placeholder: 'Card Number'
          },
          cvv: {
              elementId: 'sq-cvv',
              placeholder: 'CVV'
          },
          expirationDate: {
              elementId: 'sq-expiration-date',
              placeholder: 'MM/YY'
          },
          postalCode: {
              elementId: 'sq-postal-code',
              placeholder: 'Postal'
          },
    

    with the following card SqPaymentForm configuration field:

         card: {
               elementId: 'sq-card',
         },
    
    1. Remove the following JavaScript code block that sets the css class of input iFrame elements.

     inputClass: 'sq-input',
    
    1. Remove the following JavaScript code block that customizes the styles for the payment card form input iFrame elements.

     // Customize the CSS for SqPaymentForm iframe elements
     inputStyles: [{
         fontSize: '16px',
         lineHeight: '24px',
         padding: '16px',
         placeholderColor: '#a0a0a0',
         backgroundColor: 'transparent',
     }],
    

    The card configuration field provides pre-configured styles. We will use these pre-configured styles for this exercise.

  2. mysqpaymentform.css. Remove the following styles. The card configuration field provides pre-built CSS styles.

    .third {
      float: left;
      width: calc((100% - 32px) / 3);
      padding: 0;
      margin: 0 16px 16px 0;
    }
    
    .third:last-of-type {
      margin-right: 0;
    }
    
    /* Define how SqPaymentForm iframes should look */
    .sq-input {
      height: 56px;
      box-sizing: border-box;
      border: 1px solid #E0E2E3;
      background-color: white;
      border-radius: 6px;
      display: inline-block;
      -webkit-transition: border-color .2s ease-in-out;
         -moz-transition: border-color .2s ease-in-out;
          -ms-transition: border-color .2s ease-in-out;
              transition: border-color .2s ease-in-out;
    }
    
    /* Define how SqPaymentForm iframes should look when they have focus */
    .sq-input--focus {
      border: 1px solid #4A90E2;
    }
    
    /* Define how SqPaymentForm iframes should look when they contain invalid values */
    .sq-input--error {
      border: 1px solid #E02F2F;
    }
    
    #sq-card-number {
      margin-bottom: 16px;
    }
    
    

When you have completed your project code updates to run the single-element payment form, go back to Step 2.3: Test the payment flow from client to server and follow the instructions to re-test your payment form.

Single-element payment form and digital wallet support
Permalink Get a link to this section

The SqPaymentForm object in single-element payment form mode does not support digital wallets. If you want to use a single-element payment form in a payment page along with digital wallets, you can do so by adding a 2nd instance of SqPaymentForm configured with only the digital wallet elements. Then you add callbacks for digital wallet support to the 2nd instance of SqPaymentForm.

Deploy the application to production
Permalink Get a link to this section

In the preceding walkthrough you used the sandbox environment to test the payment form using a fake credit card number. This section explains how you deploy the application in production. In summary, you do the following:

  • Replace sandbox credentials with production credentials

  • Update your code to send requests to the production endpoints

  • Take payments with a valid credit card. Square will actually charge the card

To deploy the preceding walkthrough in production, do the following:

  1. Get production application credentials

    In the Get sandbox application credentials section, you obtained sandbox credentials. Follow the steps to open the Developer Dashboard, and this time choose the Production Settings dashboard mode, and then copy the production Application ID and Access Token.

    Note

    We assume you account is activated to accept payments. If not, you will need to activate the account. If your Credentials tab in the Developer Dashboard indicates account activation is required, follow the steps to activate the account. After activation, you can start taking payments.

  2. Update script references

    In the ADD SCRIPT REFERENCES section, you added script references in the index.html. Update the domain string in the JavaScript reference from js.squareupsandbox.com to js.squareup.com.

  3. Provide your production application ID

    SqPaymentForm requires a valid application ID to return a nonce. In the Provide your application ID section, you provided sandbox application ID. Update the code by by providing your production application ID.

  4. Configure the backend server to use production access token

    In Configure backend with your access token section, you provided sandbox access token. Replace it with production access token.


When you have completed these steps, your app will run in production. If you want to test, you will need to use a real credit card. We recommend you charge a small amount because Square will charge the credit card.