From: Steve Sutton Date: Tue, 9 Apr 2019 20:18:51 +0000 (-0400) Subject: Billing payment form with square X-Git-Url: http://cvs2.gaslightmedia.com/gitweb/?a=commitdiff_plain;h=285ab6858d29fc44b6f830c421c934e71eb90890;p=WP-Plugins%2Fglm-member-db-billing.git Billing payment form with square Testing more of the square payment integration. Handle decline error and card already processed. --- diff --git a/css/sq-payment-form.css b/css/sq-payment-form.css index 3e83a9a..5ab577e 100644 --- a/css/sq-payment-form.css +++ b/css/sq-payment-form.css @@ -170,12 +170,16 @@ 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; } diff --git a/js/sq-payment-form.js b/js/sq-payment-form.js index 9ce7773..83d3a34 100644 --- a/js/sq-payment-form.js +++ b/js/sq-payment-form.js @@ -4,222 +4,241 @@ */ 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 += "
  • " + errors[i].message + "
  • "; - } - 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 += "
  • " + errors[i].message + "
  • "; + } + 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 += "
  • " + glmField.fieldLabel + " Required!
  • "; + } + } + + 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 */ + } } - } }); diff --git a/models/admin/ajax/billingAccount.php b/models/admin/ajax/billingAccount.php index a649f51..82c7d5c 100644 --- a/models/admin/ajax/billingAccount.php +++ b/models/admin/ajax/billingAccount.php @@ -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, ); diff --git a/models/front/billing/paymentForm.php b/models/front/billing/paymentForm.php index cfd8548..d96b84b 100644 --- a/models/front/billing/paymentForm.php +++ b/models/front/billing/paymentForm.php @@ -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 '
    $_REQUEST: ' . print_r( $_REQUEST, true ) . '
    '; - echo '
    $payment_option: ' . print_r( $payment_option, true ) . '
    '; - - switch ( $payment_option ) { - case 'pay_by_credit_card': - // Do the Payment Processing. - $processErrors = $BillingSupport->processOnlinePayment( $accountId, $invoiceId, $_REQUEST['total_renew_amount'] ); - // echo '
    $processErrors: ' . print_r( $processErrors, true ) . '
    '; - - if ( $processErrors ) { - if ( isset( $processErrors ) && is_array( $processErrors ) && count( $processErrors ) > 0 ) { - $error = true; - foreach ( $processErrors as $error ) { - $messages[] = ''.$error.''; + 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 '
    $_REQUEST: ' . print_r( $_REQUEST, true ) . '
    '; + // echo '
    $payment_option: ' . print_r( $payment_option, true ) . '
    '; + + 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[] = ''.$error.''; + } + } else if ( isset( $processErrors ) && $processErrors ) { + $error = true; + $messages[] = ''.$processErrors.''; + } 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[] = ''.$processErrors.''; - } 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; diff --git a/views/front/billing/paymentForm.html b/views/front/billing/paymentForm.html index 9fd0249..7419daf 100644 --- a/views/front/billing/paymentForm.html +++ b/views/front/billing/paymentForm.html @@ -11,7 +11,7 @@ {/foreach} {/if} -
    + @@ -19,6 +19,8 @@ +
    +
    Invoice # @@ -64,6 +66,23 @@