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 +319 -110 1.2.2 → 3.1.0 View file →
@@ -1,12 +1,13 @@
1 1 <?php
2 2
3 3 namespace Payplug\PayplugWoocommerce\Gateway;
4 4
5 -use Payplug\PayplugWoocommerce\PayplugWoocommerceHelper;
6 -use Payplug\Authentication;
7 5 use libphonenumber\PhoneNumberType;
8 6 use libphonenumber\PhoneNumberUtil;
7 +use Payplug\PayplugWoocommerce\Controller\PayplugGenericGateway;
8 +use Payplug\PayplugWoocommerce\Gateway\Oney\OneyAccountMapper;
9 +use Payplug\PayplugWoocommerce\PayplugWoocommerceHelper;
9 10
10 11 // Exit if accessed directly
11 12 if (!defined('ABSPATH')) {
12 13 exit;
@@ -13,45 +14,83 @@
13 14 }
14 15
15 16 /**
16 17 * PayPlug WooCommerce Gateway.
17 - *
18 - * @package Payplug\PayplugWoocommerce\Gateway
19 18 */
20 -class PayplugGatewayOney3x extends PayplugGateway
19 +class PayplugGatewayOney3x extends PayplugGenericGateway
21 20 {
22 - const ONEY_UNAVAILABLE_CODE_COUNTRY_NOT_ALLOWED = 2;
23 - const ONEY_UNAVAILABLE_CODE_CART_SIZE_TOO_HIGH = 3;
24 - const ONEY_PRODUCT_QUANTITY_MAXIMUM = 1000;
21 + public const ONEY_UNAVAILABLE_CODE_COUNTRY_NOT_ALLOWED = 2;
22 + public const ONEY_UNAVAILABLE_CODE_CART_SIZE_TOO_HIGH = 3;
23 + public const ONEY_DISALBE_CHECKOUT_OPTIONS = 4;
25 24
25 + public const ONEY_PRODUCT_QUANTITY_MAXIMUM = 1000;
26 +
26 27 protected $oney_response;
27 - protected $min_oney_price;
28 - protected $max_oney_price;
29 - protected $allowed_country_codes;
28 + public const ENABLE_ON_TEST_MODE = true;
30 29
30 + public $allowed_country_codes = [];
31 +
31 32 public function __construct()
32 33 {
33 34 parent::__construct();
34 - $this->id = 'oney_x3_with_fees';
35 - $this->method_title = _x('PayPlug Oney 3x', 'Gateway method title', 'payplug');
35 + $this->id = 'oney_x3_with_fees';
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 - $this->title = __('Pay by card in 3x with Oney', 'payplug');
38 + $this->title = __('Pay by card in 3x with Oney', 'payplug');
39 + $this->has_fields = true;
38 40
39 - if (is_admin()) {
40 - wp_register_style('payplug-admin-oney', PAYPLUG_GATEWAY_PLUGIN_URL . 'assets/css/payplug-admin-oney.css', [], PAYPLUG_GATEWAY_VERSION);
41 - wp_enqueue_style('payplug-admin-oney');
41 + add_action('woocommerce_order_item_add_action_buttons', [$this, 'oney_refund_text']);
42 + add_action('woocommerce_after_checkout_validation', [$this, 'validate_checkout'], 10);
43 +
44 + self::set_oney_configuration();
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';
42 51 }
43 52
44 - add_action('woocommerce_order_item_add_action_buttons', [$this, 'oney_refund_text']);
53 + if (is_checkout()) {
54 + if ($this->check_oney_is_available() === self::ONEY_DISALBE_CHECKOUT_OPTIONS) {
55 + $this->enabled = 'no';
56 + }
57 + }
58 + }
45 59
46 - try {
47 - $http_response = Authentication::getAccount();
48 - $oney_configuration = $http_response['httpResponse']['configuration']['oney'];
49 - $this->min_oney_price = $oney_configuration['min_amounts']['EUR']/100;
50 - $this->max_oney_price = $oney_configuration['max_amounts']['EUR']/100;
60 + public function validate_checkout(): void
61 + {
62 + $posted_data = $this->get_post_data();
63 +
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)) {
70 + if ($this->check_oney_is_available() === self::ONEY_UNAVAILABLE_CODE_COUNTRY_NOT_ALLOWED) {
71 + throw new \Exception(__('Unavailable for the specified country.'));
72 + } elseif ($this->check_oney_is_available() === self::ONEY_UNAVAILABLE_CODE_CART_SIZE_TOO_HIGH) {
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));
74 + } elseif (!$this->check_oney_is_available()) {
75 + throw new \Exception(sprintf(__('The total amount of your order should be between %s€ and %s€ to pay with Oney.', 'payplug'), $this->oney_thresholds_min, $this->oney_thresholds_max));
76 + }
77 + }
78 + }
79 +
80 + /**
81 + * Set oney settings
82 + *
83 + * @return void
84 + */
85 + private function set_oney_configuration(): void
86 + {
87 + $account = PayplugWoocommerceHelper::get_account_data_from_options();
88 + if ($account) {
89 + $oney_configuration = $account['configuration']['oney'];
90 + $this->min_oney_price = $oney_configuration['min_amounts']['EUR'] / 100;
91 + $this->max_oney_price = $oney_configuration['max_amounts']['EUR'] / 100;
51 92 $this->allowed_country_codes = $oney_configuration['allowed_countries'];
52 - } catch ( \Payplug\Exception\UnauthorizedException $e ) {
53 - } catch ( \Payplug\Exception\ConfigurationNotSetException $e ) {
54 93 }
55 94 }
56 95
57 96 /**
@@ -60,79 +99,169 @@
60 99 * @return string
61 100 */
62 101 public function get_icon()
63 102 {
103 + $disable = $this->check_oney_is_available() === true ? '' : 'disable-checkout-icons';
104 + $available_img = 'x3_with_fees.svg';
64 105
65 - if ($this->check_oney_is_available() === true) {
66 - $total_price = floatval(WC()->cart->total);
67 - $this->oney_response = $this->api->simulate_oney_payment($total_price);
68 - $currency = get_woocommerce_currency_symbol(get_option('woocommerce_currency'));
69 - $f = function ($fn) {
70 - return $fn;
71 - };
72 - $this->description = <<<HTML
73 - <p>
74 - <div class="payplug-oney-flex">
75 - <div>{$f(__('Bring', 'payplug'))} :</div>
76 - <div>{$this->oney_response['x3_with_fees']['down_payment_amount']} {$currency}</div>
77 - </div>
78 - <div class="payplug-oney-flex">
79 - <div>{$f(__('1st monthly payment', 'payplug'))} :</div>
80 - <div>{$this->oney_response['x3_with_fees']['installments'][0]['amount']} {$currency}</div>
81 - </div>
82 - <div class="payplug-oney-flex">
83 - <div>{$f(__('2nd monthly payment', 'payplug'))} :</div>
84 - <div>{$this->oney_response['x3_with_fees']['installments'][1]['amount']} {$currency}</div>
85 - </div>
86 - </p>
87 -HTML;
88 - $available_img = 'lg-3xoney-checkout.png';
89 - } else {
90 - $available_img = 'lg-3xoney-checkout-disabled.png';
91 - }
92 -
93 106 $icons = apply_filters('payplug_payment_icons', [
94 - 'payplug' => sprintf('<img src="%s" alt="Oney 3x" class="payplug-payment-icon" />', esc_url(PAYPLUG_GATEWAY_PLUGIN_URL . '/assets/images/' . $available_img)),
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)),
95 108 ]);
96 109 $icons_str = '';
97 110 foreach ($icons as $icon) {
98 111 $icons_str .= $icon;
99 112 }
113 +
100 114 return $icons_str;
101 115 }
102 116
103 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 + /**
104 158 * Check if Oney is available
105 - *
106 - * @return void
159 + *
160 + * @return bool|int true, false, or an ONEY_* status code
107 161 */
108 162 public function check_oney_is_available()
109 163 {
164 + static $is_running = false;
165 + if ($is_running) {
166 + return false;
167 + }
168 + $is_running = true;
169 + try {
170 + $result = $this->do_check_oney_is_available();
171 + } finally {
172 + $is_running = false;
173 + }
110 174
175 + return $result;
176 + }
177 +
178 + private function do_check_oney_is_available()
179 + {
111 180 $cart = WC()->cart;
181 +
182 + //for backend orders
183 + if (!empty(get_query_var('order-pay'))) {
184 + $order = wc_get_order(get_query_var('order-pay'));
185 +
186 + //wc_get_order @return bool|WC_Order|WC_Order_Refund
187 + if ($order === false) {
188 + return false;
189 + }
190 +
191 + $items = $order->get_items();
192 +
193 + $country_code_shipping = $order->get_shipping_country();
194 + $country_code_billing = $order->get_billing_country();
195 +
196 + // Skip cart population for subscription renewals: WC Subscriptions manages the cart
197 + // itself and adding items here would cause a double entry in the order summary.
198 + $is_renewal = function_exists('wcs_order_contains_renewal') && wcs_order_contains_renewal($order);
199 + if (!$is_renewal) {
200 + $this->order_items_to_cart($cart, $items);
201 + }
202 + }
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 +
219 + if (empty($cart->total)) {
220 + return false;
221 + }
222 +
223 + if (empty($cart->cart_contents_count)) {
224 + return false;
225 + }
226 +
112 227 $total_price = floatval($cart->total);
113 - $products_qty = (int) $cart->cart_contents_count;
114 -
115 - // Min and max
116 - if ($total_price < $this->min_oney_price || $total_price > $this->max_oney_price) {
117 - $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'), $this->min_oney_price, $this->max_oney_price).'</div>';
228 + $products_qty = (int) $cart->cart_contents_count;
229 +
230 + // Min and max
231 + if ($total_price < $oney_amount['min'] || $total_price > $oney_amount['max']) {
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>';
233 +
118 234 return false;
119 235 }
120 236
121 237 // Cart check
122 238 if ($products_qty >= self::ONEY_PRODUCT_QUANTITY_MAXIMUM) {
123 - $this->description = '<div class="payment_method_oney_x3_with_fees_disabled">'.sprintf(__('The payment with Oney is unavailable because you have more than %s items in your cart.', 'payplug'), self::ONEY_PRODUCT_QUANTITY_MAXIMUM).'</div>';
239 + $this->description = '<div class="payment_method_oney_x3_with_fees_disabled">' . sprintf(__('The payment with Oney is unavailable because you have more than %s items in your cart.', 'payplug'), self::ONEY_PRODUCT_QUANTITY_MAXIMUM) . '</div>';
240 +
124 241 return self::ONEY_UNAVAILABLE_CODE_CART_SIZE_TOO_HIGH;
125 242 }
126 243
127 244 // Country check
128 - $country_code_shipping = WC()->customer->get_shipping_country();
129 - $country_code_billing = WC()->customer->get_billing_country();
130 - if (!in_array($country_code_billing, $this->allowed_country_codes) || !in_array($country_code_shipping, $this->allowed_country_codes)) {
131 - $this->description = '<div class="payment_method_oney_x3_with_fees_disabled">'.__('Unavailable for the specified country.', 'payplug').'</div>';
132 - return self::ONEY_UNAVAILABLE_CODE_COUNTRY_NOT_ALLOWED;
245 + if (empty($country_code_shipping) || empty($country_code_shipping)) {
246 + $country_code_shipping = WC()->customer->get_shipping_country();
247 + $country_code_billing = WC()->customer->get_billing_country();
133 248 }
134 249
250 + //WOOC-663 exception for the description to be visible
251 + //billing allowed?
252 + if ($this->allowed_country($country_code_billing, $this->allowed_country_codes)) {
253 +
254 + //if shipping is different from billing and billing is accepted
255 + if (!$this->validate_shipping_billing_country($country_code_shipping, $country_code_billing)) {
256 + $this->description = '<div class="payment_method_oney_x3_with_fees_disabled">' . __('Unavailable for the specified country.', 'payplug') . '</div>';
257 +
258 + return self::ONEY_UNAVAILABLE_CODE_COUNTRY_NOT_ALLOWED;
259 + }
260 + } else {
261 + return self::ONEY_DISALBE_CHECKOUT_OPTIONS;
262 + }
263 +
135 264 return true;
136 265 }
137 266
138 267 /**
@@ -158,10 +287,11 @@
158 287 * @param \WC_Order $order
159 288 * @param int $amount
160 289 * @param int $customer_id
161 290 *
291 + * @throws \Exception
292 + *
162 293 * @return array
163 - * @throws \Exception
164 294 */
165 295 public function process_standard_payment($order, $amount, $customer_id)
166 296 {
167 297 $order_id = PayplugWoocommerceHelper::is_pre_30() ? $order->id : $order->get_id();
@@ -175,25 +305,31 @@
175 305 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));
176 306 }
177 307
178 308 $country = PayplugWoocommerceHelper::is_pre_30() ? $order->billing_country : $order->get_billing_country();
179 - $phone = PayplugWoocommerceHelper::is_pre_30() ? $order->billing_phone : $order->get_billing_phone();
180 - $billing_email = PayplugWoocommerceHelper::is_pre_30() ? $order->billing_email : $order->get_billing_email();
309 + $phone = PayplugWoocommerceHelper::is_pre_30() ? $order->billing_phone : $order->get_billing_phone();
310 + $billing_email = PayplugWoocommerceHelper::is_pre_30() ? $order->billing_email : $order->get_billing_email();
181 311 $phone_number_util = PhoneNumberUtil::getInstance();
182 - $phone_number = $phone_number_util->parse( $phone, $country );
183 - if ( PhoneNumberType::MOBILE !== $phone_number_util->getNumberType( $phone_number ) ) {
312 + $phone_number = $phone_number_util->parse($phone, $country);
313 + if (PhoneNumberType::MOBILE !== $phone_number_util->getNumberType($phone_number)) {
184 314 throw new \Exception(__('Mobile phone number fullfilled is invalid. Please retry.', 'payplug'));
185 315 }
186 -
187 - if (!filter_var($billing_email, FILTER_VALIDATE_EMAIL) || strpos($billing_email,'+') !== false) {
188 - throw new \Exception(__("Your email address is too long and the + character is not valid, please change it to another address (max 100 characters).", 'payplug'));
316 +
317 + if (!filter_var($billing_email, FILTER_VALIDATE_EMAIL) || strpos($billing_email, '+') !== false) {
318 + throw new \Exception(__('Your email address is too long and the + character is not valid, please change it to another address (max 100 characters).', 'payplug'));
189 319 }
190 320
191 321 $address_data = PayplugAddressData::from_order($order);
192 322
323 + $return_url = esc_url_raw($order->get_checkout_order_received_url());
324 +
325 + if (!(substr($return_url, 0, 4) === 'http')) {
326 + $return_url = get_site_url() . $return_url;
327 + }
328 +
193 329 $cart_items = [];
194 330 $items = $order->get_items();
195 - foreach($items as $item) {
331 + foreach ($items as $item) {
196 332 $data = $item->get_data();
197 333 $total = floatval(round($data['total'], 2)) * 100;
198 334 $cart_items[] = [
199 335 'delivery_label' => 'storepickup',
@@ -198,39 +334,44 @@
198 334 $cart_items[] = [
199 335 'delivery_label' => 'storepickup',
200 336 'delivery_type' => 'storepickup',
201 337 'brand' => 'Woocommerce',
202 - 'merchant_item_id' => 'cart-'.$data['id'].'-'.$data['product_id'],
338 + 'merchant_item_id' => 'cart-' . $data['id'] . '-' . $data['product_id'],
203 339 'name' => $data['name'],
204 340 'expected_delivery_date' => date('Y-m-d'),
205 - 'total_amount' => $total,
206 - 'price' => round($total / $data['quantity']),
207 - 'quantity' => $data['quantity']
341 + 'total_amount' => (int) $total,
342 + 'price' => round($total / $data['quantity']),
343 + 'quantity' => $data['quantity'],
208 344 ];
209 345 }
210 346
211 347 $payment_data = [
212 348 'authorized_amount' => $amount,
213 - 'auto_capture' => true,
214 - 'currency' => get_woocommerce_currency(),
215 - 'payment_method' => $this->id,
216 - 'billing' => $address_data->get_billing(),
217 - 'shipping' => $address_data->get_shipping(),
218 - 'payment_context' => [
219 - "cart" => $cart_items
349 + 'auto_capture' => true,
350 + 'currency' => get_woocommerce_currency(),
351 + 'payment_method' => $this->id,
352 + 'billing' => $address_data->get_billing(),
353 + 'shipping' => $address_data->get_shipping(),
354 + 'payment_context' => [
355 + 'cart' => $cart_items,
220 356 ],
221 357 'notification_url' => esc_url_raw(WC()->api_request_url('PayplugGateway')),
222 - 'hosted_payment' => [
223 - 'return_url' => esc_url_raw($order->get_checkout_order_received_url()),
358 + 'hosted_payment' => [
359 + 'return_url' => $return_url,
224 360 'cancel_url' => esc_url_raw($order->get_cancel_order_url_raw()),
225 361 ],
226 - 'metadata' => [
227 - 'order_id' => $order_id,
362 + 'metadata' => [
363 + 'order_id' => $order_id,
228 364 'customer_id' => ((int) $customer_id > 0) ? $customer_id : 'guest',
229 - 'domain' => $this->limit_length(esc_url_raw(home_url()), 500),
365 + 'domain' => $this->limit_length(esc_url_raw(home_url()), 500),
230 366 ],
231 367 ];
232 368
369 + if (PayplugWoocommerceHelper::is_checkout_block() && is_checkout()) {
370 + $payment_data['metadata']['woocommerce_block'] = 'CHECKOUT';
371 + } elseif (PayplugWoocommerceHelper::is_cart_block() && is_cart()) {
372 + $payment_data['metadata']['woocommerce_block'] = 'CART';
373 + }
233 374
234 375 /**
235 376 * Filter the payment data before it's used
236 377 *
@@ -239,9 +380,9 @@
239 380 * @param array $customer_details
240 381 * @param PayplugAddressData $address_data
241 382 */
242 383 $payment_data = apply_filters('payplug_gateway_payment_data', $payment_data, $order_id, [], $address_data);
243 - $payment = $this->api->payment_create($payment_data);
384 + $payment = $this->payplug_api->payment_create($payment_data);
244 385
245 386 // Save transaction id for the order
246 387 PayplugWoocommerceHelper::is_pre_30()
247 388 ? update_post_meta($order_id, '_transaction_id', $payment->id)
@@ -264,11 +405,11 @@
264 405
265 406 PayplugGateway::log(sprintf('Payment creation complete for order #%s', $order_id));
266 407
267 408 return [
268 - 'result' => 'success',
409 + 'result' => 'success',
269 410 'redirect' => $payment->hosted_payment->payment_url,
270 - 'cancel' => $payment->hosted_payment->cancel_url,
411 + 'cancel' => $payment->hosted_payment->cancel_url,
271 412 ];
272 413 } catch (\HttpException $e) {
273 414 PayplugGateway::log(sprintf('Error while processing order #%s : %s', $order_id, wc_print_r($e->getErrorObject(), true)), 'error');
274 415 throw new \Exception(__($e->getMessage(), 'payplug'));
@@ -277,48 +418,116 @@
277 418 throw new \Exception(__($e->getMessage(), 'payplug'));
278 419 }
279 420 }
280 421
281 -
282 422 /**
283 - * Check if the gatteway is allowed for the order amount
423 + * Check if the gatteway is allowed for the order amount
284 424 *
285 425 * @param array
426 + *
286 427 * @return array
287 428 */
288 429 public function check_gateway($gateways)
289 430 {
290 431 if (isset($gateways[$this->id]) && $gateways[$this->id]->id == $this->id) {
291 - if(!PayplugWoocommerceHelper::is_oney_available()) {
432 + //remove gateway if thresholds/country criteria are not met
433 + if ($this->check_oney_is_available() === false) {
292 434 unset($gateways[$this->id]);
293 435 }
436 +
437 + //remove gateway if account doesn't have permission
438 + if (!PayplugWoocommerceHelper::is_oney_available()) {
439 + unset($gateways[$this->id]);
440 + } else {
441 + $gateways = parent::check_gateway($gateways);
442 + }
294 443 }
444 +
295 445 return $gateways;
296 446 }
297 447
298 448 /**
299 449 * Show Oney refund text
300 - *
450 + *
301 451 * @return void
302 452 */
303 - public function oney_refund_text($order)
453 + public function oney_refund_text($order): void
304 454 {
305 - if ($this->id === $order->get_payment_method() && parent::can_refund_order($order) && $order->get_status() !== "refunded") {
455 + if ($this->id === $order->get_payment_method() && parent::can_refund_order($order) && $order->get_status() !== 'refunded' && $this->payplug_api) {
306 456 $order_metadata = $order->get_meta('_payplug_metadata');
307 - $payment = $this->api->payment_retrieve($order_metadata['transaction_id']);
308 - $today = current_time('Y-m-d H:i:s');
309 - $can_refund_date = date('Y-m-d H:i:s', $payment->__get('refundable_after'));
310 - if ($can_refund_date >= $today) {
311 - echo "<p style='color: red;'>" . __('Refund will be possible 48 hours after the last payment or refund transaction.', 'payplug') . "</p>";
457 +
458 + if (is_array($order_metadata) && !empty($order_metadata['transaction_id'])) {
459 + try {
460 + $payment = $this->payplug_api->payment_retrieve($order_metadata['transaction_id']);
461 + $today = current_time('Y-m-d H:i:s');
462 + $can_refund_date = date('Y-m-d H:i:s', $payment->__get('refundable_after'));
463 + if ($can_refund_date >= $today) {
464 + echo "<p style='color: red;'>" . __('Refund will be possible 48 hours after the last payment or refund transaction.', 'payplug') . '</p>';
465 + }
466 + } catch (\Exception $e) {
467 + PayplugGateway::log(sprintf('Could not retrieve refundable_after for Oney order: %s', $e->getMessage()), 'error');
468 + }
312 469 }
313 470 }
314 471 }
315 472
316 - public function payment_fields()
473 + /**
474 + * Billing and shipping addresses should have the same country and allowed by Oney
475 + * https://payplug-prod.atlassian.net/browse/WOOC-227
476 + *
477 + * @param $order
478 + *
479 + * @return bool
480 + */
481 + public function validate_shipping_billing_country($shipping_country, $billing_country)
317 482 {
318 - $description = $this->get_description();
319 - if (!empty($description)) {
320 - echo wpautop(wptexturize($description));
483 + if ($billing_country === $shipping_country) {
484 + return true;
321 485 }
486 +
487 + return false;
322 488 }
323 489
490 + /**
491 + * Country of billing or shipping at oney payments should be on the allowedCountry that comes from pauyplug-api /account
492 + *
493 + * @param string $country
494 + * @param array $allowed
495 + *
496 + * @return bool
497 + */
498 + public function allowed_country($country, $allowed)
499 + {
500 + if (in_array($country, $allowed)) {
501 + return true;
502 + }
503 +
504 + return false;
505 + }
506 +
507 + /**
508 + * Empty the cart and add all order_items
509 + *
510 + * @param $cart
511 + * @param $items
512 + *
513 + * @return void
514 + */
515 + private function order_items_to_cart($cart, $items): void
516 + {
517 + $cart->empty_cart();
518 + foreach ($items as $item) {
519 + $cart->add_to_cart($item->get_product_id(), $item->get_quantity(), $item->get_variation_id());
520 + }
521 + }
522 +
523 + public function checkGateway()
524 + {
525 + $options = PayplugWoocommerceHelper::get_payplug_options();
526 +
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;
532 + }
324 533 }