Mollie Payments for WooCommerce - Version 6.3.0

Version Description

  • 29-04-2021 =

  • Feature - Allow choosing between Payment/Order API

  • Feature - Payment surcharge feature

  • Feature - Custom icons for every gateway

  • Feature - Notice about increasing minimum PHP and WP version

  • Fix - Fix missing metadata in subscriptions

  • Fix - Polylang interaction breaks redirect URL

  • Fix - Partial refund with quantity 0 errors

Download this release

Release Info

Developer carmen222
Plugin Icon wp plugin Mollie Payments for WooCommerce
Version 6.3.0
Comparing to
See all releases

Code changes from version 6.2.2 to 6.3.0

inc/settings/mollie_advanced_settings.php CHANGED
@@ -77,7 +77,58 @@ return [
77
 
78
 
79
  ],
80
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  [
82
  'id' => $pluginName . '_' .'sectionend',
83
  'type' => 'sectionend',
77
 
78
 
79
  ],
80
+ [
81
+ 'id' => $pluginName . '_' .'api_switch',
82
+ 'title' => __(
83
+ 'Select API Method',
84
+ 'mollie-payments-for-woocommerce'
85
+ ),
86
+ 'type' => 'select',
87
+ 'options' => [
88
+ Mollie_WC_Gateway_Abstract::PAYMENT_METHOD_TYPE_ORDER => ucfirst(
89
+ Mollie_WC_Gateway_Abstract::PAYMENT_METHOD_TYPE_ORDER
90
+ ) . ' (' . __('default', 'mollie-payments-for-woocommerce')
91
+ . ')',
92
+ Mollie_WC_Gateway_Abstract::PAYMENT_METHOD_TYPE_PAYMENT => ucfirst(
93
+ Mollie_WC_Gateway_Abstract::PAYMENT_METHOD_TYPE_PAYMENT
94
+ ),
95
+ ],
96
+ 'default' => Mollie_WC_Gateway_Abstract::PAYMENT_METHOD_TYPE_ORDER,
97
+ /* translators: Placeholder 1: Default order status, placeholder 2: Link to 'Hold Stock' setting */
98
+ 'desc' => sprintf(
99
+ __(
100
+ 'Click %shere%s to read more about the differences between the Payments and Orders API',
101
+ 'mollie-payments-for-woocommerce'
102
+ ),
103
+ '<a href="https://docs.mollie.com/orders/why-use-orders" target="_blank">',
104
+ '</a>'
105
+ )
106
+ ],
107
+ [
108
+ 'id' => $pluginName . '_' . 'api_payment_description',
109
+ 'title' => __(
110
+ 'API Payment Description',
111
+ 'mollie-payments-for-woocommerce'
112
+ ),
113
+ 'type' => 'select',
114
+ 'options' => [
115
+ '{orderNumber}' => '{orderNumber}',
116
+ '{storeName}' => '{storeName}',
117
+ '{customer.firstname}' => '{customer.firstname}',
118
+ '{customer.lastname}' => '{customer.lastname}',
119
+ '{customer.company}' => '{customer.company}'
120
+ ],
121
+ 'default' => '{orderNumber}',
122
+ /* translators: Placeholder 1: Default order status, placeholder 2: Link to 'Hold Stock' setting */
123
+ 'desc' => sprintf(
124
+ __(
125
+ 'Select among the available variables the description to be used for this transaction.%s(Note: this only works when the method is set to Payments API)%s',
126
+ 'mollie-payments-for-woocommerce'
127
+ ),
128
+ '<p>',
129
+ '</p>'
130
+ )
131
+ ],
132
  [
133
  'id' => $pluginName . '_' .'sectionend',
134
  'type' => 'sectionend',
mollie-payments-for-woocommerce.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: Mollie Payments for WooCommerce
4
  * Plugin URI: https://www.mollie.com
5
  * Description: Accept payments in WooCommerce with the official Mollie plugin
6
- * Version: 6.2.2
7
  * Author: Mollie
8
  * Author URI: https://www.mollie.com
9
  * Requires at least: 3.8
@@ -12,10 +12,12 @@
12
  * Domain Path: /languages
13
  * License: GPLv2 or later
14
  * WC requires at least: 3.0
15
- * WC tested up to: 5.1
16
  */
17
 
18
 
 
 
19
 
20
  require_once(ABSPATH . 'wp-admin/includes/plugin.php');
21
 
@@ -139,6 +141,30 @@ $bootstrap = Closure::bind(
139
  }
140
  return;
141
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
142
 
143
  add_action(
144
  'init',
3
  * Plugin Name: Mollie Payments for WooCommerce
4
  * Plugin URI: https://www.mollie.com
5
  * Description: Accept payments in WooCommerce with the official Mollie plugin
6
+ * Version: 6.3.0
7
  * Author: Mollie
8
  * Author URI: https://www.mollie.com
9
  * Requires at least: 3.8
12
  * Domain Path: /languages
13
  * License: GPLv2 or later
14
  * WC requires at least: 3.0
15
+ * WC tested up to: 5.2
16
  */
17
 
18
 
19
+ use Inpsyde\EnvironmentChecker\Constraints\PhpConstraint;
20
+ use Inpsyde\EnvironmentChecker\Constraints\WordPressConstraint;
21
 
22
  require_once(ABSPATH . 'wp-admin/includes/plugin.php');
23
 
141
  }
142
  return;
143
  }
144
+ $checker->maybeShowWarning(
145
+ new WordPressConstraint('5.0'),
146
+ sprintf(
147
+ __(
148
+ 'Mollie Payments for WooCommerce is dropping support for WordPress versions less than 5.0. Please update WordPress to the latest version.</br> Without an update, you will not receive any new features.
149
+ Contact our support team %1$shere%2$s if any questions remain.',
150
+ 'mollie-payments-for-woocommerce'
151
+ ),
152
+ '<a href="https://mollie.inpsyde.com/" target="_blank">',
153
+ '</a>'
154
+ )
155
+ );
156
+ $checker->maybeShowWarning(
157
+ new PhpConstraint('7.2'),
158
+ sprintf(
159
+ __(
160
+ 'Mollie Payments for WooCommerce is dropping support for PHP versions less than 7.2. As such, using outdated and unsupported versions of PHP may expose your site to security vulnerabilities. Please update PHP to the latest version.
161
+ For further informations see %1$shere%2$s and if any questions remain contact our support team.',
162
+ 'mollie-payments-for-woocommerce'
163
+ ),
164
+ '<a href="https://mollie.inpsyde.com/docs/php-7-2-update/" target="_blank">',
165
+ '</a>'
166
+ )
167
+ );
168
 
169
  add_action(
170
  'init',
public/css/mollie-gateway-icons.min.css CHANGED
@@ -1 +1 @@
1
- .mollie-gateway-icon{width:32px;vertical-align:bottom}label .mollie-gateway-icon{float:right}
1
+ .mollie-gateway-icon{width:32px;vertical-align:bottom}label .mollie-gateway-icon{float:right}.mollie_custom_icon{padding:1em}
public/js/entrypoints.json CHANGED
@@ -25,6 +25,16 @@
25
  "/public/js/settings.min.js"
26
  ]
27
  },
 
 
 
 
 
 
 
 
 
 
28
  "mollie-components.min": {
29
  "js": [
30
  "/public/js/mollie-components.min.js"
25
  "/public/js/settings.min.js"
26
  ]
27
  },
28
+ "gatewaySettings.min": {
29
+ "js": [
30
+ "/public/js/gatewaySettings.min.js"
31
+ ]
32
+ },
33
+ "gatewaySurcharge.min": {
34
+ "js": [
35
+ "/public/js/gatewaySurcharge.min.js"
36
+ ]
37
+ },
38
  "mollie-components.min": {
39
  "js": [
40
  "/public/js/mollie-components.min.js"
public/js/gatewaySettings.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/public/js/",n(n.s="6cVz")}({"6cVz":function(e,t){var n,r,o,i,c,u,a,l,d;n=window,r=n._,o=n.gatewaySettingsData,i=n.jQuery,c=o.isEnabledIcon,u=o.uploadFieldName,a=o.enableFieldName,l=o.iconUrl,d=o.message,r.isEmpty(o)||(document.addEventListener("DOMContentLoaded",(function(e){if(c){var t=document.querySelector("#"+u);r.isEmpty(l)?t.insertAdjacentHTML("afterend",'<div class="mollie_custom_icon"><p>'+d+"</p></div>"):t.insertAdjacentHTML("afterend",'<div class="mollie_custom_icon"><img src="'+l+'" alt="custom icon image" width="100px"></div>')}})),i((function(e){e("#"+a).change((function(){e(this).is(":checked")?e("#"+u).closest("tr").show():e("#"+u).closest("tr").hide()})).change()})))}});
public/js/gatewaySurcharge.min.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(e){var t={};function r(o){if(t[o])return t[o].exports;var n=t[o]={i:o,l:!1,exports:{}};return e[o].call(n.exports,n,n.exports,r),n.l=!0,n.exports}r.m=e,r.c=t,r.d=function(e,t,o){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(r.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)r.d(o,n,function(t){return e[t]}.bind(null,n));return o},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="/public/js/",r(r.s="pfyl")}({pfyl:function(e,t){var r,o,n;r=window,o=r.jQuery,n=r.surchargeData,o((function(e){e("body").on("change",'input[name="payment_method"]',(function(){e("body").trigger("update_checkout")}))})),n&&document.body.classList.contains("woocommerce-order-pay")&&o((function(e){var t=!1,r=e('input:hidden[name="mollie-woocommerce-orderId"]');r.length&&(t=r.val()),e("body").on("change",'input[name="payment_method"]',(function(){o.ajax({url:n.ajaxUrl,method:"POST",data:{action:"update_surcharge_order_pay",method:e('input:radio[name="payment_method"]:checked').val(),orderId:t},success:function(t){var r=t.data;if(r){var o="</th><td class='product-total'><span class='woocommerce-Price-amount amount'><bdi><span class='woocommerce-Price-currencySymbol'>"+r.currency+"</span>"+r.newTotal+"</bdi></span></td>";if(r.amount){var n="<tr><th scope='row' colspan='2'>"+r.name+"</th><td class='product-total'><span class='woocommerce-Price-amount amount'><bdi><span class='woocommerce-Price-currencySymbol'>"+r.currency+"</span>"+r.amount.toFixed(2)+"</bdi></span></td></tr>";-1!==e("#order_review table:first-child tfoot tr").text().indexOf("Mollie_WC_")?(e('#order_review table:first-child tfoot tr:contains("Mollie_WC_")').replaceWith(n),e("#order_review table:first-child tfoot tr:last td").replaceWith(o)):(e("#order_review table:first-child tfoot tr:first").after(n),e("#order_review table:first-child tfoot tr:last td").replaceWith(o))}else-1!==e("#order_review table:first-child tfoot tr").text().indexOf("Mollie_WC_")&&(e('#order_review table:first-child tfoot tr:contains("Mollie_WC_")').remove(),e("#order_review table:first-child tfoot tr:last td").replaceWith(o))}},error:function(e,t,r){console.warn(t,r)}})}))}))}});
public/js/manifest.json CHANGED
@@ -3,6 +3,8 @@
3
  "public/js/applepayDirect.min.js": "/public/js/applepayDirect.min.js",
4
  "public/js/applepayDirectCart.min.js": "/public/js/applepayDirectCart.min.js",
5
  "public/js/babel-polyfill.min.js": "/public/js/babel-polyfill.min.js",
 
 
6
  "public/js/mollie-components.min.js": "/public/js/mollie-components.min.js",
7
  "public/js/settings.min.js": "/public/js/settings.min.js"
8
  }
3
  "public/js/applepayDirect.min.js": "/public/js/applepayDirect.min.js",
4
  "public/js/applepayDirectCart.min.js": "/public/js/applepayDirectCart.min.js",
5
  "public/js/babel-polyfill.min.js": "/public/js/babel-polyfill.min.js",
6
+ "public/js/gatewaySettings.min.js": "/public/js/gatewaySettings.min.js",
7
+ "public/js/gatewaySurcharge.min.js": "/public/js/gatewaySurcharge.min.js",
8
  "public/js/mollie-components.min.js": "/public/js/mollie-components.min.js",
9
  "public/js/settings.min.js": "/public/js/settings.min.js"
10
  }
public/js/settings.min.js CHANGED
@@ -1 +1 @@
1
- !function(e){var t={};function r(o){if(t[o])return t[o].exports;var n=t[o]={i:o,l:!1,exports:{}};return e[o].call(n.exports,n,n.exports,r),n.l=!0,n.exports}r.m=e,r.c=t,r.d=function(e,t,o){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(r.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)r.d(o,n,function(t){return e[t]}.bind(null,n));return o},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="/public/js/",r(r.s="Hiql")}({Hiql:function(e,t){jQuery((function(e){e("#mollie-payments-for-woocommerce_test_mode_enabled").change((function(){e(this).is(":checked")?e("#mollie-payments-for-woocommerce_test_api_key").attr("required",!0).closest("tr").show():e("#mollie-payments-for-woocommerce_test_api_key").removeAttr("required").closest("tr").hide()})).change()}))}});
1
+ !function(e){var t={};function r(o){if(t[o])return t[o].exports;var n=t[o]={i:o,l:!1,exports:{}};return e[o].call(n.exports,n,n.exports,r),n.l=!0,n.exports}r.m=e,r.c=t,r.d=function(e,t,o){r.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(r.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)r.d(o,n,function(t){return e[t]}.bind(null,n));return o},r.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(t,"a",t),t},r.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r.p="/public/js/",r(r.s="Hiql")}({Hiql:function(e,t){var r,o,n;r=window,o=r._,n=r.mollieSettingsData,(0,r.jQuery)((function(e){if(e("#mollie-payments-for-woocommerce_test_mode_enabled").change((function(){e(this).is(":checked")?e("#mollie-payments-for-woocommerce_test_api_key").attr("required",!0).closest("tr").show():e("#mollie-payments-for-woocommerce_test_api_key").removeAttr("required").closest("tr").hide()})).change(),!o.isEmpty(n)){var t=n.current_section,r=e("#"+t+"_fixed_fee").closest("tr"),i=e("#"+t+"_percentage").closest("tr"),c=e("#"+t+"_surcharge_limit").closest("tr");e("#"+t+"_payment_surcharge").change((function(){switch(e(this).val()){case"no_fee":r.hide(),i.hide(),c.hide();break;case"fixed_fee":r.show(),i.hide(),c.hide();break;case"percentage":r.hide(),i.show(),c.show();break;case"fixed_fee_percentage":default:r.show(),i.show(),c.show()}})).change()}}))}});
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: daanvm, danielhuesken, davdebcom, dinamiko, inpsyde, l.vangunst, n
3
  Tags: mollie, payments, payment gateway, woocommerce, credit card, ideal, bancontact, klarna, sofort, giropay, woocommerce subscriptions
4
  Requires at least: 3.8
5
  Tested up to: 5.7
6
- Stable tag: 6.2.2
7
  Requires PHP: 5.6
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -181,6 +181,16 @@ Automatic updates should work like a charm; as always though, ensure you backup
181
 
182
  == Changelog ==
183
 
 
 
 
 
 
 
 
 
 
 
184
  = 6.2.2 - 15-04-2021 =
185
 
186
  * Fix - Missing metadata on subscriptions results in failing recurring payments
3
  Tags: mollie, payments, payment gateway, woocommerce, credit card, ideal, bancontact, klarna, sofort, giropay, woocommerce subscriptions
4
  Requires at least: 3.8
5
  Tested up to: 5.7
6
+ Stable tag: 6.3.0
7
  Requires PHP: 5.6
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
181
 
182
  == Changelog ==
183
 
184
+ = 6.3.0 - 29-04-2021 =
185
+
186
+ * Feature - Allow choosing between Payment/Order API
187
+ * Feature - Payment surcharge feature
188
+ * Feature - Custom icons for every gateway
189
+ * Feature - Notice about increasing minimum PHP and WP version
190
+ * Fix - Fix missing metadata in subscriptions
191
+ * Fix - Polylang interaction breaks redirect URL
192
+ * Fix - Partial refund with quantity 0 errors
193
+
194
  = 6.2.2 - 15-04-2021 =
195
 
196
  * Fix - Missing metadata on subscriptions results in failing recurring payments
src/Mollie/WC/ActivationHandle/ConstraintsChecker.php CHANGED
@@ -76,6 +76,30 @@ class Mollie_WC_ActivationHandle_ConstraintsChecker
76
  }
77
  }
78
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
79
  protected function showNotice(array $errors)
80
  {
81
  $message = '%1$sMollie Payments for WooCommerce is inactive:%2$s';
76
  }
77
  }
78
 
79
+ public function maybeShowWarning($constraint, $warning){
80
+ $collectionFactory = new ConstraintsCollectionFactory();
81
+ $constraintsCollection = $collectionFactory->create(
82
+ $constraint
83
+ );
84
+ $result = new EnvironmentChecker(
85
+ $constraintsCollection->constraints()
86
+ );
87
+ try {
88
+ $result->check();
89
+ return true;
90
+ } catch (ConstraintFailedException $exception) {
91
+ $mainException = $exception->getValidationErrors();
92
+ $errors = [];
93
+ foreach ($mainException as $error) {
94
+ $errors[] = $error->getMessage();
95
+ }
96
+
97
+ $this->notice->addNotice('notice-warning is-dismissible', $warning);
98
+ return false;
99
+ }
100
+
101
+ }
102
+
103
  protected function showNotice(array $errors)
104
  {
105
  $message = '%1$sMollie Payments for WooCommerce is inactive:%2$s';
src/Mollie/WC/Gateway/Abstract.php CHANGED
@@ -97,60 +97,86 @@ abstract class Mollie_WC_Gateway_Abstract extends WC_Payment_Gateway
97
  */
98
  public function init_form_fields()
99
  {
100
- $this->form_fields = array(
101
- 'enabled' => array(
102
- 'title' => __('Enable/Disable', 'mollie-payments-for-woocommerce'),
103
- 'type' => 'checkbox',
104
- 'label' => sprintf(__('Enable %s', 'mollie-payments-for-woocommerce'), $this->getDefaultTitle()),
105
- 'default' => 'yes'
106
- ),
107
- 'title' => array(
108
- 'title' => __('Title', 'mollie-payments-for-woocommerce'),
109
- 'type' => 'text',
110
- 'description' => sprintf(__('This controls the title which the user sees during checkout. Default <code>%s</code>', 'mollie-payments-for-woocommerce'), $this->getDefaultTitle()),
111
- 'default' => $this->getDefaultTitle(),
112
- 'desc_tip' => true,
113
- ),
114
- 'display_logo' => array(
115
- 'title' => __('Display logo', 'mollie-payments-for-woocommerce'),
116
- 'type' => 'checkbox',
117
- 'label' => __('Display logo on checkout page. Default <code>enabled</code>', 'mollie-payments-for-woocommerce'),
118
- 'default' => 'yes'
119
- ),
120
- 'description' => array(
121
- 'title' => __('Description', 'mollie-payments-for-woocommerce'),
122
- 'type' => 'textarea',
123
- 'description' => sprintf(__('Payment method description that the customer will see on your checkout. Default <code>%s</code>', 'mollie-payments-for-woocommerce'), $this->getDefaultDescription()),
124
- 'default' => $this->getDefaultDescription(),
125
- 'desc_tip' => true,
126
- ),
127
- 'allowed_countries' => array(
128
- 'title' => __( 'Sell to specific countries', 'mollie-payments-for-woocommerce' ),
129
- 'desc' => '',
130
- 'css' => 'min-width: 350px;',
131
- 'default' => [],
132
- 'type' => 'multi_select_countries',
133
- ),
134
  );
135
 
136
- if ($this->paymentConfirmationAfterCoupleOfDays())
137
- {
138
- $this->form_fields['initial_order_status'] = array(
139
- 'title' => __('Initial order status', 'mollie-payments-for-woocommerce'),
140
- 'type' => 'select',
141
- 'options' => array(
142
- self::STATUS_ON_HOLD => wc_get_order_status_name(self::STATUS_ON_HOLD) . ' (' . __('default', 'mollie-payments-for-woocommerce') . ')',
143
- self::STATUS_PENDING => wc_get_order_status_name(self::STATUS_PENDING),
144
- ),
145
- 'default' => self::STATUS_ON_HOLD,
146
- /* translators: Placeholder 1: Default order status, placeholder 2: Link to 'Hold Stock' setting */
147
- 'description' => sprintf(
148
- __('Some payment methods take longer than a few hours to complete. The initial order state is then set to \'%s\'. This ensures the order is not cancelled when the setting %s is used.', 'mollie-payments-for-woocommerce'),
149
- wc_get_order_status_name(self::STATUS_ON_HOLD),
150
- '<a href="' . admin_url( 'admin.php?page=wc-settings&tab=products&section=inventory') . '" target="_blank">' . __('Hold Stock (minutes)', 'woocommerce') . '</a>'
151
- ),
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  );
153
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  }
155
 
156
  /**
@@ -179,7 +205,7 @@ abstract class Mollie_WC_Gateway_Abstract extends WC_Payment_Gateway
179
 
180
  protected function _initDescription ()
181
  {
182
- $description = $this->get_option('description', '');
183
 
184
  $this->description = $description;
185
  }
@@ -569,8 +595,8 @@ abstract class Mollie_WC_Gateway_Abstract extends WC_Payment_Gateway
569
 
570
  }
571
 
572
- $molliePaymentType = $this->paymentTypeBasedOnProducts($order);
573
- $molliePaymentType = $this->paymentTypeBasedOnGateway($molliePaymentType);
574
  try {
575
  $paymentObject = Mollie_WC_Plugin::getPaymentFactoryHelper()
576
  ->getPaymentObject(
@@ -1251,54 +1277,52 @@ abstract class Mollie_WC_Gateway_Abstract extends WC_Payment_Gateway
1251
  *
1252
  * @return string
1253
  */
1254
- public function getReturnRedirectUrlForOrder( WC_Order $order )
1255
  {
1256
  $order_id = $order->get_id();
1257
  $debugLine = __METHOD__ . " {$order_id}: Determine what the redirect URL in WooCommerce should be.";
1258
  mollieWooCommerceDebug($debugLine);
1259
  $hookReturnPaymentStatus = 'success';
1260
-
 
1261
  if ( $this->orderNeedsPayment( $order ) ) {
1262
 
1263
- $hasCancelledMolliePayment = $this->paymentObject()->getCancelledMolliePaymentId( $order_id );
1264
 
1265
- if ( $hasCancelledMolliePayment ) {
1266
 
1267
- $settings_helper = Mollie_WC_Plugin::getSettingsHelper();
1268
- $order_status_cancelled_payments = $settings_helper->getOrderStatusCancelledPayments();
1269
 
1270
- // If user set all cancelled payments to also cancel the order,
1271
- // redirect to /checkout/order-received/ with a message about the
1272
- // order being cancelled. Otherwise redirect to /checkout/order-pay/ so
1273
- // customers can try to pay with another payment method.
1274
- if ( $order_status_cancelled_payments == 'cancelled' ) {
 
1275
 
1276
- return $this->get_return_url( $order );
1277
-
1278
- } else {
1279
- Mollie_WC_Plugin::addNotice( __( 'You have cancelled your payment. Please complete your order with a different payment method.', 'mollie-payments-for-woocommerce' ) );
1280
-
1281
- // Return to order payment page
1282
- if ( method_exists( $order, 'get_checkout_payment_url' ) ) {
1283
- return $order->get_checkout_payment_url( false );
1284
- }
1285
- }
1286
 
1287
- // Return to order payment page
1288
- if ( method_exists( $order, 'get_checkout_payment_url' ) ) {
1289
- return $order->get_checkout_payment_url( false );
1290
- }
1291
 
1292
- }
 
 
1293
 
1294
  try {
1295
  $payment = $this->activePaymentObject($order_id, false);
1296
  if ( ! $payment->isOpen() && ! $payment->isPending() && ! $payment->isPaid() && ! $payment->isAuthorized() ) {
1297
  mollieWooCommerceNotice(__('Your payment was not successful. Please complete your order with a different payment method.', 'mollie-payments-for-woocommerce'));
1298
  // Return to order payment page
1299
- if ( method_exists( $order, 'get_checkout_payment_url' ) ) {
1300
- return $order->get_checkout_payment_url( false );
1301
- }
1302
  }
1303
  if ($payment->method === "giftcard") {
1304
  $this->debugGiftcardDetails($payment, $order);
@@ -1311,14 +1335,14 @@ abstract class Mollie_WC_Gateway_Abstract extends WC_Payment_Gateway
1311
  mollieWooCommerceDebug($debugLine);
1312
  $hookReturnPaymentStatus = 'failed';
1313
  }
1314
- }
1315
  do_action( Mollie_WC_Plugin::PLUGIN_ID . '_customer_return_payment_' . $hookReturnPaymentStatus, $order );
1316
 
1317
- /*
1318
- * Return to order received page
1319
- */
1320
- return $this->get_return_url( $order );
1321
- }
1322
  /**
1323
  * Retrieve the payment object
1324
  *
@@ -1697,6 +1721,7 @@ abstract class Mollie_WC_Gateway_Abstract extends WC_Payment_Gateway
1697
 
1698
  /**
1699
  * Get the url to return to on Mollie return
 
1700
  * For example 'http://mollie-wc.docker.myhost/wc-api/mollie_return/?order_id=89&key=wc_order_eFZyH8jki6fge'
1701
  *
1702
  * @param WC_Order $order The order processed
@@ -1705,36 +1730,20 @@ abstract class Mollie_WC_Gateway_Abstract extends WC_Payment_Gateway
1705
  */
1706
  public function getReturnUrl (WC_Order $order)
1707
  {
1708
- $siteUrl = get_home_url();
1709
- $returnUrl = WC()->api_request_url( 'mollie_return' );
1710
- $returnUrl = untrailingslashit($returnUrl);
1711
- if (function_exists('idn_to_ascii')) {
1712
-
1713
- if (defined('IDNA_NONTRANSITIONAL_TO_ASCII') && defined('INTL_IDNA_VARIANT_UTS46')) {
1714
- $returnUrl = idn_to_ascii($returnUrl, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46);
1715
- } else {
1716
- $returnUrl = idn_to_ascii($returnUrl);
1717
- }
1718
- }
1719
  $orderId = $order->get_id();
1720
  $orderKey = $order->get_order_key();
 
1721
  $returnUrl = $this->appendOrderArgumentsToUrl(
1722
- $orderId,
1723
- $orderKey,
1724
- $returnUrl
 
1725
  );
1726
  $returnUrl = untrailingslashit($returnUrl);
1727
- $langUrl = $this->getSiteUrlWithLanguage();
1728
-
1729
- // Make sure there aren't any double /? in the URL (some (multilanguage) plugins will add this)
1730
- if ( strpos( $langUrl, '/?' ) !== false ) {
1731
- $langUrlParams = substr( $langUrl, strpos( $langUrl, "/?" ) + 2 );
1732
- $returnUrl = $returnUrl . '&' . $langUrlParams;
1733
- } else {
1734
- $returnUrl = str_replace( $siteUrl, $langUrl, $returnUrl );
1735
- }
1736
- // Some (multilanguage) plugins will add a extra slash to the url (/nl//) causing the URL to redirect and lose it's data.
1737
- $returnUrl = preg_replace('/([^:])(\/{2,})/', '$1/', $returnUrl);
1738
  mollieWooCommerceDebug("{$this->id} : Order {$orderId} returnUrl: {$returnUrl}", true);
1739
 
1740
  return apply_filters(Mollie_WC_Plugin::PLUGIN_ID . '_return_url', $returnUrl, $order);
@@ -1750,86 +1759,23 @@ abstract class Mollie_WC_Gateway_Abstract extends WC_Payment_Gateway
1750
  */
1751
  public function getWebhookUrl (WC_Order $order)
1752
  {
1753
- $siteUrl = get_home_url();
1754
-
1755
  $webhookUrl = WC()->api_request_url(strtolower(get_class($this)));
1756
  $webhookUrl = untrailingslashit($webhookUrl);
1757
- if (function_exists('idn_to_ascii')) {
1758
-
1759
- if (defined('IDNA_NONTRANSITIONAL_TO_ASCII') && defined('INTL_IDNA_VARIANT_UTS46')) {
1760
- $webhookUrl = idn_to_ascii($webhookUrl, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46);
1761
- } else {
1762
- $webhookUrl = idn_to_ascii($webhookUrl);
1763
- }
1764
- }
1765
  $orderId = $order->get_id();
1766
  $orderKey = $order->get_order_key();
1767
  $webhookUrl = $this->appendOrderArgumentsToUrl(
1768
- $orderId,
1769
- $orderKey,
1770
- $webhookUrl
1771
  );
1772
  $webhookUrl = untrailingslashit($webhookUrl);
1773
- $langUrl = $this->getSiteUrlWithLanguage();
1774
-
1775
- // Make sure there aren't any double /? in the URL (some (multilanguage) plugins will add this)
1776
- if ( strpos( $langUrl, '/?' ) !== false ) {
1777
- $langUrlParams = substr( $langUrl, strpos( $langUrl, "/?" ) + 2 );
1778
- $webhookUrl = $webhookUrl . '&' . $langUrlParams;
1779
- } else {
1780
- $webhookUrl = str_replace( $siteUrl, $langUrl, $webhookUrl );
1781
- }
1782
-
1783
- // Some (multilanguage) plugins will add a extra slash to the url (/nl//) causing the URL to redirect and lose it's data.
1784
- // Status updates via webhook will therefor not be processed. The below regex will find and remove those double slashes.
1785
- $webhookUrl = preg_replace('/([^:])(\/{2,})/', '$1/', $webhookUrl);
1786
 
1787
  mollieWooCommerceDebug("{$this->id} : Order {$orderId} webhookUrl: {$webhookUrl}", true);
1788
 
1789
  return apply_filters(Mollie_WC_Plugin::PLUGIN_ID . '_webhook_url', $webhookUrl, $order);
1790
  }
1791
 
1792
- /**
1793
- * Check if any multi language plugins are enabled and return the correct site url.
1794
- *
1795
- * @return string
1796
- */
1797
- protected function getSiteUrlWithLanguage() {
1798
- /**
1799
- * function is_plugin_active() is not available. Lets include it to use it.
1800
- */
1801
- include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
1802
-
1803
- $siteUrl = get_home_url();
1804
- $polylangFallback = false;
1805
-
1806
- if ( is_plugin_active( 'polylang/polylang.php' ) || is_plugin_active( 'polylang-pro/polylang.php' ) ) {
1807
-
1808
- $lang = PLL()->model->get_language( pll_current_language() );
1809
-
1810
-
1811
- if ( empty ( $lang->search_url ) ) {
1812
- $polylangFallback = true;
1813
- } else {
1814
- $polylangUrl = $lang->search_url;
1815
- $siteUrl = str_replace( $siteUrl,$polylangUrl, $siteUrl );
1816
- }
1817
- }
1818
-
1819
- if ( $polylangFallback == true || is_plugin_active( 'mlang/mlang.php' ) || is_plugin_active( 'mlanguage/mlanguage.php' ) ) {
1820
-
1821
- $slug = get_bloginfo( 'language' );
1822
- $pos = strpos( $slug, '-' );
1823
- if ( $pos !== false ) {
1824
- $slug = substr( $slug, 0, $pos );
1825
- }
1826
- $slug = '/' . $slug;
1827
- $siteUrl = str_replace( $siteUrl, $siteUrl . $slug, $siteUrl );
1828
- }
1829
-
1830
- return $siteUrl;
1831
- }
1832
-
1833
  /**
1834
  * @return string|NULL
1835
  */
@@ -2085,20 +2031,22 @@ abstract class Mollie_WC_Gateway_Abstract extends WC_Payment_Gateway
2085
  * @param $order_id
2086
  * @param $order_key
2087
  * @param $webhook_url
 
2088
  *
2089
  * @return string
2090
  */
2091
- protected function appendOrderArgumentsToUrl($order_id, $order_key, $webhook_url)
2092
  {
2093
  $webhook_url = add_query_arg(
2094
- array(
2095
- 'order_id' => $order_id,
2096
- 'key' => $order_key,
2097
- ),
2098
- $webhook_url
 
2099
  );
2100
  return $webhook_url;
2101
- }
2102
 
2103
  /**
2104
  * @param Mollie\Api\Resources\Payment|Mollie\Api\Resources\Order $payment
@@ -2294,11 +2242,12 @@ abstract class Mollie_WC_Gateway_Abstract extends WC_Payment_Gateway
2294
  *
2295
  * @param WC_Order $order
2296
  *
 
 
2297
  * @return string
2298
  */
2299
- protected function paymentTypeBasedOnProducts(WC_Order $order)
2300
  {
2301
- $molliePaymentType = 'order';
2302
  foreach ($order->get_items() as $cart_item) {
2303
  if ($cart_item['quantity']) {
2304
  do_action(
@@ -2565,16 +2514,187 @@ abstract class Mollie_WC_Gateway_Abstract extends WC_Payment_Gateway
2565
  return $paymentObject;
2566
  }
2567
 
2568
- protected function paymentTypeBasedOnGateway($paymentType)
2569
  {
 
 
 
2570
  $isBankTransferGateway = $this->id == 'mollie_wc_gateway_banktransfer';
2571
  if($isBankTransferGateway && $this->isExpiredDateSettingActivated()){
2572
  $paymentType = self::PAYMENT_METHOD_TYPE_PAYMENT;
2573
-
2574
  }
 
2575
  return $paymentType;
2576
  }
2577
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2578
 
 
 
 
 
 
 
 
 
 
 
2579
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2580
  }
97
  */
98
  public function init_form_fields()
99
  {
100
+ wp_register_script('mollie_wc_admin_settings', Mollie_WC_Plugin::getPluginUrl('/public/js/settings.min.js'), array('underscore','jquery'), Mollie_WC_Plugin::PLUGIN_VERSION);
101
+ wp_enqueue_script('mollie_wc_admin_settings');
102
+ global $current_section;
103
+
104
+ wp_localize_script(
105
+ 'mollie_wc_admin_settings',
106
+ 'mollieSettingsData',
107
+ [
108
+ 'current_section'=>$current_section
109
+ ]
110
+ );
111
+ $settingsHelper = Mollie_WC_Plugin::getSettingsHelper();
112
+ $this->form_fields = $settingsHelper->gatewayFormFields(
113
+ $this->getDefaultTitle(),
114
+ $this->getDefaultDescription(),
115
+ $this->paymentConfirmationAfterCoupleOfDays()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
  );
117
 
118
+ }
119
+
120
+ public function init_settings()
121
+ {
122
+ parent::init_settings();
123
+ if(is_admin()){
124
+ global $current_section;
125
+ wp_register_script(
126
+ 'mollie_wc_gateway_settings',
127
+ Mollie_WC_Plugin::getPluginUrl(
128
+ '/public/js/gatewaySettings.min.js'
129
+ ),
130
+ ['underscore', 'jquery'],
131
+ Mollie_WC_Plugin::PLUGIN_VERSION
132
+ );
133
+
134
+ wp_enqueue_script('mollie_wc_gateway_settings');
135
+ wp_enqueue_style('mollie-gateway-icons');
136
+ $settingsName = "{$current_section}_settings";
137
+ $gatewaySettings = get_option($settingsName, false);
138
+ $message = __('No custom logo selected', 'mollie-payments-for-woocommerce');
139
+ $isEnabled = false;
140
+ if($gatewaySettings && isset($gatewaySettings['enable_custom_logo'])){
141
+ $isEnabled = $gatewaySettings['enable_custom_logo'] === 'yes';
142
+ }
143
+ $uploadFieldName = "{$current_section}_upload_logo";
144
+ $enabledFieldName = "{$current_section}_enable_custom_logo";
145
+ $gatewayIconUrl = '';
146
+ if($gatewaySettings && isset($gatewaySettings['iconFileUrl'])){
147
+ $gatewayIconUrl = $gatewaySettings['iconFileUrl'];
148
+ }
149
+
150
+ wp_localize_script(
151
+ 'mollie_wc_gateway_settings',
152
+ 'gatewaySettingsData',
153
+ [
154
+ 'isEnabledIcon' => $isEnabled,
155
+ 'uploadFieldName' => $uploadFieldName,
156
+ 'enableFieldName' => $enabledFieldName,
157
+ 'iconUrl' => $gatewayIconUrl,
158
+ 'message'=>$message
159
+ ]
160
  );
161
  }
162
+
163
+
164
+ }
165
+ /**
166
+ * Save settings
167
+ *
168
+ * @since 1.0
169
+ */
170
+ /**
171
+ * Save options in admin.
172
+ */
173
+ public function process_admin_options()
174
+ {
175
+ if (isset($_POST['save']) ) {
176
+ $this->processAdminOptionCustomLogo();
177
+ $this->processAdminOptionSurcharge();
178
+ }
179
+ parent::process_admin_options();
180
  }
181
 
182
  /**
205
 
206
  protected function _initDescription ()
207
  {
208
+ $description = $this->buildDescriptionWithSurcharge();
209
 
210
  $this->description = $description;
211
  }
595
 
596
  }
597
 
598
+ $molliePaymentType = $this->paymentTypeBasedOnGateway();
599
+ $molliePaymentType = $this->paymentTypeBasedOnProducts($order,$molliePaymentType);
600
  try {
601
  $paymentObject = Mollie_WC_Plugin::getPaymentFactoryHelper()
602
  ->getPaymentObject(
1277
  *
1278
  * @return string
1279
  */
1280
+ public function getReturnRedirectUrlForOrder( WC_Order $order )
1281
  {
1282
  $order_id = $order->get_id();
1283
  $debugLine = __METHOD__ . " {$order_id}: Determine what the redirect URL in WooCommerce should be.";
1284
  mollieWooCommerceDebug($debugLine);
1285
  $hookReturnPaymentStatus = 'success';
1286
+ $returnRedirect = $this->get_return_url( $order );
1287
+ $failedRedirect = $order->get_checkout_payment_url( false );
1288
  if ( $this->orderNeedsPayment( $order ) ) {
1289
 
1290
+ $hasCancelledMolliePayment = $this->paymentObject()->getCancelledMolliePaymentId( $order_id );
1291
 
1292
+ if ( $hasCancelledMolliePayment ) {
1293
 
1294
+ $settings_helper = Mollie_WC_Plugin::getSettingsHelper();
1295
+ $order_status_cancelled_payments = $settings_helper->getOrderStatusCancelledPayments();
1296
 
1297
+ // If user set all cancelled payments to also cancel the order,
1298
+ // redirect to /checkout/order-received/ with a message about the
1299
+ // order being cancelled. Otherwise redirect to /checkout/order-pay/ so
1300
+ // customers can try to pay with another payment method.
1301
+ if ( $order_status_cancelled_payments == 'cancelled' ) {
1302
+ return $returnRedirect;
1303
 
1304
+ } else {
1305
+ Mollie_WC_Plugin::addNotice(
1306
+ __(
1307
+ 'You have cancelled your payment. Please complete your order with a different payment method.',
1308
+ 'mollie-payments-for-woocommerce'
1309
+ )
1310
+ );
 
 
 
1311
 
1312
+ // Return to order payment page
1313
+ return $failedRedirect;
1314
+ }
 
1315
 
1316
+ // Return to order payment page
1317
+ return $failedRedirect;
1318
+ }
1319
 
1320
  try {
1321
  $payment = $this->activePaymentObject($order_id, false);
1322
  if ( ! $payment->isOpen() && ! $payment->isPending() && ! $payment->isPaid() && ! $payment->isAuthorized() ) {
1323
  mollieWooCommerceNotice(__('Your payment was not successful. Please complete your order with a different payment method.', 'mollie-payments-for-woocommerce'));
1324
  // Return to order payment page
1325
+ return $failedRedirect;
 
 
1326
  }
1327
  if ($payment->method === "giftcard") {
1328
  $this->debugGiftcardDetails($payment, $order);
1335
  mollieWooCommerceDebug($debugLine);
1336
  $hookReturnPaymentStatus = 'failed';
1337
  }
1338
+ }
1339
  do_action( Mollie_WC_Plugin::PLUGIN_ID . '_customer_return_payment_' . $hookReturnPaymentStatus, $order );
1340
 
1341
+ /*
1342
+ * Return to order received page
1343
+ */
1344
+ return $returnRedirect;
1345
+ }
1346
  /**
1347
  * Retrieve the payment object
1348
  *
1721
 
1722
  /**
1723
  * Get the url to return to on Mollie return
1724
+ * saves the return redirect and failed redirect, so we save the page language in case there is one set
1725
  * For example 'http://mollie-wc.docker.myhost/wc-api/mollie_return/?order_id=89&key=wc_order_eFZyH8jki6fge'
1726
  *
1727
  * @param WC_Order $order The order processed
1730
  */
1731
  public function getReturnUrl (WC_Order $order)
1732
  {
1733
+ $returnUrl = $this->get_return_url($order);
1734
+ $returnUrl = untrailingslashit($returnUrl);
1735
+ $returnUrl = $this->asciiDomainName($returnUrl);
 
 
 
 
 
 
 
 
1736
  $orderId = $order->get_id();
1737
  $orderKey = $order->get_order_key();
1738
+ $onMollieReturn = 'onMollieReturn';
1739
  $returnUrl = $this->appendOrderArgumentsToUrl(
1740
+ $orderId,
1741
+ $orderKey,
1742
+ $returnUrl,
1743
+ $onMollieReturn
1744
  );
1745
  $returnUrl = untrailingslashit($returnUrl);
1746
+
 
 
 
 
 
 
 
 
 
 
1747
  mollieWooCommerceDebug("{$this->id} : Order {$orderId} returnUrl: {$returnUrl}", true);
1748
 
1749
  return apply_filters(Mollie_WC_Plugin::PLUGIN_ID . '_return_url', $returnUrl, $order);
1759
  */
1760
  public function getWebhookUrl (WC_Order $order)
1761
  {
 
 
1762
  $webhookUrl = WC()->api_request_url(strtolower(get_class($this)));
1763
  $webhookUrl = untrailingslashit($webhookUrl);
1764
+ $webhookUrl = $this->asciiDomainName($webhookUrl);
 
 
 
 
 
 
 
1765
  $orderId = $order->get_id();
1766
  $orderKey = $order->get_order_key();
1767
  $webhookUrl = $this->appendOrderArgumentsToUrl(
1768
+ $orderId,
1769
+ $orderKey,
1770
+ $webhookUrl
1771
  );
1772
  $webhookUrl = untrailingslashit($webhookUrl);
 
 
 
 
 
 
 
 
 
 
 
 
 
1773
 
1774
  mollieWooCommerceDebug("{$this->id} : Order {$orderId} webhookUrl: {$webhookUrl}", true);
1775
 
1776
  return apply_filters(Mollie_WC_Plugin::PLUGIN_ID . '_webhook_url', $webhookUrl, $order);
1777
  }
1778
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1779
  /**
1780
  * @return string|NULL
1781
  */
2031
  * @param $order_id
2032
  * @param $order_key
2033
  * @param $webhook_url
2034
+ * @param string $filterFlag
2035
  *
2036
  * @return string
2037
  */
2038
+ protected function appendOrderArgumentsToUrl($order_id, $order_key, $webhook_url, $filterFlag='')
2039
  {
2040
  $webhook_url = add_query_arg(
2041
+ array(
2042
+ 'order_id' => $order_id,
2043
+ 'key' => $order_key,
2044
+ 'filter_flag' => $filterFlag
2045
+ ),
2046
+ $webhook_url
2047
  );
2048
  return $webhook_url;
2049
+ }
2050
 
2051
  /**
2052
  * @param Mollie\Api\Resources\Payment|Mollie\Api\Resources\Order $payment
2242
  *
2243
  * @param WC_Order $order
2244
  *
2245
+ * @param string $molliePaymentType
2246
+ *
2247
  * @return string
2248
  */
2249
+ protected function paymentTypeBasedOnProducts(WC_Order $order, $molliePaymentType)
2250
  {
 
2251
  foreach ($order->get_items() as $cart_item) {
2252
  if ($cart_item['quantity']) {
2253
  do_action(
2514
  return $paymentObject;
2515
  }
2516
 
2517
+ protected function paymentTypeBasedOnGateway()
2518
  {
2519
+ $optionName = Mollie_WC_Plugin::PLUGIN_ID . '_' .'api_switch';
2520
+ $apiSwitchOption = get_option($optionName);
2521
+ $paymentType = $apiSwitchOption? $apiSwitchOption : self::PAYMENT_METHOD_TYPE_ORDER;
2522
  $isBankTransferGateway = $this->id == 'mollie_wc_gateway_banktransfer';
2523
  if($isBankTransferGateway && $this->isExpiredDateSettingActivated()){
2524
  $paymentType = self::PAYMENT_METHOD_TYPE_PAYMENT;
 
2525
  }
2526
+
2527
  return $paymentType;
2528
  }
2529
 
2530
+ protected function buildDescriptionWithSurcharge()
2531
+ {
2532
+ if(!mollieWooCommerceIsCheckoutContext()){
2533
+
2534
+ return $this->get_option('description', '');
2535
+ }
2536
+ if (!isset($this->settings['payment_surcharge'])
2537
+ || $this->settings['payment_surcharge']
2538
+ === Mollie_WC_Helper_GatewaySurchargeHandler::NO_FEE
2539
+ ){
2540
+ return $this->get_option('description', '');
2541
+ }
2542
+
2543
+ $surchargeType = $this->settings['payment_surcharge'];
2544
+ switch($surchargeType){
2545
+ case 'fixed_fee':
2546
+ $feeText = $this->name_fixed_fee();
2547
+ break;
2548
+ case 'percentage':
2549
+ $feeText = $this->name_percentage();
2550
+ break;
2551
+ case 'fixed_fee_percentage':
2552
+ $feeText = $this->name_fixed_fee_percentage();
2553
+ break;
2554
+ default:
2555
+ $feeText = false;
2556
+ }
2557
+ if($feeText){
2558
+ $feeLabel = '<span class="mollie-gateway-fee">' . $feeText . '</span>';
2559
+
2560
+ return $this->get_option('description', '') . $feeLabel;
2561
+ }
2562
+ return $this->get_option('description', '');
2563
+ }
2564
 
2565
+ protected function name_fixed_fee()
2566
+ {
2567
+ if (!isset($this->settings[Mollie_WC_Helper_GatewaySurchargeHandler::FIXED_FEE])
2568
+ || $this->settings[Mollie_WC_Helper_GatewaySurchargeHandler::FIXED_FEE] <= 0) {
2569
+ return false;
2570
+ }
2571
+ $amountFee = $this->settings[Mollie_WC_Helper_GatewaySurchargeHandler::FIXED_FEE];
2572
+ $currency = get_woocommerce_currency_symbol();
2573
+ return sprintf(__(" +%1s%2s Fee", 'mollie-payments-for-woocommerce'), $amountFee, $currency);
2574
+ }
2575
 
2576
+ protected function name_percentage()
2577
+ {
2578
+ if(!isset($this->settings[Mollie_WC_Helper_GatewaySurchargeHandler::PERCENTAGE])
2579
+ || $this->settings[Mollie_WC_Helper_GatewaySurchargeHandler::PERCENTAGE] <= 0){
2580
+ return false;
2581
+ }
2582
+ $amountFee = $this->settings[Mollie_WC_Helper_GatewaySurchargeHandler::PERCENTAGE];
2583
+ return sprintf(__(' +%1s%% Fee', 'mollie-payments-for-woocommerce'), $amountFee);
2584
+ }
2585
+
2586
+ protected function name_fixed_fee_percentage()
2587
+ {
2588
+ if (!isset($this->settings[Mollie_WC_Helper_GatewaySurchargeHandler::FIXED_FEE])
2589
+ || !isset($this->settings[Mollie_WC_Helper_GatewaySurchargeHandler::PERCENTAGE])
2590
+ || $this->settings[Mollie_WC_Helper_GatewaySurchargeHandler::FIXED_FEE] == ''
2591
+ || $this->settings[Mollie_WC_Helper_GatewaySurchargeHandler::PERCENTAGE] == ''
2592
+ || $this->settings[Mollie_WC_Helper_GatewaySurchargeHandler::PERCENTAGE] <= 0
2593
+ || $this->settings[Mollie_WC_Helper_GatewaySurchargeHandler::FIXED_FEE] <= 0
2594
+ ) {
2595
+ return false;
2596
+ }
2597
+ $amountFix = $this->settings[Mollie_WC_Helper_GatewaySurchargeHandler::FIXED_FEE];
2598
+ $currency = get_woocommerce_currency_symbol();
2599
+ $amountPercent = $this->settings[Mollie_WC_Helper_GatewaySurchargeHandler::PERCENTAGE];
2600
+ return sprintf(__(" +%1s%2s + %3s%% Fee", 'mollie-payments-for-woocommerce'), $amountFix, $currency, $amountPercent);
2601
+ }
2602
+
2603
+ protected function processAdminOptionCustomLogo()
2604
+ {
2605
+ $mollieUploadDirectory = trailingslashit(wp_upload_dir()['basedir'])
2606
+ . 'mollie-uploads/' . $this->id;
2607
+ wp_mkdir_p($mollieUploadDirectory);
2608
+ $targetLocation = $mollieUploadDirectory . '/';
2609
+ $fileOptionName = $this->id . '_upload_logo';
2610
+ $enabledLogoOptionName = $this->id . '_enable_custom_logo';
2611
+ $gatewaySettings = get_option("{$this->id}_settings", []);
2612
+ if (!isset($_POST[$enabledLogoOptionName])) {
2613
+ $gatewaySettings["iconFileUrl"] = null;
2614
+ $gatewaySettings["iconFilePath"] = null;
2615
+ update_option("{$this->id}_settings", $gatewaySettings);
2616
+ }
2617
+ if (isset($_POST[$enabledLogoOptionName])
2618
+ && isset($_FILES[$fileOptionName])
2619
+ && $_FILES[$fileOptionName]['size'] > 0
2620
+ ) {
2621
+ if ($_FILES[$fileOptionName]['size'] <= 500000) {
2622
+ $fileName = preg_replace(
2623
+ '/\s+/',
2624
+ '_',
2625
+ $_FILES[$fileOptionName]['name']
2626
+ );
2627
+ $tempName = $_FILES[$fileOptionName]['tmp_name'];
2628
+ move_uploaded_file($tempName, $targetLocation . $fileName);
2629
+ $gatewaySettings["iconFileUrl"] = trailingslashit(
2630
+ wp_upload_dir()['baseurl']
2631
+ ) . 'mollie-uploads/'. $this->id .'/'. $fileName;
2632
+ $gatewaySettings["iconFilePath"] = trailingslashit(
2633
+ wp_upload_dir()['basedir']
2634
+ ) . 'mollie-uploads/'. $this->id .'/'. $fileName;
2635
+ update_option("{$this->id}_settings", $gatewaySettings);
2636
+ } else {
2637
+ $notice = new Mollie_WC_Notice_AdminNotice();
2638
+ $message = sprintf(
2639
+ esc_html__(
2640
+ '%1$sMollie Payments for WooCommerce%2$s Unable to upload the file. Size must be under 500kb.',
2641
+ 'mollie-payments-for-woocommerce'
2642
+ ),
2643
+ '<strong>',
2644
+ '</strong>'
2645
+ );
2646
+ $notice->addNotice('notice-error is-dismissible', $message);
2647
+ }
2648
+ }
2649
+ }
2650
+
2651
+ protected function processAdminOptionSurcharge()
2652
+ {
2653
+ $paymentSurcharge = $this->id . '_payment_surcharge';
2654
+
2655
+ if (isset($_POST[$paymentSurcharge])
2656
+ && $_POST[$paymentSurcharge]
2657
+ !== Mollie_WC_Helper_GatewaySurchargeHandler::NO_FEE
2658
+ ) {
2659
+ $surchargeFields = [
2660
+ '_fixed_fee',
2661
+ '_percentage',
2662
+ '_surcharge_limit'
2663
+ ];
2664
+ foreach ($surchargeFields as $field) {
2665
+ $optionName = $this->id . $field;
2666
+ $validatedValue = isset($_POST[$optionName])
2667
+ && $_POST[$optionName] > 0
2668
+ && $_POST[$optionName] < 999;
2669
+ if (!$validatedValue) {
2670
+ unset($_POST[$optionName]);
2671
+ }
2672
+ }
2673
+ }
2674
+ }
2675
+
2676
+ /**
2677
+ * @param $url
2678
+ * @return string
2679
+ */
2680
+ protected function asciiDomainName($url)
2681
+ {
2682
+ if (function_exists('idn_to_ascii')) {
2683
+ $parsed = parse_url($url);
2684
+ $query = $parsed['query'];
2685
+ $url = str_replace('?' . $query, '', $url);
2686
+ if (defined('IDNA_NONTRANSITIONAL_TO_ASCII') && defined('INTL_IDNA_VARIANT_UTS46')) {
2687
+ $url = idn_to_ascii($url, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46) ? idn_to_ascii(
2688
+ $url,
2689
+ IDNA_NONTRANSITIONAL_TO_ASCII,
2690
+ INTL_IDNA_VARIANT_UTS46
2691
+ ) : $url;
2692
+ } else {
2693
+ $url = idn_to_ascii($url) ? idn_to_ascii($url) : $url;
2694
+ }
2695
+ $url = $url . '?' . $query;
2696
+ }
2697
+
2698
+ return $url;
2699
+ }
2700
  }
src/Mollie/WC/Gateway/AbstractSepaRecurring.php CHANGED
@@ -110,7 +110,7 @@ abstract class Mollie_WC_Gateway_AbstractSepaRecurring extends Mollie_WC_Gateway
110
  protected function getPaymentMethodTitle($payment)
111
  {
112
  $payment_method_title = parent::getPaymentMethodTitle($payment);
113
- $orderId = $payment->metadata->order_id;
114
  if ($orderId && Mollie_WC_Plugin::getDataHelper()->isWcSubscription($orderId) && $payment->method == $this->getRecurringMollieMethodId()){
115
  $payment_method_title = $this->getRecurringMollieMethodTitle();
116
  }
110
  protected function getPaymentMethodTitle($payment)
111
  {
112
  $payment_method_title = parent::getPaymentMethodTitle($payment);
113
+ $orderId = isset($payment->metadata) ? $payment->metadata->order_id : false;
114
  if ($orderId && Mollie_WC_Plugin::getDataHelper()->isWcSubscription($orderId) && $payment->method == $this->getRecurringMollieMethodId()){
115
  $payment_method_title = $this->getRecurringMollieMethodTitle();
116
  }
src/Mollie/WC/Gateway/Creditcard.php CHANGED
@@ -18,7 +18,8 @@ class Mollie_WC_Gateway_Creditcard extends Mollie_WC_Gateway_AbstractSubscriptio
18
  $this->hasFieldsIfMollieComponentsIsEnabled();
19
  }
20
 
21
- public function get_icon() {
 
22
  $url = Mollie_WC_Plugin::getPluginUrl(
23
  "public/images/creditcard.svg"
24
  );
@@ -30,8 +31,41 @@ class Mollie_WC_Gateway_Creditcard extends Mollie_WC_Gateway_AbstractSubscriptio
30
  ) {
31
  $output = $this->buildSvgComposed() ?: '';
32
  }
 
 
 
 
 
 
 
 
 
33
 
34
- return apply_filters( 'woocommerce_gateway_icon', $output, $this->id );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
  }
36
 
37
  /**
18
  $this->hasFieldsIfMollieComponentsIsEnabled();
19
  }
20
 
21
+ public function get_icon()
22
+ {
23
  $url = Mollie_WC_Plugin::getPluginUrl(
24
  "public/images/creditcard.svg"
25
  );
31
  ) {
32
  $output = $this->buildSvgComposed() ?: '';
33
  }
34
+ $gatewaySettings = $this->settings;
35
+ if ($this->canShowCustomLogo($gatewaySettings)) {
36
+ $url = $gatewaySettings["iconFileUrl"];
37
+ $output = '<img src="' . esc_attr($url)
38
+ . '" class="mollie-gateway-icon" />';
39
+ }
40
+
41
+ return apply_filters('woocommerce_gateway_icon', $output, $this->id);
42
+ }
43
 
44
+ protected function canShowCustomLogo($gatewaySettings)
45
+ {
46
+ if (!$gatewaySettings) {
47
+ return false;
48
+ }
49
+ if (!isset($gatewaySettings['enable_custom_logo'])
50
+ || $gatewaySettings['enable_custom_logo'] !== 'yes'
51
+ ) {
52
+ return false;
53
+ }
54
+ if (!isset($gatewaySettings['iconFileUrl'])
55
+ && !is_string(
56
+ $gatewaySettings['iconFileUrl']
57
+ )
58
+ ) {
59
+ return false;
60
+ }
61
+ if(!isset($gatewaySettings["iconFilePath"])){
62
+ return false;
63
+ }
64
+ $svgPath = $gatewaySettings["iconFilePath"];
65
+ if(! file_exists( $svgPath )){
66
+ return false;
67
+ }
68
+ return true;
69
  }
70
 
71
  /**
src/Mollie/WC/Helper/GatewaySurchargeHandler.php ADDED
@@ -0,0 +1,282 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Mollie_WC_Helper_GatewaySurchargeHandler
4
+ {
5
+ const NO_FEE = 'no_fee';
6
+ const FIXED_FEE = 'fixed_fee';
7
+ const PERCENTAGE = 'percentage';
8
+ const FIXED_AND_PERCENTAGE = 'fixed_fee_percentage';
9
+
10
+ /**
11
+ * Mollie_WC_Helper_ApplePayDirectHandler constructor.
12
+ */
13
+ public function __construct()
14
+ {
15
+ add_filter( 'woocommerce_cart_calculate_fees', [$this, 'add_engraving_fees'], 10, 1 );
16
+ add_action( 'wp_enqueue_scripts', [$this, 'enqueueSurchargeScript' ]);
17
+ add_action(
18
+ 'wp_ajax_' . 'update_surcharge_order_pay',
19
+ array($this, 'updateSurchargeOrderPay')
20
+ );
21
+ add_action(
22
+ 'wp_ajax_nopriv_' . 'update_surcharge_order_pay',
23
+ array($this, 'updateSurchargeOrderPay')
24
+ );
25
+ add_action( 'woocommerce_order_item_meta_end',[$this, 'setHiddenOrderId'], 10, 4);
26
+ }
27
+
28
+ public function setHiddenOrderId($item_id, $item, $order, $bool){
29
+ ?>
30
+ <input type="hidden" name="mollie-woocommerce-orderId" value="<?php echo $order->get_id() ?>">
31
+ <?php
32
+ }
33
+
34
+ public function enqueueSurchargeScript()
35
+ {
36
+ if (is_admin() || !mollieWooCommerceIsCheckoutContext()) {
37
+ return;
38
+ }
39
+ wp_enqueue_script('gatewaySurcharge');
40
+ wp_localize_script(
41
+ 'gatewaySurcharge',
42
+ 'surchargeData',
43
+ ['ajaxUrl' => admin_url('admin-ajax.php')]
44
+ );
45
+ }
46
+
47
+ public function updateSurchargeOrderPay(){
48
+ $orderId = isset($_POST['orderId'])?filter_var($_POST['orderId'], FILTER_SANITIZE_NUMBER_INT):false;
49
+ if(!$orderId){
50
+ return;
51
+ }
52
+ $order = wc_get_order($orderId);
53
+ if(!$order){
54
+ return;
55
+ }
56
+ $gateway = isset($_POST['method'])?filter_var($_POST['method'], FILTER_SANITIZE_STRING):false;
57
+ if (!$gateway) {
58
+ return;
59
+ }
60
+ if (!$this->isMollieGateway($gateway)) {
61
+ return;
62
+ }
63
+ $this->orderRemoveFee($order);
64
+ $gatewaySettings = $this->gatewaySettings($gateway);
65
+
66
+ if (!isset($gatewaySettings['payment_surcharge']) || $gatewaySettings['payment_surcharge'] == self::NO_FEE) {
67
+ $data= [
68
+ 'amount'=>false,
69
+ 'currency'=>get_woocommerce_currency_symbol(),
70
+ 'newTotal'=>$order->get_total()
71
+ ];
72
+ wp_send_json_success($data);
73
+ }
74
+
75
+ $amount = $this->calculteFeeAmountOrder($order, $gatewaySettings);
76
+ $surchargeName = $this->buildFeeName($gateway);
77
+
78
+
79
+ if($amount >0){
80
+ $this->orderAddFee($order, $amount, $surchargeName);
81
+ $order->calculate_totals();
82
+ $newTotal = $order->get_total();
83
+ $data= [
84
+ 'amount'=>$amount,
85
+ 'name'=>$surchargeName,
86
+ 'currency'=>get_woocommerce_currency_symbol(),
87
+ 'newTotal'=>$newTotal
88
+ ];
89
+ wp_send_json_success($data);
90
+ }
91
+ }
92
+
93
+ public function add_engraving_fees( $cart ) {
94
+
95
+ if (!mollieWooCommerceIsCheckoutContext()) {
96
+ return;
97
+ }
98
+
99
+ $gateway = $this->chosenGateway();
100
+ if (!$gateway) {
101
+ return;
102
+ }
103
+
104
+ $gatewaySettings = $this->gatewaySettings($gateway);
105
+ if (!isset($gatewaySettings['payment_surcharge']) || $gatewaySettings['payment_surcharge'] == self::NO_FEE) {
106
+ return;
107
+ }
108
+
109
+ $isRecurringCart = ! empty( $cart->recurring_cart_key );
110
+ if ($isRecurringCart) {
111
+ return;
112
+ }
113
+
114
+ $amount = $this->calculteFeeAmount($cart, $gatewaySettings);
115
+ $surchargeName = $this->buildFeeName($gateway);
116
+ $cart->add_fee( $surchargeName, $amount );
117
+ }
118
+
119
+ protected function chosenGateway()
120
+ {
121
+ $gateway = WC()->session->chosen_payment_method;
122
+ if ($gateway === '') {
123
+ $gateway = (!empty($_REQUEST['payment_method'])
124
+ ? sanitize_text_field(
125
+ wp_unslash($_REQUEST['payment_method'])
126
+ ) : '');
127
+ }
128
+
129
+ if (!$this->isMollieGateway($gateway)) {
130
+ return false;
131
+ }
132
+ return $gateway;
133
+ }
134
+
135
+ protected function isMollieGateway($gateway)
136
+ {
137
+ if (strpos($gateway, 'mollie_wc_gateway_') !== false) {
138
+ return true;
139
+ }
140
+ return false;
141
+ }
142
+
143
+ private function gatewaySettings($gateway)
144
+ {
145
+ $optionName = "{$gateway}_settings";
146
+ $allSettings = get_option($optionName, false);
147
+ if (!$allSettings) {
148
+ return false;
149
+ }
150
+
151
+ return $allSettings;
152
+ }
153
+
154
+ protected function calculteFeeAmount($cart, $gatewaySettings)
155
+ {
156
+ $surgargeType = $gatewaySettings['payment_surcharge'];
157
+ $methodName = "calculate_{$surgargeType}";
158
+
159
+ return $this->$methodName($cart, $gatewaySettings);
160
+ }
161
+
162
+ protected function calculteFeeAmountOrder($cart, $gatewaySettings)
163
+ {
164
+ $surchargeType = $gatewaySettings['payment_surcharge'];
165
+ switch ($surchargeType){
166
+ case 'fixed_fee':
167
+ return $this->calculate_fixed_fee($cart, $gatewaySettings);
168
+ case 'percentage':
169
+ return $this->calculate_percentage_order($cart, $gatewaySettings);
170
+ case 'fixed_fee_percentage':
171
+ return $this->calculate_fixed_fee_percentage_order($cart, $gatewaySettings);
172
+ }
173
+
174
+ return 0;
175
+ }
176
+
177
+ protected function calculate_fixed_fee($cart, $gatewaySettings)
178
+ {
179
+ return isset($gatewaySettings[self::FIXED_FEE])?(float) $gatewaySettings[self::FIXED_FEE]:0;
180
+ }
181
+
182
+ protected function calculate_percentage($cart, $gatewaySettings)
183
+ {
184
+ if(!isset($gatewaySettings[self::PERCENTAGE])){
185
+ return 0;
186
+ }
187
+ $percentageFee = $gatewaySettings[self::PERCENTAGE];
188
+ $subtotal = $cart->get_subtotal() + $cart->get_shipping_total() - $cart->get_discount_total();
189
+ $taxes = $cart->get_subtotal_tax() + $cart->get_shipping_tax() - $cart->get_discount_tax();
190
+ $total = $subtotal + $taxes;
191
+ $fee = $total * ($percentageFee / 100);
192
+
193
+ return $this->addMaxLimit($fee, $gatewaySettings);
194
+ }
195
+
196
+ protected function calculate_percentage_order($order, $gatewaySettings)
197
+ {
198
+ if(!isset($gatewaySettings[self::PERCENTAGE])){
199
+ return 0;
200
+ }
201
+ $percentageFee = $gatewaySettings[self::PERCENTAGE];
202
+ $total = $order->get_total();
203
+ $fee = $total * ($percentageFee / 100);
204
+
205
+ return $this->addMaxLimit($fee, $gatewaySettings);
206
+ }
207
+
208
+ protected function calculate_fixed_fee_percentage($cart, $gatewaySettings){
209
+ $fixedFee = $this->calculate_fixed_fee($cart, $gatewaySettings);
210
+ $percentageFee = $this->calculate_percentage($cart, $gatewaySettings);
211
+ $fee = $fixedFee + $percentageFee;
212
+
213
+ return $this->addMaxLimit($fee, $gatewaySettings);
214
+ }
215
+
216
+ protected function calculate_fixed_fee_percentage_order($cart, $gatewaySettings){
217
+ $fixedFee = $this->calculate_fixed_fee($cart, $gatewaySettings);
218
+ $percentageFee = $this->calculate_percentage_order($cart, $gatewaySettings);
219
+ $fee = $fixedFee + $percentageFee;
220
+
221
+ return $this->addMaxLimit($fee, $gatewaySettings);
222
+ }
223
+
224
+ /**
225
+ * @param string $gateway
226
+ *
227
+ * @return string
228
+ */
229
+ protected function buildFeeName($gateway)
230
+ {
231
+ $gatewayName = strtoupper(
232
+ str_replace('mollie_wc_gateway_', '', $gateway)
233
+ );
234
+ $notTranslated = "Mollie_WC_{$gatewayName} ";
235
+ $translated = __("Fee", 'mollie-payments-for-woocommerce');
236
+
237
+ return $notTranslated.$translated;
238
+ }
239
+
240
+ protected function addMaxLimit($fee, $gatewaySettings)
241
+ {
242
+ if (!isset($gatewaySettings['surcharge_limit'])
243
+ || $gatewaySettings['surcharge_limit'] == 0
244
+ ) {
245
+ return $fee;
246
+ }
247
+ $maxLimit = $gatewaySettings['surcharge_limit'];
248
+ if ($fee > $maxLimit) {
249
+ return $maxLimit;
250
+ }
251
+ return $fee;
252
+ }
253
+
254
+ /**
255
+ * @var wc_order $order
256
+ */
257
+ protected function orderRemoveFee($order)
258
+ {
259
+ $fees = $order->get_fees();
260
+ foreach ($fees as $fee){
261
+ $feeName = $fee->get_name();
262
+ $feeId = $fee->get_id();
263
+ if(strpos($feeName, 'Mollie_WC_') !== false){
264
+ $order->remove_item($feeId);
265
+ wc_delete_order_item( $feeId );
266
+ $order->calculate_totals();
267
+ }
268
+ }
269
+
270
+ }
271
+
272
+ protected function orderAddFee($order, $amount, $surchargeName)
273
+ {
274
+ $item_fee = new WC_Order_Item_Fee();
275
+ $item_fee->set_name( $surchargeName );
276
+ $item_fee->set_amount( $amount );
277
+ $item_fee->set_total( $amount );
278
+ $order->add_item( $item_fee );
279
+ $order->calculate_totals();
280
+ }
281
+ }
282
+
src/Mollie/WC/Helper/MaybeFixSubscription.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ class Mollie_WC_Helper_MaybeFixSubscription
5
+ {
6
+
7
+ public function maybeFix()
8
+ {
9
+ $fixSubscriptionsProcess = get_option('mollie_wc_fix_subscriptions', false);
10
+
11
+ $hasSubscriptionPlugin = function_exists('wcs_get_subscriptions');
12
+ $canSchedule = function_exists('as_schedule_single_action');
13
+ if (!$fixSubscriptionsProcess && $hasSubscriptionPlugin && $canSchedule) {
14
+ as_schedule_single_action(time(), 'runScheduledFix');
15
+ add_action('runScheduledFix', [$this, 'retrieveAndFixBrokenSubscriptions']);
16
+ }
17
+ }
18
+
19
+ public function retrieveAndFixBrokenSubscriptions()
20
+ {
21
+ $subscriptions = wcs_get_subscriptions(
22
+ [
23
+ 'subscriptions_per_page' => '-1',
24
+ 'meta_query' => [
25
+ 'relation' => 'OR',
26
+ [
27
+ 'key' => '_mollie_customer_id',
28
+ 'value' => '',
29
+ 'compare' => 'NOT EXISTS'
30
+ ]
31
+ ]
32
+ ]
33
+ );
34
+ foreach ($subscriptions as $subscription) {
35
+ $customer = $subscription->get_meta('_mollie_customer_id');
36
+ //cst_*
37
+ if (strlen($customer) < 5) {
38
+ $parent = $subscription->get_parent();
39
+ $subscription->update_meta_data('_mollie_customer_id', $parent->get_meta('_mollie_customer_id'));
40
+ $subscription->update_meta_data('_mollie_order_id', $parent->get_meta('_mollie_order_id'));
41
+ $subscription->update_meta_data('_mollie_payment_id', $parent->get_meta('_mollie_payment_id'));
42
+ $subscription->update_meta_data('_mollie_payment_mode', $parent->get_meta('_mollie_payment_mode'));
43
+ $subscription->save();
44
+ }
45
+ }
46
+ update_option('mollie_wc_fix_subscriptions', true);
47
+ }
48
+ }
49
+
src/Mollie/WC/Helper/PaymentMethodsIconUrl.php CHANGED
@@ -42,9 +42,20 @@ class Mollie_WC_Helper_PaymentMethodsIconUrl
42
  "public/images/{$paymentMethodName}s.svg"
43
  );
44
  }
45
- $svgUrl = Mollie_WC_Plugin::getPluginUrl(
46
- "public/images/{$paymentMethodName}" . self::SVG_FILE_EXTENSION
47
- );
 
 
 
 
 
 
 
 
 
 
 
48
 
49
  return '<img src="' . esc_attr($svgUrl)
50
  . '" class="mollie-gateway-icon" />';
42
  "public/images/{$paymentMethodName}s.svg"
43
  );
44
  }
45
+
46
+ $svgPath = false;
47
+ $gatewaySettings = get_option("mollie_wc_gateway_{$paymentMethodName}_settings", false);
48
+
49
+ if($gatewaySettings){
50
+ $svgPath = isset($gatewaySettings["iconFilePath"])?$gatewaySettings["iconFilePath"]:false;
51
+ $svgUrl = isset($gatewaySettings["iconFileUrl"])?$gatewaySettings["iconFileUrl"]:false;
52
+ }
53
+
54
+ if(! file_exists( $svgPath ) || !$svgUrl){
55
+ $svgUrl = Mollie_WC_Plugin::getPluginUrl(
56
+ "public/images/{$paymentMethodName}" . self::SVG_FILE_EXTENSION
57
+ );
58
+ }
59
 
60
  return '<img src="' . esc_attr($svgUrl)
61
  . '" class="mollie-gateway-icon" />';
src/Mollie/WC/Helper/Settings.php CHANGED
@@ -38,6 +38,212 @@ class Mollie_WC_Helper_Settings
38
  'lt_LT',
39
  ];
40
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
  /**
42
  * @return bool
43
  */
38
  'lt_LT',
39
  ];
40
 
41
+ public function gatewayFormFields(
42
+ $defaultTitle,
43
+ $defaultDescription,
44
+ $paymentConfirmation
45
+ ) {
46
+ $formFields = [
47
+ 'enabled' => [
48
+ 'title' => __(
49
+ 'Enable/Disable',
50
+ 'mollie-payments-for-woocommerce'
51
+ ),
52
+ 'type' => 'checkbox',
53
+ 'label' => sprintf(
54
+ __('Enable %s', 'mollie-payments-for-woocommerce'),
55
+ $defaultTitle
56
+ ),
57
+ 'default' => 'yes'
58
+ ],
59
+ 'title' => [
60
+ 'title' => __('Title', 'mollie-payments-for-woocommerce'),
61
+ 'type' => 'text',
62
+ 'description' => sprintf(
63
+ __(
64
+ 'This controls the title which the user sees during checkout. Default <code>%s</code>',
65
+ 'mollie-payments-for-woocommerce'
66
+ ),
67
+ $defaultTitle
68
+ ),
69
+ 'default' => $defaultTitle,
70
+ 'desc_tip' => true,
71
+ ],
72
+ 'display_logo' => [
73
+ 'title' => __(
74
+ 'Display logo',
75
+ 'mollie-payments-for-woocommerce'
76
+ ),
77
+ 'type' => 'checkbox',
78
+ 'label' => __(
79
+ 'Display logo on checkout page. Default <code>enabled</code>',
80
+ 'mollie-payments-for-woocommerce'
81
+ ),
82
+ 'default' => 'yes'
83
+ ],
84
+ 'enable_custom_logo' => [
85
+ 'title' => __(
86
+ 'Enable custom logo',
87
+ 'mollie-payments-for-woocommerce'
88
+ ),
89
+ 'type' => 'checkbox',
90
+ 'label' => __(
91
+ 'Enable the feature to add a custom logo for this gateway. This feature will have precedence over other logo options.',
92
+ 'mollie-payments-for-woocommerce'
93
+ )
94
+ ],
95
+ 'upload_logo' => [
96
+ 'title' => __(
97
+ 'Upload custom logo',
98
+ 'mollie-payments-for-woocommerce'
99
+ ),
100
+ 'type' => 'file',
101
+ 'custom_attributes'=>['accept'=>'.png, .jpeg, .svg, image/png, image/jpeg'],
102
+ 'description' => sprintf(
103
+ __(
104
+ 'Upload a custom icon for this gateway. The feature must be enabled.',
105
+ 'mollie-payments-for-woocommerce'
106
+ )
107
+ ),
108
+ 'desc_tip' => true,
109
+ ],
110
+ 'description' => [
111
+ 'title' => __('Description', 'mollie-payments-for-woocommerce'),
112
+ 'type' => 'textarea',
113
+ 'description' => sprintf(
114
+ __(
115
+ 'Payment method description that the customer will see on your checkout. Default <code>%s</code>',
116
+ 'mollie-payments-for-woocommerce'
117
+ ),
118
+ $defaultDescription
119
+ ),
120
+ 'default' => $defaultDescription,
121
+ 'desc_tip' => true,
122
+ ],
123
+ 'allowed_countries' => [
124
+ 'title' => __(
125
+ 'Sell to specific countries',
126
+ 'mollie-payments-for-woocommerce'
127
+ ),
128
+ 'desc' => '',
129
+ 'css' => 'min-width: 350px;',
130
+ 'default' => [],
131
+ 'type' => 'multi_select_countries',
132
+ ],
133
+ 'payment_surcharge' => [
134
+ 'title' => __(
135
+ 'Payment Surcharge',
136
+ 'mollie-payments-for-woocommerce'
137
+ ),
138
+ 'type' => 'select',
139
+ 'options' => [
140
+ Mollie_WC_Helper_GatewaySurchargeHandler::NO_FEE => __(
141
+ 'No fee',
142
+ 'mollie-payments-for-woocommerce'
143
+ ),
144
+ Mollie_WC_Helper_GatewaySurchargeHandler::FIXED_FEE => __(
145
+ 'Fixed fee',
146
+ 'mollie-payments-for-woocommerce'
147
+ ),
148
+ Mollie_WC_Helper_GatewaySurchargeHandler::PERCENTAGE => __(
149
+ 'Percentage',
150
+ 'mollie-payments-for-woocommerce'
151
+ ),
152
+ Mollie_WC_Helper_GatewaySurchargeHandler::FIXED_AND_PERCENTAGE => __(
153
+ 'Fixed fee and percentage',
154
+ 'mollie-payments-for-woocommerce'
155
+ ),
156
+ ],
157
+ 'default' => 'no_fee',
158
+ 'description' => __(
159
+ 'Choose a payment surcharge for this gateway',
160
+ 'mollie-payments-for-woocommerce'
161
+ ),
162
+ 'desc_tip' => true,
163
+ ],
164
+ 'fixed_fee' => [
165
+ 'title' => sprintf(__('Payment surcharge fixed amount in %s', 'mollie-payments-for-woocommerce'), html_entity_decode( get_woocommerce_currency_symbol() )),
166
+ 'type' => 'number',
167
+ 'description' => sprintf(
168
+ __(
169
+ 'Control the fee added on checkout. Default 0.01',
170
+ 'mollie-payments-for-woocommerce'
171
+ )
172
+ ),
173
+ 'custom_attributes'=>['step'=>'0.01', 'min'=>'0.01', 'max'=>'999'],
174
+ 'default' => '0.01',
175
+ 'desc_tip' => true,
176
+ ],
177
+ 'percentage' => [
178
+ 'title' => __('Payment surcharge percentage amount %', 'mollie-payments-for-woocommerce'),
179
+ 'type' => 'number',
180
+ 'description' => sprintf(
181
+ __(
182
+ 'Control the percentage fee added on checkout. Default 0.01',
183
+ 'mollie-payments-for-woocommerce'
184
+ )
185
+ ),
186
+ 'custom_attributes'=>['step'=>'0.01', 'min'=>'0.01', 'max'=>'999'],
187
+ 'default' => '0.01',
188
+ 'desc_tip' => true,
189
+ ],
190
+ 'surcharge_limit' => [
191
+ 'title' => sprintf(__('Payment surcharge limit in %s', 'mollie-payments-for-woocommerce'), html_entity_decode( get_woocommerce_currency_symbol())),
192
+ 'type' => 'number',
193
+ 'description' => sprintf(
194
+ __(
195
+ 'Limit the maximum fee added on checkout. Default 0',
196
+ 'mollie-payments-for-woocommerce'
197
+ )
198
+ ),
199
+ 'custom_attributes'=>['step'=>'0.01', 'min'=>'0.01', 'max'=>'999'],
200
+ 'default' => '0.01',
201
+ 'desc_tip' => true,
202
+ ],
203
+ ];
204
+
205
+ if ($paymentConfirmation) {
206
+ $formFields['initial_order_status'] = [
207
+ 'title' => __(
208
+ 'Initial order status',
209
+ 'mollie-payments-for-woocommerce'
210
+ ),
211
+ 'type' => 'select',
212
+ 'options' => [
213
+ Mollie_WC_Gateway_Abstract::STATUS_ON_HOLD => wc_get_order_status_name(
214
+ Mollie_WC_Gateway_Abstract::STATUS_ON_HOLD
215
+ ) . ' (' . __(
216
+ 'default',
217
+ 'mollie-payments-for-woocommerce'
218
+ ) . ')',
219
+ Mollie_WC_Gateway_Abstract::STATUS_PENDING => wc_get_order_status_name(
220
+ Mollie_WC_Gateway_Abstract::STATUS_PENDING
221
+ ),
222
+ ],
223
+ 'default' => Mollie_WC_Gateway_Abstract::STATUS_ON_HOLD,
224
+ /* translators: Placeholder 1: Default order status, placeholder 2: Link to 'Hold Stock' setting */
225
+ 'description' => sprintf(
226
+ __(
227
+ 'Some payment methods take longer than a few hours to complete. The initial order state is then set to \'%s\'. This ensures the order is not cancelled when the setting %s is used.',
228
+ 'mollie-payments-for-woocommerce'
229
+ ),
230
+ wc_get_order_status_name(
231
+ Mollie_WC_Gateway_Abstract::STATUS_ON_HOLD
232
+ ),
233
+ '<a href="' . admin_url(
234
+ 'admin.php?page=wc-settings&tab=products&section=inventory'
235
+ ) . '" target="_blank">' . __(
236
+ 'Hold Stock (minutes)',
237
+ 'woocommerce'
238
+ ) . '</a>'
239
+ ),
240
+ ];
241
+ }
242
+
243
+
244
+ return $formFields;
245
+ }
246
+
247
  /**
248
  * @return bool
249
  */
src/Mollie/WC/Payment/Payment.php CHANGED
@@ -37,7 +37,9 @@ class Mollie_WC_Payment_Payment extends Mollie_WC_Payment_Object {
37
  public function getPaymentRequestData($order, $customerId)
38
  {
39
  $settingsHelper = Mollie_WC_Plugin::getSettingsHelper();
40
- $paymentDescription = 'Order ' . $order->get_order_number();
 
 
41
  $paymentLocale = $settingsHelper->getPaymentLocale();
42
  $storeCustomer = $settingsHelper->shouldStoreCustomer();
43
 
@@ -118,6 +120,33 @@ class Mollie_WC_Payment_Payment extends Mollie_WC_Payment_Object {
118
  return $paymentRequestData;
119
  }
120
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
121
  public function setActiveMolliePayment($orderId)
122
  {
123
  self::$paymentId = $this->getMolliePaymentIdFromPaymentObject();
37
  public function getPaymentRequestData($order, $customerId)
38
  {
39
  $settingsHelper = Mollie_WC_Plugin::getSettingsHelper();
40
+ $optionName = Mollie_WC_Plugin::PLUGIN_ID . '_' .'api_payment_description';
41
+ $option = get_option($optionName);
42
+ $paymentDescription = $this->getPaymentDescription($order, $option);
43
  $paymentLocale = $settingsHelper->getPaymentLocale();
44
  $storeCustomer = $settingsHelper->shouldStoreCustomer();
45
 
120
  return $paymentRequestData;
121
  }
122
 
123
+ protected function getPaymentDescription($order, $option)
124
+ {
125
+ switch ($option) {
126
+ case '{orderNumber}':
127
+ $description = 'Order ' . $order->get_order_number();
128
+ break;
129
+ case '{storeName}':
130
+ $description = 'StoreName ' . get_bloginfo('name');
131
+ break;
132
+ case '{customer.firstname}':
133
+ $description = 'Customer Firstname '
134
+ . $order->get_billing_first_name();
135
+ break;
136
+ case '{customer.lastname}':
137
+ $description = 'Customer Lastname '
138
+ . $order->get_billing_last_name();
139
+ break;
140
+ case '{customer.company}':
141
+ $description = 'Customer Company '
142
+ . $order->get_billing_company();
143
+ break;
144
+ default:
145
+ $description = 'Order ' . $order->get_order_number();
146
+ }
147
+ return $description;
148
+ }
149
+
150
  public function setActiveMolliePayment($orderId)
151
  {
152
  self::$paymentId = $this->getMolliePaymentIdFromPaymentObject();
src/Mollie/WC/Payment/RefundLineItemsBuilder.php CHANGED
@@ -100,6 +100,11 @@ class Mollie_WC_Payment_RefundLineItemsBuilder
100
  ? $toRefundRemoteItem->unitPrice->value
101
  : 0;
102
 
 
 
 
 
 
103
  if ($toRefundItemAmount <= 0 || $toRefundItemQuantity < 1 || $toRefundRemoteItemPrice <= 0) {
104
  return [];
105
  }
100
  ? $toRefundRemoteItem->unitPrice->value
101
  : 0;
102
 
103
+ //as in Woo if the quantity is 0 but there is an amount, then quantity is 1
104
+ if($toRefundItemQuantity < 1 && $toRefundItemAmount > 0){
105
+ $toRefundItemQuantity = 1;
106
+ }
107
+
108
  if ($toRefundItemAmount <= 0 || $toRefundItemQuantity < 1 || $toRefundRemoteItemPrice <= 0) {
109
  return [];
110
  }
src/Mollie/WC/Plugin.php CHANGED
@@ -8,7 +8,7 @@ class Mollie_WC_Plugin
8
  {
9
  const PLUGIN_ID = 'mollie-payments-for-woocommerce';
10
  const PLUGIN_TITLE = 'Mollie Payments for WooCommerce';
11
- const PLUGIN_VERSION = '6.2.2';
12
 
13
  const DB_VERSION = '1.0';
14
  const DB_VERSION_PARAM_NAME = 'mollie-db-version';
@@ -210,6 +210,7 @@ class Mollie_WC_Plugin
210
 
211
  // Listen to return URL call
212
  add_action( 'woocommerce_api_mollie_return', array ( __CLASS__, 'onMollieReturn' ) );
 
213
 
214
  // Show Mollie instructions on order details page
215
  add_action( 'woocommerce_order_details_after_order_table', array ( __CLASS__, 'onOrderDetails' ), 10, 1 );
@@ -271,16 +272,29 @@ class Mollie_WC_Plugin
271
  });
272
  add_action('wp_loaded', [__CLASS__, 'maybeTestModeNotice']);
273
  self::mollieApplePayDirectHandling();
 
274
 
275
  self::initDb();
276
  self::schedulePendingPaymentOrdersExpirationCheck();
277
  self::registerFrontendScripts();
278
  wp_enqueue_style('mollie-gateway-icons');
 
279
 
280
  // Mark plugin initiated
281
  self::$initiated = true;
282
  }
283
 
 
 
 
 
 
 
 
 
 
 
 
284
 
285
  public static function maybeTestModeNotice()
286
  {
@@ -717,6 +731,13 @@ class Mollie_WC_Plugin
717
  filemtime(Mollie_WC_Plugin::getPluginPath('/public/css/unabledButton.min.css')),
718
  'screen'
719
  );
 
 
 
 
 
 
 
720
  }
721
 
722
  /**
@@ -845,8 +866,10 @@ class Mollie_WC_Plugin
845
 
846
  return $order;
847
  }
 
848
  /**
849
- * Payment return url callback
 
850
  */
851
  public static function onMollieReturn ()
852
  {
@@ -885,6 +908,21 @@ class Mollie_WC_Plugin
885
  mollieWooCommerceDebug(__METHOD__ . ": Redirect url on return order {$gateway->id}, order {$orderId}: {$redirect_url}");
886
 
887
  wp_safe_redirect($redirect_url);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
888
  }
889
 
890
  /**
8
  {
9
  const PLUGIN_ID = 'mollie-payments-for-woocommerce';
10
  const PLUGIN_TITLE = 'Mollie Payments for WooCommerce';
11
+ const PLUGIN_VERSION = '6.3.0';
12
 
13
  const DB_VERSION = '1.0';
14
  const DB_VERSION_PARAM_NAME = 'mollie-db-version';
210
 
211
  // Listen to return URL call
212
  add_action( 'woocommerce_api_mollie_return', array ( __CLASS__, 'onMollieReturn' ) );
213
+ add_action( 'template_redirect', array ( __CLASS__, 'mollieReturnRedirect' ) );
214
 
215
  // Show Mollie instructions on order details page
216
  add_action( 'woocommerce_order_details_after_order_table', array ( __CLASS__, 'onOrderDetails' ), 10, 1 );
272
  });
273
  add_action('wp_loaded', [__CLASS__, 'maybeTestModeNotice']);
274
  self::mollieApplePayDirectHandling();
275
+ self::gatewaySurchargeHandling();
276
 
277
  self::initDb();
278
  self::schedulePendingPaymentOrdersExpirationCheck();
279
  self::registerFrontendScripts();
280
  wp_enqueue_style('mollie-gateway-icons');
281
+ self::maybeFixSubscriptions();
282
 
283
  // Mark plugin initiated
284
  self::$initiated = true;
285
  }
286
 
287
+ public static function gatewaySurchargeHandling(){
288
+ $gatewaSurchargeHandler = new Mollie_WC_Helper_GatewaySurchargeHandler();
289
+ }
290
+ /**
291
+ * See MOL-322
292
+ */
293
+ public static function maybeFixSubscriptions(){
294
+ $fixer = new Mollie_WC_Helper_MaybeFixSubscription();
295
+ $fixer->maybeFix();
296
+ }
297
+
298
 
299
  public static function maybeTestModeNotice()
300
  {
731
  filemtime(Mollie_WC_Plugin::getPluginPath('/public/css/unabledButton.min.css')),
732
  'screen'
733
  );
734
+ wp_register_script(
735
+ 'gatewaySurcharge',
736
+ Mollie_WC_Plugin::getPluginUrl('/public/js/gatewaySurcharge.min.js'),
737
+ ['underscore', 'jquery'],
738
+ filemtime(Mollie_WC_Plugin::getPluginPath('/public/js/gatewaySurcharge.min.js')),
739
+ true
740
+ );
741
  }
742
 
743
  /**
866
 
867
  return $order;
868
  }
869
+
870
  /**
871
+ * Old Payment return url callback
872
+ *
873
  */
874
  public static function onMollieReturn ()
875
  {
908
  mollieWooCommerceDebug(__METHOD__ . ": Redirect url on return order {$gateway->id}, order {$orderId}: {$redirect_url}");
909
 
910
  wp_safe_redirect($redirect_url);
911
+ die;
912
+ }
913
+
914
+ /**
915
+ * New Payment return url callback
916
+ *
917
+ */
918
+ public static function mollieReturnRedirect()
919
+ {
920
+ if (isset($_GET['filter_flag'])) {
921
+ $filterFlag = filter_input(INPUT_GET, 'filter_flag', FILTER_SANITIZE_STRING);
922
+ if ($filterFlag === 'onMollieReturn') {
923
+ self::onMollieReturn();
924
+ }
925
+ }
926
  }
927
 
928
  /**