New
Web Payments SDK

Take ACH Bank Transfer Payments

Learn how to add a payment method to the application that you built using the quickstart project sample in Take a Card Payment with Web Payments SDK to integrate the Web Payments SDK into your application.

The steps in this topic 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.

Note

ACH bank transfers are only supported by the Web Payments SDK in the United States.

Square supports instant authentication through Plaid for verifying a buyer's bank account before making an ACH payment. Plaid lets your application quickly authenticate the bank account and then use the Web Payments SDK to connect to the ACH network to accept payments.

The following is the Plaid modal that is rendered by the Web Payments SDK: web-payments : ach : hero

You can find a complete example of the code in a GitHub repo.

Step 1: Attach ACH to the page Permalink Get a link to this section

The following code attaches the ACH method to the page:

  1. Add the following HTML elements to the prerequisite walkthrough form:

     <fieldset class="buyer-inputs">
       <input
         type="text"
         autocomplete="given-name"
         aria-required="true"
         aria-label="First Name"
         required="required"
         placeholder="Given Name"
         name="givenName"
         spellcheck="false"
       />
    
       <input
         type="text"
         autocomplete="family-name"
         aria-required="true"
         aria-label="Last Name"
         required="required"
         placeholder="Family Name"
         name="familyName"
         spellcheck="false"
       />
     </fieldset>
     <button id="ach-button">Pay with Bank Account</button>
    

    The HTML for the body of index.html should look like the following:

    <form id="payment-form">
      <fieldset class="buyer-inputs">
        <input
          type="text"
          autocomplete="given-name"
          aria-required="true"
          aria-label="First Name"
          required="required"
          placeholder="Given Name"
          name="givenName"
          spellcheck="false"
        />
    
        <input
          type="text"
          autocomplete="family-name"
          aria-required="true"
          aria-label="Last Name"
          required="required"
          placeholder="Family Name"
          name="familyName"
          spellcheck="false"
        />
      </fieldset>
      <button id="ach-button">Pay with Bank Account</button>
    
      <div id="card-container"></div>
      <button id="card-button" type="button">Pay $1.00</button>
    </form>
    <div id="payment-status-container"></div>
    
  2. Add aninitializeACH function below the initializeCard function in the <script> tag:

     async function initializeACH(payments) {
       const ach = await payments.ach();
       // Note: ACH does not have an .attach(...) method
       // the ACH auth flow is triggered by .tokenize(...)
       return ach;
     }
    
  3. In the DOMContentLoaded eventListener add the following code after you initialize the Card payment method:

     let ach;
     try {
       ach = await initializeACH(payments);
     } catch (e) {
       console.error('Initializing ACH failed', e);
       return;
     }
    

Test the application

  1. Navigate to http://localhost:3000/ in your browser. web payments : ACH : image 1

Checkpoint 1: You should now see a form that collects the buyer first and last name along with a button to start an ACH bank transfer.

Step 2: Get the payment token from the ACH payment method Permalink Get a link to this section

  1. Update the tokenize function to take in a second optional parameter options and update the paymentMethod.tokenize call to include the options parameter:

     async function tokenize(paymentMethod, options = {}) {
       const tokenResult = await paymentMethod.tokenize(options);
       // rest of the tokenize function stays the same.
     }
    
  2. Add the following two helper functions below the tokenize function in the <script> tag:

     function getBillingContact(form) {
       const formData = new FormData(form);
       // It is expected that the developer performs form field validation
       // which does not occur in this example.
       return {
         givenName: formData.get('givenName'),
         familyName: formData.get('familyName'),
       };
     }
    
     function getACHOptions(form) {
       const billingContact = getBillingContact(form);
       const accountHolderName = `${billingContact.givenName} ${billingContact.familyName}`;
    
       return { accountHolderName };
     }
    
  3. Update the handlePaymentMethodSubmission function to take in a third parameter options and update the tokenize call to add options as the second parameter:

     async function handlePaymentMethodSubmission(
       event,
       paymentMethod,
       options // Add the options parameter here
     ) {
         // code preceding tokenize call.
         // update the tokenize function to add an `options` parameter.
         const token = await tokenize(paymentMethod, options); 
         // tokenize code following the tokenize call.
     }
    
  4. Add the following code after // Checkpoint 2 in the DOMContentLoaded eventListener function:

     const achButton = document.getElementById('ach-button');
     achButton.addEventListener('click', async function (event) {
       const paymentForm = document.getElementById('payment-form');
       const achOptions = getACHOptions(paymentForm);
       await handlePaymentMethodSubmission(event, ach, achOptions);  // tokenize
       // ACH with the `accountHolderName` as an option.
     });
    
  5. Update the handlePaymentMethodSubmission function to disable the achButton when tokenizing and re-enable on a failed payment:

     async function handlePaymentMethodSubmission(event, paymentMethod) {
       event.preventDefault();
    
       try {
         // disable the submit button as we await tokenization and make a
         // payment request.
         cardButton.disabled = true;
         achButton.disabled = true; // Add this line.
       // tokenization and payment code.
       } catch (e) {
         cardButton.disabled = false;
         achButton.disabled = false; // Add this line.
         // failed tokenization and payment handling
       }
     }
    

Test the application

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

  2. Choose the Pay button. web-payments : ach :image 1

Checkpoint 2: You should see the Plaid interface and be able to complete the flow using the test credentials provided at the bottom of the screen. When complete, your application gets a payment token that is used to take an ACH bank transfer payment on your backend.

Next: Process an ACH payment token on your backend Permalink Get a link to this section

The payment token your application generated for an ACH bank transfer payment is processed on your backend in the same way a payment token from one of the other payment methods is processed, with some exceptions. To read more about the specific processing requirements for ACH bank transfers, read ACH Bank Transfer Payment.

Related topics Permalink Get a link to this section