Example code and step-by-step instructions for building an EFT payment form using PayFields.

This page describes how to build an EFT payment form using PayFields:

  • Quickstart - Sample code and instructions for building a basic EFT payment form.

  • Implementation - Details about the PayFields EFT implementation.

Quickstart

Follow the steps below to create a basic EFT payment form that you can view in your web browser:

  1. Copy the code below into a text editor.

  2. Add your API key and merchant ID on lines 140 and 141.

  3. Save the file with a .html extension.

  4. Open the file in your web browser. The page will display the fields required to process an EFT transaction with PayFields.

Quickstart Code

Click to expand the PayFields ACH HTML sample.
<head>
    <script src="https://use.fontawesome.com/c24d3cbe35.js"></script>
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
        integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
    </link>
    <title>PayFields Script</title>
    <style>
        body {
            background-color: #ffffff
        }

        .form {
            background: #fff;
            padding-left: 3rem;
            width: 100%;
            height: 30rem;
            box-shadow: 5px 5px 8px rgba(0, 0, 0, 0.075);
        }

        .el {
            margin-bottom: -111px;
            margin-right: -109px;
        }
    </style>
</head>

<body>
    <div class="container-fluid">
        <div class="row">

            <br>

            <!-- Number will always be a required field - Create a div and hide it with DOM styling -->
            <div id="number"></div>

            <div class="form">
                <div class="row">
                    <div class="col-sm-6">
                        <div>
                            <label for="name">
                                <p>Name</p>
                            </label>
                            <a href="#" data-toggle="popover" title="Card Holder"
                                data-content="First and last name must be entered."><span><i
                                        class="fa fa-info-circle"></i></span></a>
                            <div class="input-group g-brd-primary--focus">
                                <div class="input-group-prepend">
                                    <span class="input-group-text rounded-0 g-bg-white g-color-gray-light-v1"><i
                                            class="fa fa-user"></i></span>
                                    <div class="el" id="name"></div>
                                </div>
                            </div>

                        </div>
                    </div>

                    <div class="col-sm-6">

                        <div>
                            <label for="number">
                                <p>Account Number</p>
                            </label>
                            <div class="input-group">
                                <div class="input-group-prepend">
                                    <span class="input-group-text"><i class="fa fa-credit-card"
                                            aria-hidden="true"></i></span>
                                    <div class="el">
                                        <div id="account_number"></div>
                                    </div>

                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                <div class="row">

                    <div class="col-sm-6">
                        <br>
                        <div>
                            <label for="expiration">
                                <p>Account Type</p>
                            </label>
                            <div class="input-group">
                                <div class="input-group-prepend">
                                    <span class="input-group-text"><i class="fa fa-calendar"
                                            style="height: 1.25rem !important;" aria-hidden="true"></i></span>
                                    <div class="el" id="account_type" style="height: 2.75rem;"></div>
                                </div>
                            </div>
                        </div>
                    </div>

                    <div class="col-sm-6">
                        <br>
                        <div>
                            <label for="expiration">
                                <p>Routing</p>
                            </label>
                            <div class="input-group">
                                <div class="input-group-prepend">
                                    <span class="input-group-text"><i class="fa fa-calendar"
                                            aria-hidden="true"></i></span>
                                    <div class="el" id="routing"></div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <br>
                <button type="button" id="btnEFT" class="btn btn-info btn-sm">Make Payment</button>
            </div>
        </div>
    </div>
    </div>
    </div>
    </div>
</body>

<script src="https://code.jquery.com/jquery-3.6.0.min.js"
    integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script type="text/javascript" src="https:test-api.payrixcanada.com/payFieldsScript"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"
    integrity="sha384-9/reFTGAW83EW2RDu2S0VKaIzap3H66lZH81PoYlFhbGU+6BZp6G7niu735Sk7lN" crossorigin="anonymous">
</script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.min.js"
    integrity="sha384-VHvPCCyXqtD5DqJeNxl2dtTyhF78xXNXdkwX1CZeRusQfRKp+tA7hAShOK/B/fQ2" crossorigin="anonymous">
</script>
<script>
    $("[data-toggle=popover]").popover();
</script>

<script>
    // Global Variables
    // ==========================================================================================
    let btnEFT = document.querySelector("#btnEFT")

    // PayFields congiration goes here - API Key and Merchant ID
    PayFields.config.apiKey = '082dc69e1abd111d34e14f291fc890c8'
    PayFields.config.merchant = 't1_mer_6203d7c60f36fe26057c693'
    // ==========================================================================================

    // ==========================================================================================
    // Set transaction amount
    PayFields.config.amount = 1000
    // Tokenize bank account
    PayFields.config.mode = 'txn';
    // This is an echeck sale
    PayFields.config.txnType = 'ecsale'
    // ==========================================================================================

    // PayFields styling via DOM styles
    // ==========================================================================================
    PayFields.customizations.style = {
        // Hide number div in the HTML
        ".number": {
            display: "none"
        },
        ".input": {
            border: "1px solid #ced4da",
            display: "block",
            width: "12rem",
            height: "34px",
            padding: "0.375rem-0.75rem",
            font: "12px Arial, Helvetica, sans-serif",
            fontSize: ".75rem",
            lineHeight: "1.5",
            borderRadius: "2px",
            backgroundColor: "#fff",
            boxShadow: "inset 0 1px 1px rgba(0, 0, 0, .075)",
            backgroundClip: "padding-box"
        },
        ".card-icon": {
            marginRight: "6rem",
            marginTop: ".25rem"
        }
    }
    // ==========================================================================================

    // On page load, the PayFields object must know payment_cvv and expiration are optional so divs will load correctly
    PayFields.customizations.optionalFields = ["#payment_cvv", "#expiration"];

    // Initiate all fields upon page load for PayFields
    // ==========================================================================================
    PayFields.fields = [{
            // Number must be present for PayField divs to load
            type: 'number',
            element: '#number'
        },
        {
            type: 'name',
            element: '#name'
        },
        {
            type: "routing",
            element: "#routing"
        },
        {
            type: "account_type",
            element: "#account_type",
        },
        {
            type: "account_number",
            element: "#account_number",
        }
    ];
    // ==========================================================================================

    // Make Payment button for EFT
    // ==========================================================================================
    btnEFT.addEventListener('click', function () {

        // Making cvv number and expiration optional for credit / debit card if EFT only
        // The number element must be placed in the event listener (btnEFT)
        PayFields.customizations.optionalFields = ["#number"];
        // Submit payment for EFT
        PayFields.submit()
    })
    // ==========================================================================================
</script>
HTML

Canada EFT Routing Number Formatting

When accepting Canadian EFT payments, the entered routing number is different from US ACH number formatting.

The routing number in Canada must appear as a 9-digit number in ACH Universal.  If the Institution is only a 3-digit number, you'll add a leading zero.

Example:

If the account number listed is 01144 039

  • 01144 being the branch number (5 digits)

  • 039 being the institution number (3 digits)

 

The number MUST be entered in the following combination:

  • 0 + (Institution number) + (Branch Number) = Payments EFT routing number entry format. See the example below.  

Implementation

The sections provide details about how the EFT Quickstart page is built:

  • Include the JavaScript libraries - Include the PayFields and jQuery libraries in the page.

  • Build the PayFields script block - Authenticate your application, configure the PayFields options, create a submit button, and execute the transaction.

  • Add the fields to the payment page - Add <div> elements that will contain the fields and assign the correct ID.

  • Handle the response - Add JavaScript functions to your page that run when PayFields returns the transaction results.

Include the JavaScript libraries

PayFields requires the PayFields and the most recent jQuery JavaScript libraries. Add the following code to any page that will use the PayFields scripts:

<script src="https://code.jquery.com/jquery-3.6.0.min.js"
    integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
<script type="text/javascript" src="https:test-api.payrixcanada.com/payFieldsScript"></script>
HTML

If jQuery conflicts with other global variables used in the application, you may use the noConflict feature by setting PayFields.jQuery = jQuery.noConflict(), which will ensure that jQuery will not set any global variables.

See lines 121 through 123 of the Quickstart code for context.

The Quickstart example also includes Bootstrap and popper.js to create the user interface.

Build the PayFields Script Block

The PayFields script block performs the following functions:

  • Authentication - Sets the apiKey and merchant ID values with the PayFields.config.apiKey and PayFields.config.merchant.

  • Configuration - Defines the type, mode, and a default amount for transactions. Identifies optional fields to ensure that PayFields works as expected.

  • Customization - Sets the styles that will be applied to the form elements.

  • Initialization - Defines the fields that will be used on the page and sets their IDs.

  • Execution - Creates a submit button and attaches an event listener, and runs the PayFields.submit(); function to send the payment.

Click here to expand an example of the entire PayFields script block for ACH transactions.
<script>
    // Global Variables
    // ==========================================================================================
    let btnEFT = document.querySelector("#btnEFT")

    // PayFields congiration goes here - API Key and Merchant ID
    PayFields.config.apiKey = 'Your API Key'
    PayFields.config.merchant = 'Your Merchant ID'
    // ==========================================================================================

    // ==========================================================================================
    // Set transaction amount
    PayFields.config.amount = 1000
    // Tokenize bank account
    PayFields.config.mode = 'txn';
    // This is an echeck sale
    PayFields.config.txnType = 'ecsale'
    // ==========================================================================================

    // PayFields styling via DOM styles
    // ==========================================================================================
    PayFields.customizations.style = {
        // Hide number div in the HTML
        ".number": {
            display: "none"
        },
        ".input": {
            border: "1px solid #ced4da",
            display: "block",
            width: "12rem",
            height: "34px",
            padding: "0.375rem-0.75rem",
            font: "12px Arial, Helvetica, sans-serif",
            fontSize: ".75rem",
            lineHeight: "1.5",
            borderRadius: "2px",
            backgroundColor: "#fff",
            boxShadow: "inset 0 1px 1px rgba(0, 0, 0, .075)",
            backgroundClip: "padding-box"
        },
        ".card-icon": {
            marginRight: "6rem",
            marginTop: ".25rem"
        }
    }
    // ==========================================================================================

    // On page load, the PayFields object must know payment_cvv and expiration are optional so divs will load correctly
    PayFields.customizations.optionalFields = ["#payment_cvv", "#expiration"];

    // Initiate all fields upon page load for PayFields
    // ==========================================================================================
    PayFields.fields = [{
            // Number must be present for PayField divs to load
            type: 'number',
            element: '#number'
        },
        {
            type: 'name',
            element: '#name'
        },
        {
            type: "routing",
            element: "#routing"
        },
        {
            type: "account_type",
            element: "#account_type",
        },
        {
            type: "account_number",
            element: "#account_number",
        }
    ];
    // ==========================================================================================

    // Make Payment button for EFT
    // ==========================================================================================
    btnEFT.addEventListener('click', function () {

        // Making cvv number and expiration optional for credit / debit card if EFT only
        // The number element must be placed in the event listener (btnEFT)
        PayFields.customizations.optionalFields = ["#number"];
        // Submit payment for EFT
        PayFields.submit()
    })
    // ==========================================================================================
</script>
HTML

The sections below define the functions of the script block in more detail.

Authentication

Use the PayFields.config functions shown below to set your API Key and Merchant ID:

// PayFields congiration goes here - API Key and Merchant ID
PayFields.config.apiKey = 'Your API Key'
PayFields.config.merchant = 'Your merchant ID'
// ==========================================================================================
HTML

Configure the PayFields Options

Configure the PayFields options in your script block as shown below:

// ==========================================================================================
// Set transaction amount
PayFields.config.amount = 1000
// Tokenize bank account
PayFields.config.mode = 'txn';
// This is an echeck sale
PayFields.config.txnType = 'ecsale'
// ========================================================================================== 
HTML

For EFT payments, the txnType must be set to `ecsale`.

You must also set the CVV and Expiration date fields to optional, since they are required by default but are not used for EFT transactions:

// On page load, the PayFields object must know payment_cvv and expiration are optional so divs will load correctly
PayFields.customizations.optionalFields = ["#payment_cvv", "#expiration"];
HTML

Customization

Set the styles that determine the appearance of the payment form:

// PayFields styling via DOM styles
// ==========================================================================================
PayFields.customizations.style = {
    // Hide number div in the HTML
    ".number": {
        display: "none"
    },
    ".input": {
        border: "1px solid #ced4da",
        display: "block",
        width: "12rem",
        height: "34px",
        padding: "0.375rem-0.75rem",
        font: "12px Arial, Helvetica, sans-serif",
        fontSize: ".75rem",
        lineHeight: "1.5",
        borderRadius: "2px",
        backgroundColor: "#fff",
        boxShadow: "inset 0 1px 1px rgba(0, 0, 0, .075)",
        backgroundClip: "padding-box"
    },
    ".card-icon": {
        marginRight: "6rem",
        marginTop: ".25rem"
    }
}
// ==========================================================================================
CODE

Initialization

Define the fields that will be used on the form and set their IDs. For EFT transactions, use the following fields:

  • number - The credit card number field. This field is required for PayFields DIVs to load, but you will not send a value for this field.

  • name - The accountholder’s name.

  • routing - The routing number of the accountholder’s bank.

  • account_type - Defines whether the account is a checking or savings account.

  • account_number - The bank account number.

The code below shows an example of the initialization:

// Initiate all fields upon page load for PayFields
// ==========================================================================================
PayFields.fields = [{
        // Number must be present for PayField divs to load
        type: 'number',
        element: '#number'
    },
    {
        type: 'name',
        element: '#name'
    },
    {
        type: "routing",
        element: "#routing"
    },
    {
        type: "account_type",
        element: "#account_type",
    },
    {
        type: "account_number",
        element: "#account_number",
    }
];
// ==========================================================================================
CODE

Execution

Use the let keyword to identify the button that a customer will use to submit a payment:

// Global Variables
// ==========================================================================================
let btnEFT = document.querySelector("#btnEFT")
CODE

Then add an event listener that calls the PayFields.submit() function when the button is clicked:

// Make Payment button for EFT
// ==========================================================================================
btnEFT.addEventListener('click', function () {

    // Making cvv number and expiration optional for credit / debit card if EFT only
    // The number element must be placed in the event listener (btnEFT)
    PayFields.customizations.optionalFields = ["#number"];
    // Submit payment for EFT
    PayFields.submit()
})
// ==========================================================================================
CODE

You must set the number field to optional in the event listener. This ensures that PayFields will not expect a card number, but that the form will be displayed as expected.

Add the fields to the payment page

Add the form fields to the <body> of your page by creating <div> elements and assigning the id values that you defined in the previous step. For example, the code below creates a <div> for the name element:

<div id="#name"></div>
CODE
Click here to expand an example of the page body, which includes DIVs for each PayFields ACH element.
<body>
    <div class="container-fluid">
        <div class="row">

            <br>

            <!-- Number will always be a required field - Create a div and hide it with DOM styling -->
            <div id="number"></div>

            <div class="form">
                <div class="row">
                    <div class="col-sm-6">
                        <div>
                            <label for="name">
                                <p>Name</p>
                            </label>
                            <a href="#" data-toggle="popover" title="Card Holder"
                                data-content="First and last name must be entered."><span><i
                                        class="fa fa-info-circle"></i></span></a>
                            <div class="input-group g-brd-primary--focus">
                                <div class="input-group-prepend">
                                    <span class="input-group-text rounded-0 g-bg-white g-color-gray-light-v1"><i
                                            class="fa fa-user"></i></span>
                                    <div class="el" id="name"></div>
                                </div>
                            </div>

                        </div>
                    </div>

                    <div class="col-sm-6">

                        <div>
                            <label for="number">
                                <p>Account Number</p>
                            </label>
                            <div class="input-group">
                                <div class="input-group-prepend">
                                    <span class="input-group-text"><i class="fa fa-credit-card"
                                            aria-hidden="true"></i></span>
                                    <div class="el">
                                        <div id="account_number"></div>
                                    </div>

                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                <div class="row">

                    <div class="col-sm-6">
                        <br>
                        <div>
                            <label for="expiration">
                                <p>Account Type</p>
                            </label>
                            <div class="input-group">
                                <div class="input-group-prepend">
                                    <span class="input-group-text"><i class="fa fa-calendar"
                                            style="height: 1.25rem !important;" aria-hidden="true"></i></span>
                                    <div class="el" id="account_type" style="height: 2.75rem;"></div>
                                </div>
                            </div>
                        </div>
                    </div>

                    <div class="col-sm-6">
                        <br>
                        <div>
                            <label for="expiration">
                                <p>Routing</p>
                            </label>
                            <div class="input-group">
                                <div class="input-group-prepend">
                                    <span class="input-group-text"><i class="fa fa-calendar"
                                            aria-hidden="true"></i></span>
                                    <div class="el" id="routing"></div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <br>
                <button type="button" id="btnEFT" class="btn btn-info btn-sm">Make Payment</button>
            </div>
        </div>
    </div>
    </div>
    </div>
    </div>
</body>
HTML

PayFields will display the fields on the payment page inside each <div> element and apply the appropriate styles based on the id. Be sure to also create a <button> element with the ID that you set in the configuration step.

When the customer is finished entering data and clicks the submit button, the event listener will call the PayFields.submit(); function to send the payment information to Payrix for processing.

Handle the response

Payrix returns the results of the transaction using one of the following callback function:

  • PayFields.onSuccess = (response) => {} - Runs when the API responds with a successful transaction or token.

  • PayFields.onValidationFailure = () => {} - Runs when PayField validation fails before creating the API call.

  • PayFields.onFailure = (response) => {} - Runs when the API responds with a failed transaction or token.

  • PayFields.onFinish = (response) => {} - Runs when the API responds.

  • PayFields.onRestore = () => {} - Runs when the restore action is run.

Fill in each function body to define the behavior of the application for each possible type of response.

PayFields Actions

The table below defines all of the actions supported by the PayFields JavaScript library:

Action

Description

PayFields.submit();

Submits the PayFields data to Payrix.

PayFields.swipePopup();

Opens the card swipe popup.

PayFields.clearFields();

Clears all the values from the fields.

PayFields.clearFields(["number", "cvv"]);

Clears the values from the specified fields.

PayFields.appendTo("number", "#newElement");

Moves the field to a new DIV.

PayFields.reload();

Reappends the PayField with all existing values to the DIV only if the DIV has been removed.

PayFields.restore();

Restores the values if PayFields is moved to a new DIV.

PayFields.button = { element: "#submit", value: "Click to Submit" };

Displays a button in the specified element for submitting field data to Payrix .

PayFields.swipeButton = { element: "#swipe", value: "Click to Swipe"};

Displays a button in the specified element for opening the card swipe popup.

PayFields.onSuccess = (response) => {};

Callback function that runs when the API responds with a successful transaction or token.

PayFields.onValidationFailure = () => {};

Callback function that runs when validation fails before creating the API call.

PayFields.onFailure = (response) => {};

Callback function that runs when the API responds with a failed transaction or token.

PayFields.onFinish = (response) => {};

Callback function that runs when the API responds.

PayFields.onRestore = () => {};

Callback function that runs when the restore action is run.

PayFields.config.order = {order number};

Sets an order number for Level II/III processing.

PayFields.config.tax = {tax number};

Sets a tax ID number for Level II/III processing.

PayFields.config.dicount = {discount number};

Sets a discount value for Level II/III processing.

PayFields.config.shipping = {shipping number};

Sets a shipping number for Level II/III processing.

PayFields.config.duty = {duty number};

Sets an duty value for Level II/III processing.

PayFields.config.items = {items Object};

Adds an array of items to the order for Level II/III processing.

PayFields.config.billingAddress = {Billing Object};

Sets known values of the cardholders billing address without displaying them on the payment page.

PayFields.config.additionalData = {Additional Object};

Adds additional data to the order for Level II/III processing.

PayFields.config.invoiceResult = {Invoice Object};

Adds an invoice object to the order for Level II/III processing.