PluginProbe
PayPlug for WooCommerce (Official) / 1.10.1
PayPlug for WooCommerce (Official) v1.10.1
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
payplug / src / Gateway / PayplugGatewayOney3x.php

PayplugGatewayOney3x.php in PayPlug for WooCommerce (Official) 1.10.1, at src/Gateway/PayplugGatewayOney3x.php

438 lines 16.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Payplug\PayplugWoocommerce\Gateway;
4
5 use Payplug\PayplugWoocommerce\PayplugWoocommerceHelper;
6 use Payplug\Authentication;
7 use libphonenumber\PhoneNumberType;
8 use libphonenumber\PhoneNumberUtil;
9
10 // Exit if accessed directly
11 if (!defined('ABSPATH')) {
12 exit;
13 }
14
15 /**
16 * PayPlug WooCommerce Gateway.
17 *
18 * @package Payplug\PayplugWoocommerce\Gateway
19 */
20 class PayplugGatewayOney3x extends PayplugGateway
21 {
22 const OPTION_NAME = "payplug_oney_config";
23 const ONEY_UNAVAILABLE_CODE_COUNTRY_NOT_ALLOWED = 2;
24 const ONEY_UNAVAILABLE_CODE_CART_SIZE_TOO_HIGH = 3;
25 const ONEY_PRODUCT_QUANTITY_MAXIMUM = 1000;
26
27 protected $oney_response;
28 protected $min_oney_price;
29 protected $max_oney_price;
30 protected $allowed_country_codes = [];
31
32 public function __construct()
33 {
34 parent::__construct();
35 $this->id = 'oney_x3_with_fees';
36 $this->method_title = _x('PayPlug Oney 3x', 'Gateway method title', 'payplug');
37 $this->method_description = __('Enable PayPlug Oney 3x for your customers.', 'payplug');
38 $this->title = __('Pay by card in 3x with Oney', 'payplug');
39
40 if (is_admin()) {
41 wp_register_style('payplug-admin-oney', PAYPLUG_GATEWAY_PLUGIN_URL . 'assets/css/payplug-admin-oney.css', [], PAYPLUG_GATEWAY_VERSION);
42 wp_enqueue_style('payplug-admin-oney');
43 }
44
45 add_action('woocommerce_order_item_add_action_buttons', [$this, 'oney_refund_text']);
46
47 if (is_checkout()) {
48 PayplugWoocommerceHelper::set_account_data_from_options();
49 }
50
51 self::set_oney_configuration();
52
53 }
54
55 /**
56 * Set oney settings
57 *
58 * @return void
59 */
60 private function set_oney_configuration()
61 {
62 $account = PayplugWoocommerceHelper::get_account_data_from_options();
63 if ($account) {
64 $oney_configuration = $account['configuration']['oney'];
65 $this->min_oney_price = $oney_configuration['min_amounts']['EUR'] / 100;
66 $this->max_oney_price = $oney_configuration['max_amounts']['EUR'] / 100;
67 $this->allowed_country_codes = $oney_configuration['allowed_countries'];
68 }
69 }
70
71 /**
72 * Get payment icons.
73 *
74 * @return string
75 */
76 public function get_icon()
77 {
78 if ($this->check_oney_is_available() === true) {
79 $total_price = floatval(WC()->cart->total);
80 $this->oney_response = $this->api->simulate_oney_payment($total_price, 'with_fees');
81 $currency = get_woocommerce_currency_symbol(get_option('woocommerce_currency'));
82 $f = function ($fn) {
83 return $fn;
84 };
85 if(is_array($this->oney_response)) {
86 $this->description = <<<HTML
87 <p>
88 <div class="payplug-oney-flex">
89 <div>{$f(__('Bring', 'payplug'))}:</div>
90 <div>{$this->oney_response['x3_with_fees']['down_payment_amount']} {$currency}</div>
91 </div>
92 <div class="payplug-oney-flex">
93 <div>{$f(__('1st monthly payment', 'payplug'))}:</div>
94 <div>{$this->oney_response['x3_with_fees']['installments'][0]['amount']} {$currency}</div>
95 </div>
96 <div class="payplug-oney-flex">
97 <div>{$f(__('2nd monthly payment', 'payplug'))}:</div>
98 <div>{$this->oney_response['x3_with_fees']['installments'][1]['amount']} {$currency}</div>
99 </div>
100 </p>
101 HTML;
102 } else {
103 $this->description = $this->oney_response;
104 }
105
106 $available_img = 'lg-3xoney-checkout.png';
107 } else {
108 $available_img = 'lg-3xoney-checkout-disabled.png';
109 }
110
111 $icons = apply_filters('payplug_payment_icons', [
112 'payplug' => sprintf('<img src="%s" alt="Oney 3x" class="payplug-payment-icon" />', esc_url(PAYPLUG_GATEWAY_PLUGIN_URL . '/assets/images/' . $available_img)),
113 ]);
114 $icons_str = '';
115 foreach ($icons as $icon) {
116 $icons_str .= $icon;
117 }
118 return $icons_str;
119 }
120
121 /**
122 * Check if Oney is available
123 *
124 * @return void
125 */
126 public function check_oney_is_available()
127 {
128 $cart = WC()->cart;
129
130 //for backend orders
131 if( !empty(get_query_var('order-pay')) ){
132 $order = wc_get_order(get_query_var('order-pay'));
133 $items = $order->get_items();
134
135 $country_code_shipping = $order->get_shipping_country();
136 $country_code_billing = $order->get_billing_country();
137
138 $this->order_items_to_cart($cart, $items);
139 }
140
141 $total_price = floatval($cart->total);
142 $products_qty = (int) $cart->cart_contents_count;
143
144 // Min and max
145 if ($total_price < $this->oney_thresholds_min || $total_price > $this->oney_thresholds_max) {
146 $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->oney_thresholds_min , $this->oney_thresholds_max ).'</div>';
147 return false;
148 }
149
150 // Cart check
151 if ($products_qty >= self::ONEY_PRODUCT_QUANTITY_MAXIMUM) {
152 $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>';
153 return self::ONEY_UNAVAILABLE_CODE_CART_SIZE_TOO_HIGH;
154 }
155
156 // Country check
157 if( empty($country_code_shipping) || empty($country_code_shipping) ){
158 $country_code_shipping = WC()->customer->get_shipping_country();
159 $country_code_billing = WC()->customer->get_billing_country();
160 }
161
162 if ( !$this->validate_shipping_billing_country($country_code_shipping, $country_code_billing) ||
163 !$this->allowed_country($country_code_billing, $this->allowed_country_codes) ||
164 !$this->allowed_country($country_code_shipping, $this->allowed_country_codes)
165 ) {
166 $this->description = '<div class="payment_method_oney_x3_with_fees_disabled">'.__('Unavailable for the specified country.', 'payplug').'</div>';
167 return self::ONEY_UNAVAILABLE_CODE_COUNTRY_NOT_ALLOWED;
168 }
169
170 return true;
171 }
172
173 /**
174 * Check the order amount to ensure it's on the allowed range.
175 *
176 * @param int $amount
177 *
178 * @return int|\WP_Error
179 */
180 public function validate_order_amount($amount)
181 {
182 if ($amount / 100 < $this->min_oney_price || $amount / 100 > $this->max_oney_price) {
183 return new \WP_Error(
184 'invalid order amount',
185 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)
186 );
187 }
188
189 return $amount;
190 }
191
192 /**
193 * @param \WC_Order $order
194 * @param int $amount
195 * @param int $customer_id
196 *
197 * @return array
198 * @throws \Exception
199 */
200 public function process_standard_payment($order, $amount, $customer_id)
201 {
202 $order_id = PayplugWoocommerceHelper::is_pre_30() ? $order->id : $order->get_id();
203 try {
204 if (!$this->check_oney_is_available()) {
205 throw new \Exception(__('Payment processing failed. Please retry.', 'payplug'));
206 } elseif ($this->check_oney_is_available() === self::ONEY_UNAVAILABLE_CODE_COUNTRY_NOT_ALLOWED) {
207 $country_code = WC()->customer->get_shipping_country();
208 throw new \Exception(__('Unavailable for the specified country.'));
209 } elseif ($this->check_oney_is_available() === self::ONEY_UNAVAILABLE_CODE_CART_SIZE_TOO_HIGH) {
210 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));
211 }
212
213 $country = PayplugWoocommerceHelper::is_pre_30() ? $order->billing_country : $order->get_billing_country();
214 $phone = PayplugWoocommerceHelper::is_pre_30() ? $order->billing_phone : $order->get_billing_phone();
215 $billing_email = PayplugWoocommerceHelper::is_pre_30() ? $order->billing_email : $order->get_billing_email();
216 $phone_number_util = PhoneNumberUtil::getInstance();
217 $phone_number = $phone_number_util->parse( $phone, $country );
218 if ( PhoneNumberType::MOBILE !== $phone_number_util->getNumberType( $phone_number ) ) {
219 throw new \Exception(__('Mobile phone number fullfilled is invalid. Please retry.', 'payplug'));
220 }
221
222 if (!filter_var($billing_email, FILTER_VALIDATE_EMAIL) || strpos($billing_email,'+') !== false) {
223 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'));
224 }
225
226 $address_data = PayplugAddressData::from_order($order);
227
228 $return_url = esc_url_raw($order->get_checkout_order_received_url());
229
230 if (!(substr( $return_url, 0, 4 ) === "http")) {
231 $return_url = get_site_url().$return_url;
232 }
233
234 $cart_items = [];
235 $items = $order->get_items();
236 foreach($items as $item) {
237 $data = $item->get_data();
238 $total = floatval(round($data['total'], 2)) * 100;
239 $cart_items[] = [
240 'delivery_label' => 'storepickup',
241 'delivery_type' => 'storepickup',
242 'brand' => 'Woocommerce',
243 'merchant_item_id' => 'cart-'.$data['id'].'-'.$data['product_id'],
244 'name' => $data['name'],
245 'expected_delivery_date' => date('Y-m-d'),
246 'total_amount' => (int) $total,
247 'price' => round($total / $data['quantity']),
248 'quantity' => $data['quantity']
249 ];
250 }
251
252 $payment_data = [
253 'authorized_amount' => $amount,
254 'auto_capture' => true,
255 'currency' => get_woocommerce_currency(),
256 'payment_method' => $this->id,
257 'billing' => $address_data->get_billing(),
258 'shipping' => $address_data->get_shipping(),
259 'payment_context' => [
260 "cart" => $cart_items
261 ],
262 'notification_url' => esc_url_raw(WC()->api_request_url('PayplugGateway')),
263 'hosted_payment' => [
264 'return_url' => $return_url,
265 'cancel_url' => esc_url_raw($order->get_cancel_order_url_raw()),
266 ],
267 'metadata' => [
268 'order_id' => $order_id,
269 'customer_id' => ((int) $customer_id > 0) ? $customer_id : 'guest',
270 'domain' => $this->limit_length(esc_url_raw(home_url()), 500),
271 ],
272 ];
273
274
275 /**
276 * Filter the payment data before it's used
277 *
278 * @param array $payment_data
279 * @param int $order_id
280 * @param array $customer_details
281 * @param PayplugAddressData $address_data
282 */
283 $payment_data = apply_filters('payplug_gateway_payment_data', $payment_data, $order_id, [], $address_data);
284 $payment = $this->api->payment_create($payment_data);
285
286 // Save transaction id for the order
287 PayplugWoocommerceHelper::is_pre_30()
288 ? update_post_meta($order_id, '_transaction_id', $payment->id)
289 : $order->set_transaction_id($payment->id);
290
291 if (is_callable([$order, 'save'])) {
292 $order->save();
293 }
294
295 /**
296 * Fires once a payment has been created.
297 *
298 * @param int $order_id Order ID
299 * @param PaymentResource $payment Payment resource
300 */
301 \do_action('payplug_gateway_payment_created', $order_id, $payment);
302
303 $metadata = PayplugWoocommerceHelper::extract_transaction_metadata($payment);
304 PayplugWoocommerceHelper::save_transaction_metadata($order, $metadata);
305
306 PayplugGateway::log(sprintf('Payment creation complete for order #%s', $order_id));
307
308 return [
309 'result' => 'success',
310 'redirect' => $payment->hosted_payment->payment_url,
311 'cancel' => $payment->hosted_payment->cancel_url,
312 ];
313 } catch (\HttpException $e) {
314 PayplugGateway::log(sprintf('Error while processing order #%s : %s', $order_id, wc_print_r($e->getErrorObject(), true)), 'error');
315 throw new \Exception(__($e->getMessage(), 'payplug'));
316 } catch (\Exception $e) {
317 PayplugGateway::log(sprintf('Error while processing order #%s : %s', $order_id, $e->getMessage()), 'error');
318 throw new \Exception(__($e->getMessage(), 'payplug'));
319 }
320 }
321
322
323 /**
324 * Check if the gatteway is allowed for the order amount
325 *
326 * @param array
327 * @return array
328 */
329 public function check_gateway($gateways)
330 {
331 $ordered_gateways = [];
332 if (isset($gateways[$this->id]) && $gateways[$this->id]->id == $this->id) {
333 if (!PayplugWoocommerceHelper::is_oney_available()) {
334 unset($gateways[$this->id]);
335 } else {
336 foreach ($gateways as $id => $gateway) {
337 switch ($id) {
338 case 'payplug':
339 $ordered_gateways[$id] = $gateway;
340 if($this->oney_type == 'with_fees'){
341 $ordered_gateways['oney_x3_with_fees'] = $gateways['oney_x3_with_fees'];
342 $ordered_gateways['oney_x4_with_fees'] = $gateways['oney_x4_with_fees'];
343 } else{
344 $ordered_gateways['oney_x3_without_fees'] = $gateways['oney_x3_without_fees'];
345 $ordered_gateways['oney_x4_without_fees'] = $gateways['oney_x4_without_fees'];
346 }
347 break;
348 case 'oney_x3_with_fees':
349 case 'oney_x4_with_fees':
350 case 'oney_x3_without_fees':
351 case 'oney_x4_without_fees':
352 break;
353 default:
354 $ordered_gateways[$id] = $gateway;
355 break;
356 }
357 }
358 $gateways = $ordered_gateways;
359 }
360 }
361 return $gateways;
362 }
363
364 /**
365 * Show Oney refund text
366 *
367 * @return void
368 */
369 public function oney_refund_text($order)
370 {
371 if ($this->id === $order->get_payment_method() && parent::can_refund_order($order) && $order->get_status() !== "refunded" && $this->api) {
372 $order_metadata = $order->get_meta('_payplug_metadata');
373 $payment = $this->api->payment_retrieve($order_metadata['transaction_id']);
374 $today = current_time('Y-m-d H:i:s');
375 $can_refund_date = date('Y-m-d H:i:s', $payment->__get('refundable_after'));
376 if ($can_refund_date >= $today) {
377 echo "<p style='color: red;'>" . __('Refund will be possible 48 hours after the last payment or refund transaction.', 'payplug') . "</p>";
378 }
379 }
380 }
381
382 public function payment_fields()
383 {
384 $description = $this->get_description();
385 if (!empty($description)) {
386 echo wpautop(wptexturize($description));
387 }
388 }
389
390 /**
391 *
392 * Billing and shipping addresses should have the same country and allowed by Oney
393 * https://payplug-prod.atlassian.net/browse/WOOC-227
394 *
395 * @param $order
396 * @return bool
397 *
398 */
399 public function validate_shipping_billing_country($shipping_country, $billing_country)
400 {
401 if($billing_country === $shipping_country)
402 return true;
403
404 return false;
405 }
406
407 /**
408 * Country of billing or shipping at oney payments should be on the allowedCountry that comes from pauyplug-api /account
409 *
410 * @param string $country
411 * @param array $allowed
412 * @return bool
413 */
414 public function allowed_country($country, $allowed)
415 {
416 if( in_array($country, $allowed))
417 return true;
418
419 return false;
420 }
421
422 /**
423 * Empty the cart and add all order_items
424 *
425 * @param $cart
426 * @param $items
427 * @return void
428 */
429 private function order_items_to_cart($cart, $items){
430 $cart->empty_cart();
431 foreach ($items as $item){
432 $cart->add_to_cart($item->get_product_id(), $item->get_quantity());
433 }
434 }
435
436
437 }
438