diff --git a/metadata/site_import/meta/system-objecttype-extensions.xml b/metadata/site_import/meta/system-objecttype-extensions.xml
index b096fa6e2..883155cb0 100644
--- a/metadata/site_import/meta/system-objecttype-extensions.xml
+++ b/metadata/site_import/meta/system-objecttype-extensions.xml
@@ -529,6 +529,15 @@
0
0
+
+ Selected StoreId for Terminal API
+ Selected StoreId for Terminal API
+ string
+ false
+ false
+ 0
+ 0
+
X-API-KEY of Web service
X-API-KEY of Web service
@@ -713,6 +722,7 @@
+
diff --git a/metadata/site_import/services.xml b/metadata/site_import/services.xml
index 2d884663e..764b4e732 100644
--- a/metadata/site_import/services.xml
+++ b/metadata/site_import/services.xml
@@ -110,6 +110,16 @@
+
+ https://management-test.adyen.com/v3/stores
+
+
+
+
+ https://management-live.adyen.com/v3/stores
+
+
+
30000
@@ -228,4 +238,13 @@
Adyen
AdyenPaypalUpdateOrder
+
+ HTTP
+ true
+ adyen
+ true
+ false
+ Adyen
+ AdyenManagementApiGetStores
+
diff --git a/src/cartridges/bm_adyen/cartridge/controllers/AdyenSettings.js b/src/cartridges/bm_adyen/cartridge/controllers/AdyenSettings.js
index 4ad5cf358..ac3deffa1 100644
--- a/src/cartridges/bm_adyen/cartridge/controllers/AdyenSettings.js
+++ b/src/cartridges/bm_adyen/cartridge/controllers/AdyenSettings.js
@@ -6,6 +6,7 @@ const AdyenConfigs = require('*/cartridge/adyen/utils/adyenConfigs');
const AdyenHelper = require('*/cartridge/adyen/utils/adyenHelper');
const constants = require('*/cartridge/adyen/config/constants');
const AdyenLogs = require('*/cartridge/adyen/logs/adyenCustomLogs');
+const bmHelper = require('*/cartridge/utils/helper');
server.get('Start', (_req, res, next) => {
if (!csrfProtection.validateRequest()) {
@@ -84,4 +85,32 @@ server.post('TestConnection', server.middleware.https, (req, res, next) => {
return next();
});
+server.get('GetStores', server.middleware.https, (req, res, next) => {
+ try {
+ const service = bmHelper.initializeAdyenService(
+ constants.SERVICE.GETSTORES,
+ 'GET',
+ );
+ const merchantAccount = AdyenConfigs.getAdyenMerchantAccount();
+ const callResult = service.call(JSON.stringify({ merchantAccount }));
+
+ if (!callResult.isOk()) {
+ throw new Error('/getStores call failed');
+ }
+ const resultObject = callResult.object;
+ const response = JSON.parse(resultObject.getText());
+ const mappedData = response.data.map((store) => ({
+ id: store.id,
+ description: store.description,
+ }));
+
+ bmHelper.saveMetadataField('Adyen_StoreId', mappedData);
+ res.json({ success: true, stores: mappedData });
+ } catch (error) {
+ AdyenLogs.error_log('Error while fetching stores:', error);
+ res.json({ success: false });
+ }
+ return next();
+});
+
module.exports = server.exports();
diff --git a/src/cartridges/bm_adyen/cartridge/static/default/js/adyenSettings.js b/src/cartridges/bm_adyen/cartridge/static/default/js/adyenSettings.js
index c5a3c9831..08892b316 100644
--- a/src/cartridges/bm_adyen/cartridge/static/default/js/adyenSettings.js
+++ b/src/cartridges/bm_adyen/cartridge/static/default/js/adyenSettings.js
@@ -47,6 +47,17 @@ const expressPaymentMethods = [
},
];
+document.addEventListener('DOMContentLoaded', async () => {
+ const response = await fetch('AdyenSettings-GetStores', {
+ headers: {
+ 'Content-Type': 'application/json; charset=utf-8',
+ },
+ method: 'GET',
+ });
+ const result = await response.json();
+ return result;
+});
+
document.addEventListener('DOMContentLoaded', () => {
const form = document.querySelector('#settingsForm');
const troubleshootingForm = document.querySelector('#troubleshootingForm');
@@ -89,12 +100,28 @@ document.addEventListener('DOMContentLoaded', () => {
const params = 'resizable=yes,width=1000,height=500,left=100,top=100';
const draggableList = document.getElementById('draggable-list');
+ const availableStores = document.getElementById('storeID').value;
+ const terminalDropdown = document.getElementById('terminalDropdown');
+ const activeSelectedStores = document.getElementById('selectedStoreID').value;
let ruleCounter = 0;
const installmentsResult = {};
const listItems = [];
let dragStartIndex;
+ function renderStores() {
+ const stores = JSON.parse(availableStores);
+ stores.forEach((store) => {
+ const option = document.createElement('option');
+ option.value = store.id;
+ option.textContent = `${store.description} (${store.id})`;
+ terminalDropdown.appendChild(option);
+ if (activeSelectedStores.includes(store.id)) {
+ option.selected = true;
+ }
+ });
+ }
+
function settingChanged(key, value) {
const settingIndex = changedSettings.findIndex(
(setting) => setting.key === key,
@@ -563,26 +590,40 @@ document.addEventListener('DOMContentLoaded', () => {
})();
});
- // add event listener to maintain form updates
- form.addEventListener('change', (event) => {
- const { name } = event.target;
- let { value } = event.target; // get checked boolean value for checkboxes
-
- if (event.target.type === 'checkbox') {
- value = event.target.checked;
- }
+ function parseRadioValue(rawValue) {
+ if (rawValue === 'true') return true;
+ if (rawValue === 'false') return false;
+ return rawValue;
+ }
- // convert radio button strings to boolean if values are 'true' or 'false'
- if (event.target.type === 'radio') {
- if (event.target.value === 'true') {
- value = true;
- }
+ function getMultipleSelectValues(selectedOptions) {
+ return Array.from(selectedOptions)
+ .map((option) => option.value)
+ .join(',');
+ }
- if (event.target.value === 'false') {
- value = false;
- }
+ function getValueFromInput(type, rawValue, checked, selectedOptions) {
+ if (type === 'checkbox') {
+ return checked;
}
+ if (type === 'select-multiple') {
+ return getMultipleSelectValues(selectedOptions);
+ }
+ if (type === 'radio') {
+ return parseRadioValue(rawValue);
+ }
+ return rawValue;
+ }
+ form.addEventListener('change', (event) => {
+ const {
+ name,
+ type,
+ value: rawValue,
+ checked,
+ selectedOptions,
+ } = event.target;
+ const value = getValueFromInput(type, rawValue, checked, selectedOptions);
settingChanged(name, value);
});
@@ -648,5 +689,6 @@ document.addEventListener('DOMContentLoaded', () => {
window.location.reload();
});
+ renderStores();
createExpressPaymentsComponent(expressPaymentMethods, draggableList);
});
diff --git a/src/cartridges/bm_adyen/cartridge/templates/default/adyenSettings/settingCards/posSettings.isml b/src/cartridges/bm_adyen/cartridge/templates/default/adyenSettings/settingCards/posSettings.isml
index f19557b49..cf8ab9888 100644
--- a/src/cartridges/bm_adyen/cartridge/templates/default/adyenSettings/settingCards/posSettings.isml
+++ b/src/cartridges/bm_adyen/cartridge/templates/default/adyenSettings/settingCards/posSettings.isml
@@ -13,7 +13,11 @@
If you want a POS in your physical store, enter the unique store ID. Keep in mind that you can only assign your POS to a single store.
-
+
+
+
diff --git a/src/cartridges/bm_adyen/cartridge/utils/helper.js b/src/cartridges/bm_adyen/cartridge/utils/helper.js
new file mode 100644
index 000000000..c59a137af
--- /dev/null
+++ b/src/cartridges/bm_adyen/cartridge/utils/helper.js
@@ -0,0 +1,31 @@
+const Site = require('dw/system/Site');
+const Transaction = require('dw/system/Transaction');
+const AdyenConfigs = require('*/cartridge/adyen/utils/adyenConfigs');
+const AdyenHelper = require('*/cartridge/adyen/utils/adyenHelper');
+
+// Helper function to save to metadata field
+function saveMetadataField(field, data) {
+ const currentSite = Site.getCurrent();
+ Transaction.wrap(() => {
+ currentSite.setCustomPreferenceValue(field, JSON.stringify(data));
+ });
+}
+
+// Helper function to initialize a service
+function initializeAdyenService(svc, reqMethod) {
+ const service = AdyenHelper.getService(svc, reqMethod);
+ const apiKey = AdyenConfigs.getAdyenApiKey();
+ const merchantAccount = AdyenConfigs.getAdyenMerchantAccount();
+
+ if (!service || !apiKey || !merchantAccount) {
+ throw new Error('Missing request parameters, could not perform the call');
+ }
+
+ service.addHeader('Content-type', 'application/json');
+ service.addHeader('charset', 'UTF-8');
+ service.addHeader('X-API-key', apiKey);
+
+ return service;
+}
+
+module.exports = { saveMetadataField, initializeAdyenService };
diff --git a/src/cartridges/int_adyen_SFRA/cartridge/adyen/config/constants.js b/src/cartridges/int_adyen_SFRA/cartridge/adyen/config/constants.js
index 2c4759fce..1179575c4 100644
--- a/src/cartridges/int_adyen_SFRA/cartridge/adyen/config/constants.js
+++ b/src/cartridges/int_adyen_SFRA/cartridge/adyen/config/constants.js
@@ -49,6 +49,7 @@ module.exports = {
CANCELPARTIALPAYMENTORDER: 'AdyenCancelPartialPaymentOrder',
PARTIALPAYMENTSORDER: 'AdyenPartialPaymentsOrder',
PAYPALUPDATEORDER: 'AdyenPaypalUpdateOrder',
+ GETSTORES: 'AdyenManagementApiGetStores',
},
CONTRACT: {
ONECLICK: 'ONECLICK',
diff --git a/src/cartridges/int_adyen_SFRA/cartridge/adyen/utils/adyenConfigs.js b/src/cartridges/int_adyen_SFRA/cartridge/adyen/utils/adyenConfigs.js
index c6f5831a4..e2c57144d 100644
--- a/src/cartridges/int_adyen_SFRA/cartridge/adyen/utils/adyenConfigs.js
+++ b/src/cartridges/int_adyen_SFRA/cartridge/adyen/utils/adyenConfigs.js
@@ -98,6 +98,10 @@ const adyenConfigsObj = {
return getCustomPreference('Adyen_StoreId');
},
+ getAdyenActiveStoreId() {
+ return getCustomPreference('Adyen_SelectedStoreID');
+ },
+
getAdyenApiKey() {
return getCustomPreference('Adyen_API_Key');
},
diff --git a/src/cartridges/int_adyen_SFRA/cartridge/adyen/utils/adyenHelper.js b/src/cartridges/int_adyen_SFRA/cartridge/adyen/utils/adyenHelper.js
index 9cad8e3f1..36ba7f41b 100644
--- a/src/cartridges/int_adyen_SFRA/cartridge/adyen/utils/adyenHelper.js
+++ b/src/cartridges/int_adyen_SFRA/cartridge/adyen/utils/adyenHelper.js
@@ -42,13 +42,13 @@ const AdyenLogs = require('*/cartridge/adyen/logs/adyenCustomLogs');
/* eslint no-var: off */
let adyenHelperObj = {
// Create the service config used to make calls to the Adyen Checkout API (used for all services)
- getService(service) {
+ getService(service, reqMethod = 'POST') {
let adyenService = null;
try {
adyenService = LocalServiceRegistry.createService(service, {
createRequest(svc, args) {
- svc.setRequestMethod('POST');
+ svc.setRequestMethod(reqMethod);
if (args) {
return args;
}