Billing payment form with square
authorSteve Sutton <steve@gaslightmedia.com>
Tue, 9 Apr 2019 20:18:51 +0000 (16:18 -0400)
committerSteve Sutton <steve@gaslightmedia.com>
Tue, 9 Apr 2019 20:18:51 +0000 (16:18 -0400)
Testing more of the square payment integration.
Handle decline error and card already processed.

css/sq-payment-form.css
js/sq-payment-form.js
models/admin/ajax/billingAccount.php
models/front/billing/paymentForm.php
views/front/billing/paymentForm.html

index 3e83a9a..5ab577e 100644 (file)
   background-color: #4281CB;
 }
 
-#error {
+#error, #billing-error {
+  display: none;
   width: 100%;
   margin-top: 16px;
   font-size: 14px;
   color: red;
-  font-weight: 500;
-  text-align: center;
+  font-weight: bold;
+  text-align: left;
   opacity: 0.8;
+  background-color: red;
+  color: white;
+  padding: 20px;
 }
index 9ce7773..83d3a34 100644 (file)
  */
 function onGetCardNonce(event) {
 
-  // Don't submit the form until SqPaymentForm returns with a nonce
-  event.preventDefault();
+    // Don't submit the form until SqPaymentForm returns with a nonce
+    event.preventDefault();
 
-  // Request a nonce from the SqPaymentForm object
-  paymentForm.requestCardNonce();
+    // Request a nonce from the SqPaymentForm object
+    paymentForm.requestCardNonce();
 }
 
 // Initializes the SqPaymentForm object by
 // initializing various configuration fields and providing implementation for callback functions.
 var paymentForm = new SqPaymentForm({
-  // Initialize the payment form elements
-  applicationId: applicationId,
-  locationId: locationId,
-  inputClass: 'sq-input',
-
-  // Customize the CSS for SqPaymentForm iframe elements
-  inputStyles: [{
-    backgroundColor: 'transparent',
-    color: '#333333',
-    fontFamily: '"Helvetica Neue", "Helvetica", sans-serif',
-    fontSize: '16px',
-    fontWeight: '400',
-    placeholderColor: '#8594A7',
-    placeholderFontWeight: '400',
-    padding: '16px',
-    _webkitFontSmoothing: 'antialiased',
-    _mozOsxFontSmoothing: 'grayscale'
-  }],
-
-  // Initialize Google Pay button ID
-  googlePay: {
-    elementId: 'sq-google-pay'
-  },
-
-  // Initialize Apple Pay placeholder ID
-  applePay: {
-    elementId: 'sq-apple-pay'
-  },
-
-  // Initialize Masterpass placeholder ID
-  masterpass: {
-    elementId: 'sq-masterpass'
-  },
-
-  // Initialize the credit card placeholders
-  cardNumber: {
-    elementId: 'sq-card-number',
-    placeholder: '•••• •••• •••• ••••'
-  },
-  cvv: {
-    elementId: 'sq-cvv',
-    placeholder: 'CVV'
-  },
-  expirationDate: {
-    elementId: 'sq-expiration-date',
-    placeholder: 'MM/YY'
-  },
-  postalCode: {
-    elementId: 'sq-postal-code'
-  },
-
-  // SqPaymentForm callback functions
-  callbacks: {
-
-    /*
-     * callback function: methodsSupported
-     * Triggered when: the page is loaded.
-     */
-    methodsSupported: function (methods) {
-      if (!methods.masterpass && !methods.applePay && !methods.googlePay) {
-        var walletBox = document.getElementById('sq-walletbox');
-        walletBox.style.display = 'none';
-      } else {
-        var walletBox = document.getElementById('sq-walletbox');
-        walletBox.style.display = 'block';
-      }
-
-      // Only show the button if Google Pay is enabled
-      if (methods.googlePay === true) {
-        var googlePayBtn = document.getElementById('sq-google-pay');
-        googlePayBtn.style.display = 'inline-block';
-      }
-
-      // Only show the button if Apple Pay for Web is enabled
-      if (methods.applePay === true) {
-        var applePayBtn = document.getElementById('sq-apple-pay');
-        applePayBtn.style.display = 'inline-block';
-      }
-
-      // Only show the button if Masterpass is enabled
-      if (methods.masterpass === true) {
-        var masterpassBtn = document.getElementById('sq-masterpass');
-        masterpassBtn.style.display = 'inline-block';
-      }
+    // Initialize the payment form elements
+    applicationId: applicationId,
+    locationId: locationId,
+    inputClass: 'sq-input',
+
+    // Customize the CSS for SqPaymentForm iframe elements
+    inputStyles: [{
+        backgroundColor: 'transparent',
+        color: '#333333',
+        fontFamily: '"Helvetica Neue", "Helvetica", sans-serif',
+        fontSize: '12px',
+        fontWeight: '400',
+        placeholderColor: '#8594A7',
+        placeholderFontWeight: '400',
+        padding: '12px',
+        _webkitFontSmoothing: 'antialiased',
+        _mozOsxFontSmoothing: 'grayscale'
+    }],
+
+    // Initialize Google Pay button ID
+    // googlePay: {
+    //   elementId: 'sq-google-pay'
+    // },
+
+    // Initialize Apple Pay placeholder ID
+    // applePay: {
+    //   elementId: 'sq-apple-pay'
+    // },
+
+    // Initialize Masterpass placeholder ID
+    // masterpass: {
+    //   elementId: 'sq-masterpass'
+    // },
+
+    // Initialize the credit card placeholders
+    cardNumber: {
+        elementId: 'sq-card-number',
+        placeholder: '•••• •••• •••• ••••'
     },
-
-    /*
-     * callback function: createPaymentRequest
-     * Triggered when: a digital wallet payment button is clicked.
-     */
-    createPaymentRequest: function () {
-
-      var paymentRequestJson = {
-        requestShippingAddress: false,
-        requestBillingInfo: true,
-        shippingContact: {
-          familyName: "CUSTOMER LAST NAME",
-          givenName: "CUSTOMER FIRST NAME",
-          email: "mycustomer@example.com",
-          country: "USA",
-          region: "CA",
-          city: "San Francisco",
-          addressLines: [
-            "1455 Market St #600"
-          ],
-          postalCode: "94103",
-          phone:"14255551212"
-        },
-        currencyCode: "USD",
-        countryCode: "US",
-        total: {
-          label: "MERCHANT NAME",
-          amount: "1.00",
-          pending: false
-        },
-        lineItems: [
-          {
-            label: "Subtotal",
-            amount: "1.00",
-            pending: false
-          }
-        ]
-      };
-
-      return paymentRequestJson;
+    cvv: {
+        elementId: 'sq-cvv',
+        placeholder: 'CVV'
     },
-
-    /*
-     * callback function: validateShippingContact
-     * Triggered when: a shipping address is selected/changed in a digital
-     *                 wallet UI that supports address selection.
-     */
-    validateShippingContact: function (contact) {
-
-      var validationErrorObj ;
-      /* ADD CODE TO SET validationErrorObj IF ERRORS ARE FOUND */
-      return validationErrorObj ;
+    expirationDate: {
+        elementId: 'sq-expiration-date',
+        placeholder: 'MM/YY'
+    },
+    postalCode: {
+        elementId: 'sq-postal-code'
     },
 
-    /*
-     * callback function: cardNonceResponseReceived
-     * Triggered when: SqPaymentForm completes a card nonce request
-     */
-    cardNonceResponseReceived: function(errors, nonce, cardData, billingContact, shippingContact) {
-      if (errors){
-        var error_html = "";
-        for (var i =0; i < errors.length; i++){
-          error_html += "<li> " + errors[i].message + " </li>";
-        }
-        document.getElementById("error").innerHTML = error_html;
-        document.getElementById('sq-creditcard').disabled = false;
+    // SqPaymentForm callback functions
+    callbacks: {
+
+        /*
+         * callback function: methodsSupported
+         * Triggered when: the page is loaded.
+         */
+        methodsSupported: function (methods) {
+            if (!methods.masterpass && !methods.applePay && !methods.googlePay) {
+                var walletBox = document.getElementById('sq-walletbox');
+                walletBox.style.display = 'none';
+            } else {
+                var walletBox = document.getElementById('sq-walletbox');
+                walletBox.style.display = 'block';
+            }
+
+            // Only show the button if Google Pay is enabled
+            if (methods.googlePay === true) {
+                var googlePayBtn = document.getElementById('sq-google-pay');
+                googlePayBtn.style.display = 'inline-block';
+            }
+
+            // Only show the button if Apple Pay for Web is enabled
+            if (methods.applePay === true) {
+                var applePayBtn = document.getElementById('sq-apple-pay');
+                applePayBtn.style.display = 'inline-block';
+            }
+
+            // Only show the button if Masterpass is enabled
+            if (methods.masterpass === true) {
+                var masterpassBtn = document.getElementById('sq-masterpass');
+                masterpassBtn.style.display = 'inline-block';
+            }
+        },
+
+        /*
+         * callback function: createPaymentRequest
+         * Triggered when: a digital wallet payment button is clicked.
+         */
+        createPaymentRequest: function () {
+
+            var paymentRequestJson = {
+                requestShippingAddress: false,
+                requestBillingInfo: true,
+                shippingContact: {
+                    familyName: "CUSTOMER LAST NAME",
+                    givenName: "CUSTOMER FIRST NAME",
+                    email: "mycustomer@example.com",
+                    country: "USA",
+                    region: "CA",
+                    city: "San Francisco",
+                    addressLines: [
+                        "1455 Market St #600"
+                    ],
+                    postalCode: "94103",
+                    phone:"14255551212"
+                },
+                currencyCode: "USD",
+                countryCode: "US",
+                total: {
+                    label: "MERCHANT NAME",
+                    amount: "1.00",
+                    pending: false
+                },
+                lineItems: [
+                    {
+                        label: "Subtotal",
+                        amount: "1.00",
+                        pending: false
+                    }
+                ]
+            };
+
+            return paymentRequestJson;
+        },
 
-        return;
-      }else{
-        document.getElementById("error").innerHTML = "";
-      }
+        /*
+         * callback function: validateShippingContact
+         * Triggered when: a shipping address is selected/changed in a digital
+         *                 wallet UI that supports address selection.
+         */
+        validateShippingContact: function (contact) {
 
-      // Assign the nonce value to the hidden form field
-      document.getElementById('card-nonce').value = nonce;
+            var validationErrorObj ;
+            /* ADD CODE TO SET validationErrorObj IF ERRORS ARE FOUND */
+            return validationErrorObj ;
+        },
 
-      // POST the nonce form to the payment processing page
-      document.getElementById('nonce-form').submit();
+        /*
+         * callback function: cardNonceResponseReceived
+         * Triggered when: SqPaymentForm completes a card nonce request
+         */
+        cardNonceResponseReceived: function(errors, nonce, cardData, billingContact, shippingContact) {
+            if (errors){
+                var error_html = "";
+                for (var i =0; i < errors.length; i++){
+                    error_html += "<li> " + errors[i].message + " </li>";
+                }
+                document.getElementById("error").innerHTML = error_html;
+                jQuery('#error').show();
+                document.getElementById('sq-creditcard').disabled = false;
+
+                return;
+            }else{
+                document.getElementById("error").innerHTML = "";
+                jQuery('#error').hide();
+            }
+
+            console.log( 'formRequiredFields:', billingFieldsReq  );
+            var glmErrorsHtml = '';
+            for ( var i = 0; i < billingFieldsReq.length; i++ ) {
+                var glmField = billingFieldsReq[i];
+                if ( jQuery('input[name=' + glmField.fieldName + ']' ).val() == '' ) {
+                    glmErrorsHtml += "<li> " + glmField.fieldLabel + " Required! </li>";
+                }
+            }
+
+            if ( glmErrorsHtml != '' ) {
+                jQuery('#billing-error').html( glmErrorsHtml );
+                jQuery('#billing-error').show();
+                window.location.href='#billing-payment-form';
+
+                return;
+            }
+
+            // Assign the nonce value to the hidden form field
+            document.getElementById('card-nonce').value = nonce;
+
+            // POST the nonce form to the payment processing page
+            document.getElementById('nonce-form').submit();
 
-    },
+        },
 
-    /*
-     * callback function: unsupportedBrowserDetected
-     * Triggered when: the page loads and an unsupported browser is detected
-     */
-    unsupportedBrowserDetected: function() {
-      /* PROVIDE FEEDBACK TO SITE VISITORS */
-    },
+        /*
+         * callback function: unsupportedBrowserDetected
+         * Triggered when: the page loads and an unsupported browser is detected
+         */
+        unsupportedBrowserDetected: function() {
+            /* PROVIDE FEEDBACK TO SITE VISITORS */
+        },
 
-    /*
-     * callback function: inputEventReceived
-     * Triggered when: visitors interact with SqPaymentForm iframe elements.
-     */
-    inputEventReceived: function(inputEvent) {
-      switch (inputEvent.eventType) {
-        case 'focusClassAdded':
-          /* HANDLE AS DESIRED */
-          break;
-        case 'focusClassRemoved':
-          /* HANDLE AS DESIRED */
-          break;
-        case 'errorClassAdded':
-          /* HANDLE AS DESIRED */
-          break;
-        case 'errorClassRemoved':
-          /* HANDLE AS DESIRED */
-          break;
-        case 'cardBrandChanged':
-          /* HANDLE AS DESIRED */
-          break;
-        case 'postalCodeChanged':
-          /* HANDLE AS DESIRED */
-          break;
-      }
-    },
+        /*
+         * callback function: inputEventReceived
+         * Triggered when: visitors interact with SqPaymentForm iframe elements.
+         */
+        inputEventReceived: function(inputEvent) {
+            switch (inputEvent.eventType) {
+                case 'focusClassAdded':
+                    /* HANDLE AS DESIRED */
+                    break;
+                case 'focusClassRemoved':
+                    /* HANDLE AS DESIRED */
+                    break;
+                case 'errorClassAdded':
+                    /* HANDLE AS DESIRED */
+                    break;
+                case 'errorClassRemoved':
+                    /* HANDLE AS DESIRED */
+                    break;
+                case 'cardBrandChanged':
+                    /* HANDLE AS DESIRED */
+                    break;
+                case 'postalCodeChanged':
+                    /* HANDLE AS DESIRED */
+                    break;
+            }
+        },
 
-    /*
-     * callback function: paymentFormLoaded
-     * Triggered when: SqPaymentForm is fully loaded
-     */
-    paymentFormLoaded: function() {
-      /* HANDLE AS DESIRED */
+        /*
+         * callback function: paymentFormLoaded
+         * Triggered when: SqPaymentForm is fully loaded
+         */
+        paymentFormLoaded: function() {
+            /* HANDLE AS DESIRED */
+        }
     }
-  }
 });
index a649f51..82c7d5c 100644 (file)
@@ -128,7 +128,7 @@ class GlmMembersAdmin_ajax_billingAccount extends GlmDataAccounts
             }
             break;
         case 'verifyInvoiceNumber':
-            if ( isset( $_REQUEST['invoice_number'] ) && $invoiceNumber = filter_var( $_REQUEST['invoice_number'], FILTER_SANITIZE_STRING ) ) {
+            if ( isset( $_REQUEST['invoice_number'] ) && $invoiceNumber = filter_var( $_REQUEST['invoice_number'], FILTER_VALIDATE_INT ) ) {
                 // Get the invoice
                 $Invoices = new GlmDataInvoices( $this->wpdb, $this->config );
                 $Invoices->line_items_post = true;
@@ -170,8 +170,8 @@ class GlmMembersAdmin_ajax_billingAccount extends GlmDataAccounts
                     if ( $account ) {
                         $return = array(
                             'status'       => true,
-                            'member_id'    => (int)$account['id'],
-                            'account_id'   => (int)$account['ref_dest'],
+                            'member_id'    => (int)$account['ref_dest'],
+                            'account_id'   => (int)$account['id'],
                             'invoice_type' => (int)$invoiceTypeId,
                             'invoice'      => $invoice,
                         );
index cfd8548..d96b84b 100644 (file)
@@ -194,7 +194,7 @@ class GlmMembersFront_billing_paymentForm // extends GlmDataBilling
             if ( isset( $_REQUEST['invoice_number'] ) ) {
                 $invoiceId = filter_var( $_REQUEST['invoice_number'], FILTER_VALIDATE_INT );
             } else {
-                die( 'Error: no invoiceId' );
+                $error = true;
             }
             // Pull member invoice
             $memberInvoice = $BillingSupport->getInvoiceById( $invoiceId );
@@ -216,116 +216,81 @@ class GlmMembersFront_billing_paymentForm // extends GlmDataBilling
             // Check for account_number
             // If given then this is from unregistered user.
             // Have to verify that this number does match with billing_account.
-            if ( isset( $_REQUEST['account_number'] ) && $account_number = filter_var( $_REQUEST['account_number'], FILTER_SANITIZE_STRING ) ) {
-                // Verify account number.
-                $accountId = $this->wpdb->get_var(
-                    $this->wpdb->prepare(
-                        "SELECT id
-                           FROM " . GLM_MEMBERS_BILLING_PLUGIN_DB_PREFIX . "accounts
-                          WHERE account_number = %s",
-                        $account_number
-                    )
-                );
+            if ( isset( $_REQUEST['account_id'] ) ) {
+                $accountId = filter_var( $_REQUEST['account_id'], FILTER_VALIDATE_INT );
+            }
+            if ( !$accountId ) {
+                $error = true;
             }
 
-            // Start database transaction
-            $this->wpdb->show_errors();
-            $this->wpdb->query('START TRANSACTION');
-
-            // Look at the payment option given
-            $payment_option = filter_var( $_REQUEST['payment_option'], FILTER_SANITIZE_STRING );
-            echo '<pre>$_REQUEST: ' . print_r( $_REQUEST, true ) . '</pre>';
-            echo '<pre>$payment_option: ' . print_r( $payment_option, true ) . '</pre>';
-
-            switch ( $payment_option ) {
-            case 'pay_by_credit_card':
-                // Do the Payment Processing.
-                $processErrors = $BillingSupport->processOnlinePayment( $accountId, $invoiceId, $_REQUEST['total_renew_amount'] );
-                // echo '<pre>$processErrors: ' . print_r( $processErrors, true ) . '</pre>';
-
-                if ( $processErrors ) {
-                    if ( isset( $processErrors ) && is_array( $processErrors ) && count( $processErrors ) > 0 ) {
-                        $error = true;
-                        foreach ( $processErrors as $error ) {
-                            $messages[] = '<span style="color: red;">'.$error.'</span>';
+            if ( !$error ) {
+
+                // Start database transaction
+                $this->wpdb->show_errors();
+                $this->wpdb->query('START TRANSACTION');
+
+                // Look at the payment option given
+                $payment_option = filter_var( $_REQUEST['payment_option'], FILTER_SANITIZE_STRING );
+                // echo '<pre>$_REQUEST: ' . print_r( $_REQUEST, true ) . '</pre>';
+                // echo '<pre>$payment_option: ' . print_r( $payment_option, true ) . '</pre>';
+
+                switch ( $payment_option ) {
+                    case 'pay_by_credit_card':
+                        // Do the Payment Processing.
+                        $processErrors = $BillingSupport->processOnlinePayment( $accountId, $invoiceId, $_REQUEST['total_renew_amount'] );
+
+                        if ( $processErrors ) {
+                            if ( isset( $processErrors ) && is_array( $processErrors ) && count( $processErrors ) > 0 ) {
+                                $error = true;
+                                foreach ( $processErrors as $error ) {
+                                    $messages[] = '<span style="color: red;">'.$error.'</span>';
+                                }
+                            } else if ( isset( $processErrors ) && $processErrors ) {
+                                $error = true;
+                                $messages[] = '<span style="color: red;">'.$processErrors.'</span>';
+                            } else {
+                                $paymentSuccess = true;
+                            }
+                            $view = 'paymentForm';
+
+                            // Get list of payable invoice_types
+                            $payable_types = $BillingSupport->getAllPayableInvoiceTypes();
+
+                            // $member_invoice_id = $BillingSupport->getMembersInvoiceTypeByRefDest( $this->memberId );
+                            // if ( $member_invoice_id ) {
+                            //     $member_invoice = $BillingSupport->getInvoiceTypeById( $member_invoice_id );
+                            // }
+
+                            if ( $this->config['settings']['allow_employees'] ) {
+                                // Get a list of this accounts employees. If they have any.
+                                $employees = $BillingSupport->getListOfAccountEmployees( $this->memberId );
+                            }
+
+                            // Load DataClass for Management.
+                            require_once GLM_MEMBERS_BILLING_PLUGIN_CLASS_PATH .  '/data/dataManagement.php';
+                            $Management = new GlmDataBillingManagement( $this->wpdb, $this->config );
+                            $management = $Management->getEntry( 1 );
+
+                            // Need to see if there's an account for this member.
+                            $account = $Accounts->editEntry( $accountId );
                         }
-                    } else if ( isset( $processErrors ) && $processErrors ) {
-                        $error = true;
-                        $messages[] = '<span style="color: red;">'.$processErrors.'</span>';
-                    } else {
-                        $paymentSuccess = true;
-                    }
-                    $view = 'paymentForm';
-
-                    // Get list of payable invoice_types
-                    $payable_types = $BillingSupport->getAllPayableInvoiceTypes();
-
-                    // $member_invoice_id = $BillingSupport->getMembersInvoiceTypeByRefDest( $this->memberId );
-                    // if ( $member_invoice_id ) {
-                    //     $member_invoice = $BillingSupport->getInvoiceTypeById( $member_invoice_id );
-                    // }
-
-                    if ( $this->config['settings']['allow_employees'] ) {
-                        // Get a list of this accounts employees. If they have any.
-                        $employees = $BillingSupport->getListOfAccountEmployees( $this->memberId );
-                    }
-
-                    // Load DataClass for Management.
-                    require_once GLM_MEMBERS_BILLING_PLUGIN_CLASS_PATH .  '/data/dataManagement.php';
-                    $Management = new GlmDataBillingManagement( $this->wpdb, $this->config );
-                    $management = $Management->getEntry( 1 );
-
-                    // Need to see if there's an account for this member.
-                    $account = $Accounts->editEntry( $accountId );
+                        break;
+                    case 'pay_by_check':
+                        break;
                 }
-                break;
-            case 'pay_by_check':
-                break;
             }
 
             // If there's no error reported then show the invoice
-            // if ( !$error ) {
-            //     $this->wpdb->query( 'COMMIT' );
-            //     // Now need to show the invoice.
-            //     $view = 'viewInvoice';
-            //
-            //     // Get the invoice.
-            //     $invoiceHtml = $BillingSupport->viewInvoice( $invoiceId );
-            //
-            //     // If the member_type is changing then update member
-            //     // Get current member type
-            //     $member_id = filter_var( $_REQUEST['member'], FILTER_VALIDATE_INT );
-            //     if ( $member_id ) {
-            //         $current_member_type = $this->wpdb->get_var(
-            //             $this->wpdb->prepare(
-            //                 "SELECT member_type
-            //                    FROM " . GLM_MEMBERS_PLUGIN_DB_PREFIX . "members
-            //                   WHERE id = %d",
-            //                 $member_id
-            //             )
-            //         );
-            //         $new_type = filter_var( $_REQUEST['member_renewing'], FILTER_VALIDATE_INT );
-            //         $new_member_type = $this->wpdb->get_var(
-            //             $this->wpdb->prepare(
-            //                 "SELECT member_type
-            //                    FROM " . GLM_MEMBERS_BILLING_PLUGIN_DB_PREFIX . "invoice_types
-            //                   WHERE id = %d",
-            //                 $new_type
-            //             )
-            //         );
-            //         if ( $current_member_type != $new_member_type ) {
-            //             $this->wpdb->update(
-            //                 GLM_MEMBERS_PLUGIN_DB_PREFIX . 'members',
-            //                 array( 'member_type' => $new_member_type ),
-            //                 array( 'id' => $member_id ),
-            //                 array( '%d' ),
-            //                 array( '%d' )
-            //             );
-            //         }
-            //     }
-            // } else {
-            //     $this->wpdb->query( 'ROLLBACK' );
-            // }
+            if ( !$error ) {
+                $this->wpdb->query( 'COMMIT' );
+                // Now need to show the invoice.
+                $view = 'viewInvoice';
+
+                // Get the invoice.
+                $invoiceHtml = $BillingSupport->viewInvoice( $invoiceId );
+            } else {
+                $this->wpdb->query( 'ROLLBACK' );
+            }
 
             break;
 
index 9fd0249..7419daf 100644 (file)
@@ -11,7 +11,7 @@
         {/foreach}
     {/if}
 
-    <form action="{$thisUrl}" method="post"{if $billing_settings.proc_methods == 4} id="nonce-form" novalidate{/if}>
+    <form action="{$thisUrl}" method="post"{if $billing_settings.proc_methods == 4} id="nonce-form"{/if}>
         <input type="hidden" name="option" value="paymentProcess" />
         <input type="hidden" id="member_id" name="member" value="{$memberId}" />
         <input type="hidden" id="account_id" name="account_id" value="{$accountId}" />
@@ -19,6 +19,8 @@
 
         <span id="membername"></span>
 
+        <div id="billing-error"></div>
+
         <div class="glm-billing-field">
             <div class="glm-billing-label glm-required">
                 Invoice #
 </div>
 
 <script>
+{if $billing_settings.proc_methods == 4}
+    var billingFieldsReq = [
+        { fieldName: 'invoice_number', fieldLabel: 'Invoice Number' },
+        {if $settings.billing_contact_name_enabled}
+            { fieldName: 'billing_contact_name', fieldLabel: 'Billing Contact Name' },
+        {else}
+            { fieldName: 'billing_fname', fieldLabel: 'Billing First Name' },
+            { fieldName: 'billing_lname', fieldLabel: 'Billing Last Name' },
+        {/if}
+        { fieldName: 'billing_addr1', fieldLabel: 'Billing Address' },
+        { fieldName: 'billing_city', fieldLabel: 'Billing City' },
+        { fieldName: 'billing_state', fieldLabel: 'Billing State' },
+        { fieldName: 'billing_zip', fieldLabel: 'Billing Zip' },
+        { fieldName: 'email', fieldLabel: 'Email Address' },
+    ];
+{/if}
+
 jQuery(document).ready(function($){
 
     $('#billing-invoice-select').change(function(){