bambora / checkout-opencart

Bambora Online Checkout - OpenCart
1 stars 5 forks source link

Multi-Store Support #6

Open syntaxerror opened 6 years ago

syntaxerror commented 6 years ago

OpenCart, Magento and some other of the supported carts have multi-store support.

This means they can be running several stores, using different domains (or sub-domains), from the same admin (about 50% of our clients use this).

Bambora supports normally only one domain per account (merchant id), as I have understood, but possibly have some workaround to allow several domains per account (still unclear to me).

So as a minimum, the modules should at least support using different payment windows (logo and name) per store/domain. But preferably also different Bambora accounts per domain, unless this domain restriction is going to change soon at Bamboras end.

syntaxerror commented 6 years ago

I don't recall any modules having "store-front" based settings, but I have one displaying feed url's for each. I'll post the code, in case it gives you any ideas. skjermdump fra 2018-02-01 17-52-23

From the controller file:

        $this->load->model('setting/store');

        $data['stores'] = array();

        $data['stores'][] = array(
            'store_id'    => '0',
            'name'        => 'Default',
            'url'        => HTTP_CATALOG,
            'ssl'        => ($this->request->server['HTTPS']) ? HTTPS_CATALOG : HTTP_CATALOG,
        );

        $data['stores'] = array_merge($data['stores'], $this->model_setting_store->getStores());

And the view:

                                    <fieldset>
                                    <?php if ($stores) { ?>
                                    <legend><?php echo $fieldset_data_feeds; ?></legend>
                                    <?php } else { ?>
                                    <legend><?php echo $fieldset_data_feed; ?></legend>
                                    <?php } ?>
                                    <?php foreach ($stores as $store) { ?>
                                    <div class="form-group">
                                        <label class="col-sm-2 control-label" for="input-data-feed-<?php echo $store['store_id']; ?>">
                                            <?php echo $store['name']; ?>
                                        </label>
                                        <div class="col-sm-10">
                                            <textarea rows="1" readonly="readonly" id="input-data-feed-<?php echo $store['store_id']; ?>" class="form-control"><?php echo (($store['ssl']) ? $store['ssl'] : $store['url']) . $feed_url ?></textarea>
                                            <button type="button" class="btn btn-default badge" onclick="copyToClipboard('#input-data-feed-<?php echo $store['store_id']; ?>')"><?php echo $text_copy; ?></a>
                                        </div>
                                    </div>
                                    <?php } ?>
                                    </fieldset>
AllanWLie commented 6 years ago

Hi @syntaxerror

Thank you for your input for the module. I have added your request to our backlog, but I can not say when or if the feature will be implemented.

Have a nice day

Best regards Allan

mehov commented 3 years ago

Hi everyone,

We have a multistore with 15 domain names. The actual store is the same, it is operated by the same company, and the websites only differ by language and ccTLDs for SEO reasons.

We received 15 merchant IDs from Bambora, but this official extension accepts only one, most likely because it was designed with one backend = one store logic in mind.

If we implement and contribute the changes required to make the extension work with multiple merchant IDs, will you consider merging them? Provided, they're submitted here using Github via a pull request where you can see which files had been changed and where exactly.

Or maybe due to some regulations (who knows) you can only publish the code that originated from within your organisation?

The change I can think of would be:

What do you think?

sessan commented 3 years ago

Hi @mehov! I have now posed the question to Product :) Will get back to you when a decision has been made! Best Regards Jessica, Developer Bambora Online

mehov commented 2 years ago

@sessan Hi, it's been 5 months, are there any news maybe? Please let me know. Thank you!

syntaxerror commented 2 years ago

The change I can think of would be:

  • Admin: loop though the defined stores and show a set of the Merchant ID, Secret Key etc. inputs per each. Save them into the config indexed by the store_id.
  • Catalog: fetch the configs by the id of the current store (e.g. here, or maybe even in a reusable fashion inside getConfigBaseName())

What do you think?

If anything is done with this, the easiest is probably to add the store id's to the returned values in getConfigBaseName(), plus the needed loop in admin for setting up the config for each. T.ex.: protected function getConfigBaseName() { if($this->is_oc_3()) { return "payment_{$this->module_name}_{$this->config->get('config_store_id')}"; } else { return {$this->module_name}_{$this->config->get('config_store_id')}; } }

syntaxerror commented 2 years ago

Or maybe due to some regulations (who knows) you can only publish the code that originated from within your organisation?

When it comes to this I hardly see any issue, as long as the quality control is done by Worldline (Bambora), the module already includes t.ex. my code, and also lots of OpenCart code.

And actually since it's built on and with OpenCart code, it's still GPL licensed code, no mater what's stated in the file headings, and actually the headers are GPL license violations #3

sessan commented 2 years ago

We have brought this request up to Product but it is not prioritised at the moment unfortunately.

mehov commented 2 years ago

To whoever is stuck with this like we are, here comes:

First commit:

---
 .../payment/bambora_online_checkout.php       | 42 ++++++++++--
 .../payment/bambora_online_checkout.php       | 12 +++-
 .../payment/bambora_online_checkout.tpl       | 65 ++++++++++---------
 .../payment/bambora_online_checkout.php       |  2 +-
 .../payment/bambora_online_checkout.php       | 32 ++++++++-
 5 files changed, 111 insertions(+), 42 deletions(-)

diff --git a/admin/controller/extension/payment/bambora_online_checkout.php b/admin/controller/extension/payment/bambora_online_checkout.php
index 2d14b173..40e6f71b 100644
--- a/admin/controller/extension/payment/bambora_online_checkout.php
+++ b/admin/controller/extension/payment/bambora_online_checkout.php
@@ -37,7 +37,34 @@ class ControllerExtensionPaymentBamboraOnlineCheckout extends Controller
     /**
      * @var array();
      */
-    private $errorFields = array('merchant', 'access_token', 'secret_token', 'permission');
+    private $errorFields = array('permission');
+
+    /**
+     * A list of store-dependent fields
+     *
+     * @var array()
+     * @access private
+     */
+    private $storeFields = array('merchant', 'access_token', 'secret_token', 'md5');
+
+    /**
+     * Returns all stores including the Default configured in this Opencart
+     *
+     * @access private
+     * @return array()
+     */
+    private function getConfiguredStores() {
+        // Get the list of all stores
+        $this->load->model('setting/store');
+        $stores = $this->model_setting_store->getStores();
+        // Prepend the default store to the list
+        array_unshift($stores, array(
+            'store_id' => 0,
+            'name' => $this->config->get('config_name') . $this->language->get('text_default'),
+            'url' => HTTP_CATALOG,
+        ));
+        return $stores;
+    }

     /**
      * Inits the module admin section
@@ -148,6 +175,8 @@ class ControllerExtensionPaymentBamboraOnlineCheckout extends Controller
         $this->data['order_statuses'] = $this->model_localisation_order_status->getOrderStatuses();
         $this->load->model('localisation/geo_zone');
         $this->data['geo_zones'] = $this->model_localisation_geo_zone->getGeoZones();
+        $this->data['stores'] = $this->getConfiguredStores();
+        $this->data['stores_merchants_fields'] = $this->storeFields;
         $this->data['header'] = $this->load->controller('common/header');
         $this->data['column_left'] = $this->load->controller('common/column_left');
         $this->data['footer'] = $this->load->controller('common/footer');
@@ -200,10 +229,6 @@ class ControllerExtensionPaymentBamboraOnlineCheckout extends Controller
     {
         $fields = array(
             'status',
-            'merchant',
-            'access_token',
-            'secret_token',
-            'md5',
             'window_state',
             'window_id',
             'surcharge',
@@ -231,6 +256,13 @@ class ControllerExtensionPaymentBamboraOnlineCheckout extends Controller
             'order_status_completed' => '5'
         );

+        $stores = $this->getConfiguredStores();
+        foreach ($this->storeFields as $key) {
+            foreach ($stores as $store) {
+                $fields[] = $store['store_id'].'_'.$key;
+            }
+        }
+
         // Loop through configuration fields and populate them
         foreach ($fields as $field) {
             $field = $this->getConfigBaseName() . '_' . $field;
diff --git a/admin/model/extension/payment/bambora_online_checkout.php b/admin/model/extension/payment/bambora_online_checkout.php
index 8df5e316..5825046e 100644
--- a/admin/model/extension/payment/bambora_online_checkout.php
+++ b/admin/model/extension/payment/bambora_online_checkout.php
@@ -184,9 +184,15 @@ class ModelExtensionPaymentBamboraOnlineCheckout extends Model
      */
     protected function getApiKey()
     {
-        $accesstoken = $this->config->get($this->getConfigBaseName() . '_access_token');
-        $merchantNumber = $this->config->get($this->getConfigBaseName() . '_merchant');
-        $secretToken = $this->config->get($this->getConfigBaseName() . '_secret_token');
+        $values = array();
+        foreach ($this->storeFields as $field) {
+            $values[] = $this->config->get(implode('_', [
+                $this->getConfigBaseName(),
+                $this->config->get('config_store_id'),
+                $field,
+            ]));
+        }
+        list($merchantNumber, $accesstoken, $secretToken, $md5) = $values;

         $combined = $accesstoken . '@' . $merchantNumber . ':' . $secretToken;
         $encoded_key = base64_encode($combined);
diff --git a/admin/view/template/extension/payment/bambora_online_checkout.tpl b/admin/view/template/extension/payment/bambora_online_checkout.tpl
index b48ef319..7f0d152c 100644
--- a/admin/view/template/extension/payment/bambora_online_checkout.tpl
+++ b/admin/view/template/extension/payment/bambora_online_checkout.tpl
@@ -49,39 +49,44 @@ echo $column_left;
               </select>
             </div>
           </div>      
-          <div class="form-group required">
-            <label class="col-sm-2 control-label" for="input-merchant"><span data-toggle="tooltip" title="<?php echo $help_merchant; ?>"><?php echo $entry_merchant; ?></span></label>
-            <div class="col-sm-10">
-              <input type="text" name="bambora_online_checkout_merchant" value="<?php echo $bambora_online_checkout_merchant; ?>" placeholder="<?php echo $entry_merchant; ?>" id="input-merchant" class="form-control" />
-              <?php if($error_merchant) { ?>
-              <div class="text-danger"><?php echo $error_merchant; ?></div>
-              <?php } ?>
-            </div>
-          </div>
-          <div class="form-group required">
-            <label class="col-sm-2 control-label" for="input-access-token"><span data-toggle="tooltip" title="<?php echo $help_access_token; ?>"> <?php echo $entry_access_token; ?></span></label>
-            <div class="col-sm-10">
-              <input type="text" name="bambora_online_checkout_access_token" value="<?php echo $bambora_online_checkout_access_token; ?>" placeholder="<?php echo $entry_access_token; ?>" id="input-accesstoken" class="form-control" />
-              <?php if($error_access_token) { ?> 
-              <div class="text-danger"><?php echo $error_access_token; ?></div>
-              <?php } ?> 
-            </div>
-          </div>
-          <div class="form-group required">
-            <label class="col-sm-2 control-label" for="input-secret-token"><span data-toggle="tooltip" title="<?php echo $help_secret_token; ?>"><?php echo $entry_secret_token; ?></span></label>
-            <div class="col-sm-10">
-              <input type="password" name="bambora_online_checkout_secret_token" value="<?php echo $bambora_online_checkout_secret_token; ?>" placeholder="<?php echo $entry_secret_token; ?>" id="input-secrettoken" class="form-control" />
-              <?php if($error_secret_token) { ?>
-              <div class="text-danger"><?php echo $error_secret_token; ?></div>
-              <?php } ?>
-            </div>
-          </div>
+
           <div class="form-group">
-            <label class="col-sm-2 control-label" for="input-md5"><span data-toggle="tooltip" title="<?php echo $help_md5; ?>"><?php echo $entry_md5; ?></span></label>
-            <div class="col-sm-10">
-              <input type="password" name="bambora_online_checkout_md5" value="<?php echo $bambora_online_checkout_md5; ?>" placeholder="<?php echo $entry_md5; ?>" id="input-md5" class="form-control" />
+            <div class="col-sm-10 col-sm-offset-2">
+                <table class="table table-bordered">
+                    <thead>
+                        <tr>
+                            <td>Store</td>
+<?php foreach ($stores_merchants_fields as $key): ?>
+                            <td>
+                                <span data-toggle="tooltip" title="<?=${'help_'.$key}?>">
+                                    <?=${'entry_'.$key}?>
+                                </span>
+                            </td>
+<?php endforeach; ?>
+                        </tr>
+                    </thead>
+                    <tbody>
+<?php foreach ($stores as $store) : ?>
+                        <tr>
+                            <td><?=$store['name']?></td>
+<?php foreach ($stores_merchants_fields as $key): ?>
+                            <td>
+                                <input
+                                    name="bambora_online_checkout_<?=$store['store_id']?>_<?=$key?>"
+                                    value="<?=${'bambora_online_checkout_'.$store['store_id'].'_'.$key}?>"
+                                    title="<?=${'entry_'.$key}?>"
+                                    placeholder="<?=${'entry_'.$key}?>"
+                                    class="form-control"
+                                    >
+                            </td>
+<?php endforeach; ?>
+                        </tr>
+<?php endforeach; ?>
+                    </tbody>
+                </table>
             </div>
           </div>
+
           <div class="form-group">
             <label class="col-sm-2 control-label" for="input-window-state"><span data-toggle="tooltip" title="<?php echo $help_window_state; ?>"><?php echo $entry_window_state; ?></span></label>
             <div class="col-sm-10">
diff --git a/catalog/controller/extension/payment/bambora_online_checkout.php b/catalog/controller/extension/payment/bambora_online_checkout.php
index 1a9ed22d..738befc4 100644
--- a/catalog/controller/extension/payment/bambora_online_checkout.php
+++ b/catalog/controller/extension/payment/bambora_online_checkout.php
@@ -498,7 +498,7 @@ class ControllerExtensionPaymentBamboraOnlineCheckout extends Controller
             return false;
         }
         // Validate MD5!
-        $merchantMd5Key = $this->config->get($this->getConfigBaseName() . '_md5');
+        $merchantMd5Key = $this->config->get($this->getConfigBaseName().'_'.$this->config->get('config_store_id').'_md5');
         if(!empty($merchantMd5Key)) {
             $concatenatedValues  = '';
             foreach ($getParameteres as $key => $value) {
diff --git a/catalog/model/extension/payment/bambora_online_checkout.php b/catalog/model/extension/payment/bambora_online_checkout.php
index be001bdd..40bf2930 100644
--- a/catalog/model/extension/payment/bambora_online_checkout.php
+++ b/catalog/model/extension/payment/bambora_online_checkout.php
@@ -27,6 +27,14 @@ class ModelExtensionPaymentBamboraOnlineCheckout extends Model
      */
     private $module_version = '1.3.0';

+    /**
+     * A list of store-dependent fields
+     *
+     * @var array()
+     * @access private
+     */
+    private $storeFields = array('merchant', 'access_token', 'secret_token', 'md5');
+
     /**
      * Returns method data
      *
@@ -49,6 +57,18 @@ class ModelExtensionPaymentBamboraOnlineCheckout extends Model
         } else {
             $status = false;
         }
+        // Abort if some important store-based setting values are missing
+        foreach ($this->storeFields as $field) {
+            if (!$status) {
+                break;
+            }
+            $field = implode('_', [
+                $this->getConfigBaseName(),
+                $this->config->get('config_store_id'),
+                $field,
+            ]);
+            $status = $status && !!$this->config->get($field);
+        }

         $method_data = array();

@@ -193,9 +213,15 @@ class ModelExtensionPaymentBamboraOnlineCheckout extends Model
      */
     protected function getApiKey()
     {
-        $accesstoken = $this->config->get($this->getConfigBaseName() . '_access_token');
-        $merchantNumber = $this->config->get($this->getConfigBaseName() . '_merchant');
-        $secretToken = $this->config->get($this->getConfigBaseName() . '_secret_token');
+        $values = array();
+        foreach ($this->storeFields as $field) {
+            $values[] = $this->config->get(implode('_', [
+                $this->getConfigBaseName(),
+                $this->config->get('config_store_id'),
+                $field,
+            ]));
+        }
+        list($merchantNumber, $accesstoken, $secretToken, $md5) = $values;

         $combined = $accesstoken . '@' . $merchantNumber . ':' . $secretToken;
         $encoded_key = base64_encode($combined);
-- 

Followed by:

---
 .../extension/payment/bambora_online_checkout.php      | 10 +++++++++-
 .../extension/payment/bambora_online_checkout.php      |  2 +-
 2 files changed, 10 insertions(+), 2 deletions(-)

diff --git a/admin/model/extension/payment/bambora_online_checkout.php b/admin/model/extension/payment/bambora_online_checkout.php
index 5825046e..cd115594 100644
--- a/admin/model/extension/payment/bambora_online_checkout.php
+++ b/admin/model/extension/payment/bambora_online_checkout.php
@@ -27,6 +27,14 @@ class ModelExtensionPaymentBamboraOnlineCheckout extends Model
      */
     private $module_name = 'bambora_online_checkout';

+    /**
+     * A list of store-dependent fields
+     *
+     * @var array()
+     * @access private
+     */
+    private $storeFields = array('merchant', 'access_token', 'secret_token', 'md5');
+
     /**
      * Install and create Bambora Online Checkout Transaction table
      */
@@ -188,7 +196,7 @@ class ModelExtensionPaymentBamboraOnlineCheckout extends Model
         foreach ($this->storeFields as $field) {
             $values[] = $this->config->get(implode('_', [
                 $this->getConfigBaseName(),
-                $this->config->get('config_store_id'),
+                (int)$this->config->get('config_store_id'),
                 $field,
             ]));
         }
diff --git a/catalog/model/extension/payment/bambora_online_checkout.php b/catalog/model/extension/payment/bambora_online_checkout.php
index 40bf2930..e17a0d62 100644
--- a/catalog/model/extension/payment/bambora_online_checkout.php
+++ b/catalog/model/extension/payment/bambora_online_checkout.php
@@ -217,7 +217,7 @@ class ModelExtensionPaymentBamboraOnlineCheckout extends Model
         foreach ($this->storeFields as $field) {
             $values[] = $this->config->get(implode('_', [
                 $this->getConfigBaseName(),
-                $this->config->get('config_store_id'),
+                (int)$this->config->get('config_store_id'),
                 $field,
             ]));
         }
-- 

I initially wanted to make this into a pull request, but I guess chances are it will be ignored, plus if you said yourself that you don't need it, then why should we even bother, right?

And it looks like Opencart is a sinking ship anyway.

syntaxerror commented 2 years ago

I initially wanted to make this into a pull request, but I guess chances are it will be ignored, plus if you said yourself that you don't need it, then why should we even bother, right?

A pull request is probably easier for many to read and use than the old fashion diffs, even if WorldLine (Bambora) ignores it, or have it pending forever. But sure they have some weird priorities at Product... :)

And it looks like Opencart is a sinking ship anyway.

Sure OpenCart and its dev is what it is, and we probably wouldn't build any new stores on it at this point, but still using search stats as a measurement for the use of it probably isn't the best idea - most software have some of the same drop. Better look at something like https://trends.builtwith.com/shop

sessan commented 2 years ago

Hi! I've brought this up again with the product team and it has finally been prioritised (multi store setups for all the different shopping carts we provide) so we can look into it! So it would be very helpful if you could provide a pull request @mehov So I'm opening this again @syntaxerror :)

introlone commented 2 years ago

I'm looking to implement Bambora in a multi-store setup. It's been a few months since this was last discussed. Any updates @sessan ?