-
Notifications
You must be signed in to change notification settings - Fork 2
Improve dynamic terminal selection with AJAX loading #310
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: release-2.0.3
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -21,15 +21,224 @@ | |||||
| */ | ||||||
|
|
||||||
| $(document).ready(function (e) { | ||||||
| // #region agent log | ||||||
| console.log('[DEBUG] saferpay_settings.js loaded'); | ||||||
| // #endregion | ||||||
|
Comment on lines
+24
to
+26
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||
|
|
||||||
| $("input[name='SAFERPAY_CONFIGURATION_NAME']").keypress(function (e) { | ||||||
| //disable symbols | ||||||
| var txt = String.fromCharCode(e.which); | ||||||
| if (!txt.match(/[A-Za-z0-9&. ]/)) { | ||||||
| return false; | ||||||
| } | ||||||
| // disable space | ||||||
| if (e.keyCode === 32) { | ||||||
| return false; | ||||||
| } | ||||||
| }); | ||||||
| }); | ||||||
|
|
||||||
| var terminalFetchTimeout = null; | ||||||
|
|
||||||
| $('.saferpay-terminal-selector').each(function() { | ||||||
| // #region agent log | ||||||
| console.log('[DEBUG] Found terminal selector, count:', $('.saferpay-terminal-selector').length); | ||||||
| // #endregion | ||||||
|
|
||||||
| var $container = $(this); | ||||||
| var environment = $container.data('environment'); | ||||||
| var $select = $container.find('.saferpay-terminal-select'); | ||||||
| var $helpBlock = $container.find('.help-block'); | ||||||
| var $manualInput = $container.find('.saferpay-terminal-manual-input'); | ||||||
|
|
||||||
| var getFieldValue = function(fieldName) { | ||||||
| var $field = $('input[name="' + fieldName + '"], select[name="' + fieldName + '"]'); | ||||||
| // #region agent log | ||||||
| console.log('[DEBUG] getFieldValue:', fieldName, 'found:', $field.length > 0, 'value:', $field.length ? ($field.attr('type') === 'password' ? '***' : $field.val()) : 'not found'); | ||||||
| // #endregion | ||||||
| if ($field.length) { | ||||||
| if ($field.attr('type') === 'password') { | ||||||
| return $field.val() || ''; | ||||||
| } | ||||||
| return $field.val() || ''; | ||||||
| } | ||||||
| return ''; | ||||||
| }; | ||||||
|
|
||||||
| var getFieldName = function(baseName) { | ||||||
| return environment === 'test' ? baseName + '_TEST' : baseName; | ||||||
| }; | ||||||
|
|
||||||
| var lastCredentials = { | ||||||
| customerId: getFieldValue(getFieldName('SAFERPAY_CUSTOMER_ID')), | ||||||
| username: getFieldValue(getFieldName('SAFERPAY_USERNAME')), | ||||||
| password: getFieldValue(getFieldName('SAFERPAY_PASSWORD')) | ||||||
| }; | ||||||
|
|
||||||
| var fetchTerminals = function(force) { | ||||||
| var customerId = getFieldValue(getFieldName('SAFERPAY_CUSTOMER_ID')); | ||||||
| var username = getFieldValue(getFieldName('SAFERPAY_USERNAME')); | ||||||
| var password = getFieldValue(getFieldName('SAFERPAY_PASSWORD')); | ||||||
|
|
||||||
| var credentialsChanged = | ||||||
| customerId !== lastCredentials.customerId || | ||||||
| username !== lastCredentials.username || | ||||||
| password !== lastCredentials.password; | ||||||
|
|
||||||
| if (!force && !credentialsChanged && $select.find('option').length > 1) { | ||||||
| return; | ||||||
| } | ||||||
|
|
||||||
| // Update last credentials | ||||||
| lastCredentials = { | ||||||
| customerId: customerId, | ||||||
| username: username, | ||||||
| password: password | ||||||
| }; | ||||||
|
|
||||||
| if (!customerId || !username || !password) { | ||||||
| $select.prop('disabled', true).html('<option value="">-- Select Terminal --</option>'); | ||||||
| $helpBlock.text($helpBlock.data('empty-text') || 'Please configure Customer ID, Username, and Password to load terminals'); | ||||||
| if ($manualInput.length) { | ||||||
| $manualInput.show(); | ||||||
| } | ||||||
| return; | ||||||
| } | ||||||
|
|
||||||
| $select.prop('disabled', true); | ||||||
| $select.html('<option value="">Loading terminals...</option>'); | ||||||
| $helpBlock.html('<i class="icon-spinner icon-spin"></i> Loading terminals...'); | ||||||
|
|
||||||
| var ajaxUrl = window.location.href; | ||||||
|
|
||||||
| // #region agent log | ||||||
| console.log('[DEBUG] AJAX URL:', ajaxUrl, 'Window location:', window.location.href); | ||||||
| // #endregion | ||||||
|
|
||||||
| var params = { | ||||||
| ajax: 1, | ||||||
| action: 'getTerminals', | ||||||
| environment: environment, | ||||||
| customer_id: customerId, | ||||||
| username: username, | ||||||
| password: password | ||||||
| }; | ||||||
|
|
||||||
| // #region agent log | ||||||
| console.log('[DEBUG] Making AJAX request with params:', Object.assign({}, params, {password: '***'})); | ||||||
| // #endregion | ||||||
|
|
||||||
| alert('Customer ID before AJAX: ' + customerId); // Temporary debug alert | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||
|
|
||||||
| $.ajax({ | ||||||
| url: ajaxUrl, | ||||||
| type: 'POST', | ||||||
| data: params, | ||||||
| dataType: 'json', | ||||||
| success: function(response) { | ||||||
| // #region agent log | ||||||
| console.log('[DEBUG] AJAX success response:', {success: response.success, terminalsCount: response.terminals ? response.terminals.length : 0, error: response.error}); | ||||||
| // #endregion | ||||||
| if (response.success && response.terminals && response.terminals.length > 0) { | ||||||
| var options = '<option value="">-- Select Terminal --</option>'; | ||||||
| var currentValue = $select.data('current-value') || ''; | ||||||
|
|
||||||
| $.each(response.terminals, function(index, terminal) { | ||||||
| var selected = terminal.TerminalId === currentValue ? ' selected' : ''; | ||||||
| var label = terminal.TerminalId + (terminal.Description ? ' - ' + terminal.Description : ''); | ||||||
| options += '<option value="' + terminal.TerminalId + '"' + selected + '>' + label + '</option>'; | ||||||
| }); | ||||||
|
|
||||||
| $select.html(options).prop('disabled', false); | ||||||
|
|
||||||
| if (response.count === 1 && !$select.val()) { | ||||||
| $select.val(response.terminals[0].TerminalId).trigger('change'); | ||||||
| } | ||||||
|
|
||||||
| $helpBlock.text('Select a terminal from the list'); | ||||||
| if ($manualInput.length) { | ||||||
| $manualInput.hide(); | ||||||
| $manualInput.val(''); | ||||||
| } | ||||||
| } else { | ||||||
| $select.html('<option value="">-- Select Terminal --</option>').prop('disabled', false); | ||||||
| var errorMsg = response.error || 'No terminals found. Please check your credentials.'; | ||||||
| $helpBlock.html('<span class="text-danger">' + errorMsg + '</span>'); | ||||||
| if ($manualInput.length) { | ||||||
| $manualInput.show(); | ||||||
| } | ||||||
| } | ||||||
| }, | ||||||
| error: function(xhr, status, error) { | ||||||
| // #region agent log | ||||||
| console.error('[DEBUG] AJAX Error:', {status: xhr.status, statusText: xhr.statusText, responseText: xhr.responseText ? xhr.responseText.substring(0, 200) : 'empty', error: error}); | ||||||
| // #endregion | ||||||
| $select.html('<option value="">-- Select Terminal --</option>').prop('disabled', false); | ||||||
| $helpBlock.html('<span class="text-danger">Failed to load terminals. You can enter the Terminal ID manually.</span>'); | ||||||
| if ($manualInput.length) { | ||||||
| $manualInput.show(); | ||||||
| } | ||||||
| } | ||||||
| }); | ||||||
| }; | ||||||
|
|
||||||
| var debouncedFetch = function() { | ||||||
| clearTimeout(terminalFetchTimeout); | ||||||
| terminalFetchTimeout = setTimeout(fetchTerminals, 500); | ||||||
| }; | ||||||
|
|
||||||
| var fieldNames = [ | ||||||
| getFieldName('SAFERPAY_CUSTOMER_ID'), | ||||||
| getFieldName('SAFERPAY_USERNAME'), | ||||||
| getFieldName('SAFERPAY_PASSWORD') | ||||||
| ]; | ||||||
|
|
||||||
| fieldNames.forEach(function(fieldName) { | ||||||
| $('input[name="' + fieldName + '"], select[name="' + fieldName + '"]').on('input change blur', debouncedFetch); | ||||||
| }); | ||||||
|
|
||||||
| $select.on('change', function() { | ||||||
| if ($(this).val()) { | ||||||
| $manualInput.val(''); | ||||||
| } | ||||||
| }); | ||||||
|
|
||||||
| $manualInput.on('input', function() { | ||||||
| if ($(this).val()) { | ||||||
| $select.val(''); | ||||||
| } | ||||||
| }); | ||||||
|
|
||||||
| $manualInput.on('blur', function() { | ||||||
| if ($(this).val() && !$select.val()) { | ||||||
| var manualValue = $(this).val(); | ||||||
| if (!$select.find('option[value="' + manualValue + '"]').length) { | ||||||
| $select.append('<option value="' + manualValue + '" selected>' + manualValue + '</option>'); | ||||||
| } else { | ||||||
| $select.val(manualValue); | ||||||
| } | ||||||
| $(this).val(''); | ||||||
| } | ||||||
| }); | ||||||
|
|
||||||
| $container.find('.saferpay-refresh-terminals').on('click', function() { | ||||||
| fetchTerminals(true); | ||||||
| }); | ||||||
|
|
||||||
| $('form').on('submit', function() { | ||||||
| if ($manualInput.val() && !$select.val()) { | ||||||
| var manualValue = $(this).val(); | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a bug in the form submit handler.
Suggested change
|
||||||
| if (!$select.find('option[value="' + manualValue + '"]').length) { | ||||||
| $select.append('<option value="' + manualValue + '" selected>' + manualValue + '</option>'); | ||||||
| } else { | ||||||
| $select.val(manualValue); | ||||||
| } | ||||||
| } | ||||||
| }); | ||||||
|
|
||||||
| if (getFieldValue(getFieldName('SAFERPAY_CUSTOMER_ID')) && | ||||||
| getFieldValue(getFieldName('SAFERPAY_USERNAME')) && | ||||||
| getFieldValue(getFieldName('SAFERPAY_PASSWORD'))) { | ||||||
| if ($select.find('option').length <= 1) { | ||||||
| fetchTerminals(); | ||||||
| } | ||||||
| } | ||||||
| }); | ||||||
| }); | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -20,28 +20,43 @@ | |
| *@license SIX Payment Services | ||
| *} | ||
| <div class="saferpay-terminal-selector" data-environment="{$field['environment']|escape:'htmlall':'UTF-8'}"> | ||
| <select | ||
| name="{$key|escape:'htmlall':'UTF-8'}" | ||
| id="{$key|escape:'htmlall':'UTF-8'}" | ||
| class="saferpay-terminal-select form-control fixed-width-xl" | ||
| {if !isset($field['terminals']) || count($field['terminals']) == 0}disabled{/if}> | ||
| <option value="">{l s='-- Select Terminal --' mod='saferpayofficial'}</option> | ||
| {if isset($field['terminals']) && count($field['terminals']) > 0} | ||
| {foreach from=$field['terminals'] item=terminal} | ||
| <option value="{$terminal['TerminalId']|escape:'htmlall':'UTF-8'}" | ||
| {if $field['value'] == $terminal['TerminalId']}selected{/if}> | ||
| {$terminal['TerminalId']|escape:'htmlall':'UTF-8'} - {$terminal['Description']|escape:'htmlall':'UTF-8'} | ||
| </option> | ||
| {/foreach} | ||
| {/if} | ||
| </select> | ||
| {if !isset($field['terminals']) || count($field['terminals']) == 0} | ||
| <p class="help-block text-muted"> | ||
| <div class="input-group fixed-width-xl"> | ||
| <select | ||
| name="{$key|escape:'htmlall':'UTF-8'}" | ||
| id="{$key|escape:'htmlall':'UTF-8'}" | ||
| class="saferpay-terminal-select form-control" | ||
| data-current-value="{$field['value']|escape:'htmlall':'UTF-8'}" | ||
| {if !isset($field['terminals']) || count($field['terminals']) == 0}disabled{/if}> | ||
| <option value="">{l s='-- Select Terminal --' mod='saferpayofficial'}</option> | ||
| {if isset($field['terminals']) && count($field['terminals']) > 0} | ||
| {foreach from=$field['terminals'] item=terminal} | ||
| <option value="{$terminal['TerminalId']|escape:'htmlall':'UTF-8'}" | ||
| {if $field['value'] == $terminal['TerminalId']}selected{/if}> | ||
| {$terminal['TerminalId']|escape:'htmlall':'UTF-8'}{if $terminal['Description']} - {$terminal['Description']|escape:'htmlall':'UTF-8'}{/if} | ||
| </option> | ||
| {/foreach} | ||
| {/if} | ||
| </select> | ||
| <span class="input-group-btn"> | ||
| <button type="button" class="btn btn-default saferpay-refresh-terminals" title="{l s='Refresh Terminals' mod='saferpayofficial'}"> | ||
| <i class="icon-refresh"></i> | ||
| </button> | ||
| </span> | ||
| </div> | ||
| <input | ||
| type="text" | ||
| name="{$key|escape:'htmlall':'UTF-8'}_manual" | ||
| id="{$key|escape:'htmlall':'UTF-8'}_manual" | ||
| class="saferpay-terminal-manual-input form-control fixed-width-xl" | ||
| placeholder="{l s='Or enter Terminal ID manually' mod='saferpayofficial'}" | ||
| value="{if (!isset($field['terminals']) || count($field['terminals']) == 0) && $field['value']}{$field['value']|escape:'htmlall':'UTF-8'}{/if}" | ||
| style="margin-top: 5px; {if isset($field['terminals']) && count($field['terminals']) > 0}display: none;{/if}" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using inline styles for conditional display logic is not ideal as it mixes presentation with structure. It's better to toggle a CSS class. PrestaShop/Bootstrap provides utility classes like For example: class="... {if isset($field['terminals']) && count($field['terminals']) > 0}hidden{/if}"
style="margin-top: 5px;" |
||
| /> | ||
| <p class="help-block" data-empty-text="{l s='Please configure Customer ID, Username, and Password to load terminals' mod='saferpayofficial'}"> | ||
| {if !isset($field['terminals']) || count($field['terminals']) == 0} | ||
| {l s='Please configure Customer ID, Username, and Password to load terminals' mod='saferpayofficial'} | ||
| </p> | ||
| {else} | ||
| <p class="help-block"> | ||
| {else} | ||
| {l s='Select a terminal from the list' mod='saferpayofficial'} | ||
| </p> | ||
| {/if} | ||
| {/if} | ||
| </p> | ||
| </div> | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
getAvailableTerminalsmethod is called with four arguments ($customerId,$username,$password,$isTestMode), but its definition inSaferPayTerminalServiceonly accepts one optional argument ($customerId). This will cause a fatal error.The
SaferPayTerminalService::getAvailableTerminalsmethod needs to be updated to accept these new parameters and use them to make the API request with the correct credentials and environment, instead of relying on the stored configuration values.