PluginProbe
PayPlug for WooCommerce (Official) / 3.1.0
PayPlug for WooCommerce (Official) v3.1.0
3.1.0 3.0.0 2.18.0 1.0.17 1.0.18 1.0.19 1.0.20 1.0.21 1.0.22 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.1.0 1.10.0 1.10.1 1.2.1 1.2.10 1.2.11 1.2.2 1.2.3 1.2.4 1.2.5 All 102 releases
← All changes | src/Gateway/PayplugGatewayOney3x.php +76 -60 3.0.0 → 3.1.0 View file →
@@ -4,8 +4,9 @@
4 4
5 5 use libphonenumber\PhoneNumberType;
6 6 use libphonenumber\PhoneNumberUtil;
7 7 use Payplug\PayplugWoocommerce\Controller\PayplugGenericGateway;
8 +use Payplug\PayplugWoocommerce\Gateway\Oney\OneyAccountMapper;
8 9 use Payplug\PayplugWoocommerce\PayplugWoocommerceHelper;
9 10
10 11 // Exit if accessed directly
11 12 if (!defined('ABSPATH')) {
@@ -34,9 +35,9 @@
34 35 $this->id = 'oney_x3_with_fees';
35 36 $this->method_title = _x('PayPlug Oney 3x', 'Gateway method title', 'payplug');
36 37 $this->method_description = __('Enable PayPlug Oney 3x for your customers.', 'payplug');
37 38 $this->title = __('Pay by card in 3x with Oney', 'payplug');
38 - $this->has_fields = false;
39 + $this->has_fields = true;
39 40
40 41 add_action('woocommerce_order_item_add_action_buttons', [$this, 'oney_refund_text']);
41 42 add_action('woocommerce_after_checkout_validation', [$this, 'validate_checkout'], 10);
42 43
@@ -41,8 +42,15 @@
41 42 add_action('woocommerce_after_checkout_validation', [$this, 'validate_checkout'], 10);
42 43
43 44 self::set_oney_configuration();
44 45
46 + // Unlike the other sub-gateways (Bancontact, AmericanExpress, PPRO methods...), Oney never
47 + // synced $this->enabled with the plugin's own "active" toggle, so disabling Oney from the
48 + // Payplug config left it shown as enabled on WooCommerce's native Payments settings page.
49 + if (!$this->checkGateway()) {
50 + $this->enabled = 'no';
51 + }
52 +
45 53 if (is_checkout()) {
46 54 if ($this->check_oney_is_available() === self::ONEY_DISALBE_CHECKOUT_OPTIONS) {
47 55 $this->enabled = 'no';
48 56 }
@@ -52,9 +60,14 @@
52 60 public function validate_checkout(): void
53 61 {
54 62 $posted_data = $this->get_post_data();
55 63
56 - if (in_array($posted_data['payment_method'], ['oney_x3_with_fees","oney_x4_with_fees", "oney_x3_without_fees", "oney_x4_without_fees'])) {
64 + // Was a single malformed string (missing quotes around each id) instead of a 4-element
65 + // array, so this guard never matched and the whole method was a silent no-op (PRE-3457
66 + // review / PRE-3457 follow-up fix).
67 + $oney_gateway_ids = ['oney_x3_with_fees', 'oney_x4_with_fees', 'oney_x3_without_fees', 'oney_x4_without_fees'];
68 +
69 + if (in_array($posted_data['payment_method'] ?? '', $oney_gateway_ids, true)) {
57 70 if ($this->check_oney_is_available() === self::ONEY_UNAVAILABLE_CODE_COUNTRY_NOT_ALLOWED) {
58 71 throw new \Exception(__('Unavailable for the specified country.'));
59 72 } elseif ($this->check_oney_is_available() === self::ONEY_UNAVAILABLE_CODE_CART_SIZE_TOO_HIGH) {
60 73 throw new \Exception(sprintf(__('The payment with Oney is unavailable because you have more than %s items in your cart.', 'payplug'), self::ONEY_PRODUCT_QUANTITY_MAXIMUM));
@@ -86,52 +99,9 @@
86 99 * @return string
87 100 */
88 101 public function get_icon()
89 102 {
90 - $disable = '';
91 - if ($this->check_oney_is_available() === true) {
92 - $total_price = floatval(WC()->cart->total);
93 - $this->oney_response = $this->payplug_api->simulate_oney_payment($total_price, 'with_fees');
94 - $currency = get_woocommerce_currency_symbol(get_option('woocommerce_currency'));
95 - $total_price_oney = floatval($this->oney_response['x3_with_fees']['down_payment_amount']);
96 - foreach ($this->oney_response['x3_with_fees']['installments'] as $installment) {
97 - $total_price_oney = $total_price_oney + floatval($installment['amount']);
98 - }
99 - $f = fn ($fn) => $fn;
100 -
101 - $tax_cost = floatval($this->oney_response['x3_with_fees']['total_cost']) / 100;
102 -
103 - if (is_array($this->oney_response)) {
104 - $this->description = <<<HTML
105 - <p>
106 - <div class="payplug-oney-flex">
107 - <div>{$f(__('Bring', 'payplug'))}:</div>
108 - <div>{$this->oney_response['x3_with_fees']['down_payment_amount']} {$currency}</div>
109 - </div>
110 - <div class="payplug-oney-flex">
111 - <small>( {$f(__('oney_financing_cost', 'payplug'))} <b>{$tax_cost} {$currency}</b> TAEG : <b>{$this->oney_response['x3_with_fees']['effective_annual_percentage_rate']} %</b> )</small>
112 - </div>
113 - <div class="payplug-oney-flex">
114 - <div>{$f(__('1st monthly payment', 'payplug'))}:</div>
115 - <div>{$this->oney_response['x3_with_fees']['installments'][0]['amount']} {$currency}</div>
116 - </div>
117 - <div class="payplug-oney-flex">
118 - <div>{$f(__('2nd monthly payment', 'payplug'))}:</div>
119 - <div>{$this->oney_response['x3_with_fees']['installments'][1]['amount']} {$currency}</div>
120 - </div>
121 - <div class="payplug-oney-flex">
122 - <div><b>{$f(__('oney_total', 'payplug'))}</b></div>
123 - <div><b>{$total_price_oney} {$currency}</b></div>
124 - </div>
125 - </p>
126 -HTML;
127 - } else {
128 - $this->description = $this->oney_response;
129 - }
130 - } else {
131 - $disable = 'disable-checkout-icons';
132 - }
133 -
103 + $disable = $this->check_oney_is_available() === true ? '' : 'disable-checkout-icons';
134 104 $available_img = 'x3_with_fees.svg';
135 105
136 106 $icons = apply_filters('payplug_payment_icons', [
137 107 'payplug' => sprintf('<img src="%s" alt="Oney 3x" class="payplug-payment-icon ' . $disable . '" />', esc_url(PAYPLUG_GATEWAY_PLUGIN_URL . '/assets/images/checkout/' . $available_img)),
@@ -144,8 +114,48 @@
144 114 return $icons_str;
145 115 }
146 116
147 117 /**
118 + * Render the placeholder + config the official Oney widget uses to display the inline
119 + * payment-schedule section for this specific gateway (checkout obligation).
120 + */
121 + public function payment_fields(): void
122 + {
123 + if ($this->check_oney_is_available() !== true) {
124 + // check_oney_is_available() sets $this->description with the reason Oney can't be used.
125 + $description = $this->get_description();
126 +
127 + if (!empty($description)) {
128 + echo wpautop(wptexturize($description));
129 + }
130 +
131 + return;
132 + }
133 +
134 + $account = PayplugWoocommerceHelper::get_account_data_from_options();
135 + $oney_settings = $this->get_configuration()->get_option('payment_methods.configuration.oney');
136 + $country = PayplugWoocommerceHelper::getISOCountryCode();
137 + $mapper = OneyAccountMapper::map((array) $account, $oney_settings, $country);
138 + $code = $mapper->business_transaction_code_for_gateway($this->id);
139 +
140 + if (!$mapper->is_enabled() || !$code) {
141 + return;
142 + }
143 +
144 + printf(
145 + '<div id="oney-checkout-loading-%1$s" class="payplug-lds-roller"><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div><div id="oney-checkout-%1$s"></div><script type="application/json" id="oney-checkout-config-%1$s">%2$s</script>',
146 + esc_attr($this->id),
147 + wp_json_encode([
148 + 'merchant_guid' => $mapper->get_merchant_guid(),
149 + 'business_transaction_code' => $code,
150 + 'country' => $country,
151 + 'language' => strtoupper(substr(get_locale(), 0, 2)),
152 + 'payment_amount' => floatval(WC()->cart->total),
153 + ])
154 + );
155 + }
156 +
157 + /**
148 158 * Check if Oney is available
149 159 *
150 160 * @return bool|int true, false, or an ONEY_* status code
151 161 */
@@ -190,8 +200,23 @@
190 200 $this->order_items_to_cart($cart, $items);
191 201 }
192 202 }
193 203
204 + $oney_cfg = $this->get_configuration()->get_option('payment_methods.configuration.oney');
205 + $account = PayplugWoocommerceHelper::get_account_data_from_options();
206 + $oney_account_cfg = ((array) $account)['configuration']['oney'] ?? [];
207 + // Same clamping OneyAccountMapper::map() uses for the badge/widget display, so
208 + // checkout validation and display never silently drift apart (PRE-3457 review).
209 + [$min_cents, $max_cents] = OneyAccountMapper::effective_bounds($oney_account_cfg, $oney_cfg);
210 + $oney_amount = [
211 + 'min' => $min_cents / 100,
212 + 'max' => $max_cents / 100,
213 + ];
214 + // validate_checkout() reads these to build its exception message - populate them
215 + // unconditionally (before any early return below) so they're never stale/unset there.
216 + $this->oney_thresholds_min = $oney_amount['min'];
217 + $this->oney_thresholds_max = $oney_amount['max'];
218 +
194 219 if (empty($cart->total)) {
195 220 return false;
196 221 }
197 222
@@ -201,13 +226,8 @@
201 226
202 227 $total_price = floatval($cart->total);
203 228 $products_qty = (int) $cart->cart_contents_count;
204 229
205 - $oney_cfg = $this->get_configuration()->get_option('payment_methods.configuration.oney');
206 - $oney_amount = json_decode($oney_cfg['custom_amounts'], true);
207 - $oney_amount['min'] = (float) $oney_amount['min'] / 100;
208 - $oney_amount['max'] = (float) $oney_amount['max'] / 100;
209 -
210 230 // Min and max
211 231 if ($total_price < $oney_amount['min'] || $total_price > $oney_amount['max']) {
212 232 $this->description = '<div class="payment_method_oney_x3_with_fees_disabled">' . sprintf(__('The total amount of your order should be between %s€ and %s€ to pay with Oney.', 'payplug'), $oney_amount['min'], $oney_amount['max']) . '</div>';
213 233
@@ -449,16 +469,8 @@
449 469 }
450 470 }
451 471 }
452 472
453 - public function payment_fields(): void
454 - {
455 - $description = $this->get_description();
456 - if (!empty($description)) {
457 - echo wpautop(wptexturize($description));
458 - }
459 - }
460 -
461 473 /**
462 474 * Billing and shipping addresses should have the same country and allowed by Oney
463 475 * https://payplug-prod.atlassian.net/browse/WOOC-227
464 476 *
@@ -511,7 +523,11 @@
511 523 public function checkGateway()
512 524 {
513 525 $options = PayplugWoocommerceHelper::get_payplug_options();
514 526
515 - return empty($options) || !isset($options['payment_methods']) ? false : $options['payment_methods']['configuration']['oney']['active'];
527 + // Now called unconditionally from the constructor (not just at checkout via
528 + // is_available()), so a legacy account whose stored config predates the oney block
529 + // (never went through Upgrade::run_upgrade()) would otherwise throw "undefined array
530 + // key" warnings on every admin page that builds the WC gateway list (PRE-3597 review).
531 + return $options['payment_methods']['configuration']['oney']['active'] ?? false;
516 532 }
517 533 }