PluginProbe
PayPlug for WooCommerce (Official) / 2.9.0
PayPlug for WooCommerce (Official) v2.9.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 1.2.6 All 101 releases
payplug / src / Controller / PayplugGenericGateway.php

PayplugGenericGateway.php in PayPlug for WooCommerce (Official) 2.9.0, at src/Controller/PayplugGenericGateway.php

530 lines 15.9 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\Controller;
4
5 use Payplug\PayplugWoocommerce\Gateway\PayplugAddressData;
6 use Payplug\PayplugWoocommerce\Gateway\PayplugGateway;
7 use Payplug\PayplugWoocommerce\Interfaces\PayplugGatewayBuilder;
8 use Payplug\PayplugWoocommerce\PayplugWoocommerceHelper;
9 use Automattic\WooCommerce\Utilities\OrderUtil;
10
11
12 use Payplug\Authentication;
13 use Payplug\Exception\ConfigurationException;
14 use Payplug\Exception\HttpException;
15 use Payplug\Exception\ForbiddenException;
16 use Payplug\Payplug;
17 use Payplug\Resource\Payment as PaymentResource;
18 use Payplug\Resource\Refund as RefundResource;
19
20 class PayplugGenericGateway extends PayplugGateway implements PayplugGatewayBuilder
21 {
22
23 public function __construct()
24 {
25 parent::__construct();
26
27 //this is only for PPRo payments
28 add_action('woocommerce_after_order_itemmeta', [$this, 'hide_wc_refund_button']);
29 //TODO:: add requirements here
30
31 }
32
33 /**
34 * Generic code to fetch payment gateway specific image
35 * @return string
36 */
37 public function get_icon()
38 {
39
40 //get object $image
41 $icons = apply_filters('payplug_payment_icons', [
42 'payplug' => sprintf('<img src="%s" alt="%s" class="payplug-payment-icon" />', esc_url(PAYPLUG_GATEWAY_PLUGIN_URL . '/assets/images/checkout/' . $this->image), $this->id . " Icon"),
43 ]);
44
45 $icons_str = '';
46 foreach ($icons as $icon) {
47 $icons_str .= $icon;
48 }
49
50 return $icons_str;
51 }
52
53 /**
54 * @return void
55 */
56 public function display_notice()
57 {
58 $error_message = 'payplug_' . $this->id . '_unauthorized_message';
59 ?>
60 <div class="notice notice-error is-dismissible">
61 <p><?php echo __( $error_message, 'payplug' ); ?></p>
62 </div>
63 <?php
64 }
65
66 public function checkGateway()
67 {
68
69 //check if module is enabled
70 if(!empty($this->settings['enabled']) && 'no' === $this->settings['enabled']){
71 return false;
72 }
73
74 $account = PayplugWoocommerceHelper::generic_get_account_data_from_options( $this->id );
75
76 if( !$this->check_api_gateway_enable($account)){
77 return false;
78 }
79
80
81 if (empty(WC()->cart)) {
82 return false;
83 }
84
85 //for backend orders
86 if (!empty(get_query_var('order-pay'))) {
87 $order = wc_get_order( (int) get_query_var('order-pay'));
88 $items = $order->get_items();
89 $country_code_shipping = $order->get_shipping_country();
90 $country_code_billing = $order->get_billing_country();
91 $this->order_items_to_cart(WC()->cart, $items);
92 }
93
94 if ( empty( $country_code_billing ) || empty( $country_code_shipping ) ) {
95 $country_code_shipping = method_exists(WC()->customer, "get_shipping_country") ? WC()->customer->get_shipping_country() : null;
96 $country_code_billing = method_exists(WC()->customer, "get_billing_country") ? WC()->customer->get_billing_country() : null;;
97 }
98
99 if( !$this->check_billing_country_permissions($account, $country_code_billing) ){
100 return false;
101 }
102
103
104 return true;
105 }
106
107 /**
108 * check if payment is enable and customer has permissions
109 * @param $account
110 * @return bool
111 */
112 protected function check_api_gateway_enable($account){
113
114 if (
115 isset( $account["payment_methods"] ) &&
116 empty( $account["payment_methods"][ $this->id ] ) &&
117 !$account["payment_methods"][ $this->id ]['enabled']
118 ) {
119 return false;
120 }
121
122
123 if (! isset( $account['permissions'][ $this->id ] ) ||
124 ( isset( $account['permissions'][ $this->id ] ) && !$account['permissions'][ $this->id ] )
125 ) {
126 return false;
127 }
128
129 return true;
130 }
131
132
133 /**
134 * Check if billing country can use this payment method
135 * @param $account
136 * @param $billing_code
137 * @return bool
138 */
139 public function check_billing_country_permissions($account, $billing_code){
140 $this->allowed_country_codes = !empty($account["payment_methods"][ $this->id ]['allowed_countries']) ? $account["payment_methods"][ $this->id ]['allowed_countries'] : null;
141
142 if (is_array($this->allowed_country_codes)) {
143 if ( in_array( "ALL", $this->allowed_country_codes) || empty( $this->allowed_country_codes ) ) {
144 return true;
145 }
146
147 //check if country is allowed
148 if ( in_array( $billing_code, $this->allowed_country_codes ) ) {
149 return true;
150
151 } else {
152 return false;
153 }
154 }
155
156 return true;
157 }
158
159
160 /**
161 * if payment was generated by an intend, we shouldn't generate another one and try to pay it, this would generate duplications
162 * @param $order
163 * @return array|null
164 * @throws \Exception
165 */
166 private function process_standard_intent_payment($order){
167
168 if ( !is_wc_endpoint_url('order-pay') &&
169 $this->is_checkout_block() &&
170 (
171 ( $this->id === "payplug" && ($this->payment_method === 'integrated'|| $this->payment_method === 'popup') ) ||
172 ( $this->id === "american_express" && $this->payment_method === 'popup')
173 ) &&
174 !empty($order->get_transaction_id()) ) {
175
176 $order_id = PayplugWoocommerceHelper::is_pre_30() ? $order->id : $order->get_id();
177
178 try {
179 $payment = $this->api->payment_retrieve($order->get_transaction_id());
180 if (ob_get_length() > 0) {
181 ob_clean();
182 }
183
184
185 // Save transaction id for the order
186 PayplugWoocommerceHelper::is_pre_30()
187 ? update_post_meta($order_id, '_transaction_id', $payment->id)
188 : $order->set_transaction_id($payment->id);
189
190 if (is_callable([$order, 'save'])) {
191 $order->save();
192 }
193
194 /**
195 * Fires once a payment has been created.
196 *
197 * @param int $order_id Order ID
198 * @param PaymentResource $payment Payment resource
199 */
200 \do_action('payplug_gateway_payment_created', $order_id, $payment);
201
202 $metadata = PayplugWoocommerceHelper::extract_transaction_metadata($payment);
203 PayplugWoocommerceHelper::save_transaction_metadata($order, $metadata);
204
205 PayplugGateway::log(sprintf('Payment intent created for order #%s', $order_id));
206
207 $return_url = esc_url_raw($order->get_checkout_order_received_url());
208
209 wp_send_json_success(
210 array(
211 'payment_id' => $payment->id,
212 'result' => 'success',
213 'redirect' => !empty($payment->hosted_payment->payment_url) ? $payment->hosted_payment->payment_url : $return_url,
214 'cancel' => !empty($payment->hosted_payment->cancel_url) ? $payment->hosted_payment->cancel_url : null
215 )
216 );
217
218 return array("stt" => "OK");
219
220 } catch (HttpException $e) {
221 PayplugGateway::log(sprintf('Error while processing order #%s : %s', $order_id, wc_print_r($e->getErrorObject(), true)), 'error');
222 throw new \Exception(__('Payment processing failed. Please retry.', 'payplug'));
223 } catch (\Exception $e) {
224 PayplugGateway::log(sprintf('Error while processing order #%s : %s', $order_id, $e->getMessage()), 'error');
225 throw new \Exception(__('Payment processing failed. Please retry.', 'payplug'));
226 }
227 }
228
229 return null;
230 }
231
232 public function process_standard_payment($order, $amount, $customer_id)
233 {
234
235 $intent = $this->process_standard_intent_payment($order);
236 if( !empty($intent) ){
237 return $intent;
238 }
239
240 $order_id = PayplugWoocommerceHelper::is_pre_30() ? $order->id : $order->get_id();
241 try {
242
243 //if there's no auth to process payment
244 if ( !$this->checkGateway() ){
245 throw new \Exception(__('Payment processing failed. Please retry.', 'payplug'));
246 }
247
248 $address_data = PayplugAddressData::from_order($order);
249
250 $return_url = esc_url_raw($order->get_checkout_order_received_url());
251
252 if (!(substr( $return_url, 0, 4 ) === "http")) {
253 $return_url = get_site_url().$return_url;
254 }
255
256 $payment_data = [
257 'amount' => $amount,
258 'currency' => get_woocommerce_currency(),
259 'payment_method' => $this->id,
260 'billing' => $address_data->get_billing(),
261 'shipping' => $address_data->get_shipping(),
262 'hosted_payment' => [
263 'return_url' => $return_url,
264 'cancel_url' => esc_url_raw($order->get_cancel_order_url_raw()),
265 ],
266 'notification_url' => esc_url_raw(WC()->api_request_url('PayplugGateway')),
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 "save_card"=> false,
273 "force_3ds"=> false
274 ];
275
276 /**
277 * Filter the payment data before it's used
278 *
279 * @param array $payment_data
280 * @param int $order_id
281 * @param array $customer_details
282 * @param PayplugAddressData $address_data
283 */
284 $payment_data = apply_filters('payplug_gateway_payment_data', $payment_data, $order_id, [], $address_data);
285 $payment = $this->api->payment_create($payment_data);
286
287 // Save transaction id for the order
288 PayplugWoocommerceHelper::is_pre_30()
289 ? update_post_meta($order_id, '_transaction_id', $payment->id)
290 : $order->set_transaction_id($payment->id);
291
292 if (is_callable([$order, 'save'])) {
293 $order->save();
294 }
295
296 /**
297 * Fires once a payment has been created.
298 *
299 * @param int $order_id Order ID
300 * @param PaymentResource $payment Payment resource
301 */
302 \do_action('payplug_gateway_payment_created', $order_id, $payment);
303
304 $metadata = PayplugWoocommerceHelper::extract_transaction_metadata($payment);
305 PayplugWoocommerceHelper::save_transaction_metadata($order, $metadata);
306
307 PayplugGateway::log(sprintf('Payment creation complete for order #%s', $order_id));
308
309 return [
310 'result' => 'success',
311 'redirect' => $payment->hosted_payment->payment_url,
312 'cancel' => $payment->hosted_payment->cancel_url,
313 ];
314
315 } catch (HttpException $e) {
316 PayplugGateway::log(sprintf('Error while processing order #%s : %s', $order_id, wc_print_r($e->getErrorObject(), true)), 'error');
317 throw new \Exception(__('Payment processing failed. Please retry.', 'payplug'));
318 } catch (\Exception $e) {
319 PayplugGateway::log(sprintf('Error while processing order #%s : %s', $order_id, $e->getMessage()), 'error');
320 throw new \Exception(__('Payment processing failed. Please retry.', 'payplug'));
321 }
322
323 }
324
325 /**
326 * Process refund for an order paid with PayPlug gateway.
327 *
328 * @param int $order_id
329 * @param null $amount
330 * @param string $reason
331 *
332 * @return bool|\WP_Error
333 */
334 public function process_refund($order_id, $amount = null, $reason = ''){
335
336 PayplugGateway::log(sprintf('Processing refund for order #%s', $order_id));
337
338 if( !$this->user_logged_in()){
339 PayplugGateway::log(__('You must be logged in with your PayPlug account.', 'payplug'), 'error');
340 return new \WP_Error('process_refund_error', __('You must be logged in with your PayPlug account.', 'payplug'));
341 }
342
343 $order = wc_get_order($order_id);
344 if (!$order instanceof \WC_Order) {
345 PayplugGateway::log(sprintf('The order #%s does not exist.', $order_id), 'error');
346 return new \WP_Error('process_refund_error', sprintf(__('The order %s does not exist.', 'payplug'), $order_id));
347 }
348
349 if ($order->get_status() === "cancelled") {
350 PayplugGateway::log(sprintf('The order #%s cannot be refund.', $order_id), 'error');
351 return new \WP_Error('process_refund_error', sprintf(__('The order %s cannot be refund.', 'payplug'), $order_id));
352 }
353
354 $transaction_id = PayplugWoocommerceHelper::is_pre_30() ? get_post_meta($order_id, '_transaction_id', true) : $order->get_transaction_id();
355 if (empty($transaction_id)) {
356 PayplugGateway::log(sprintf('The order #%s does not have PayPlug transaction ID associated with it.', $order_id), 'error');
357 return new \WP_Error('process_refund_error', __('No PayPlug transaction was found for this order. The refund could not be processed.', 'payplug'));
358 }
359
360 /**
361 * PPRO gateways feature!
362 */
363 if( isset($this->enable_refund) && $this->enable_refund === false){
364 add_action('admin_head', [$this, 'hide_wc_refund_button'] );
365 PayplugGateway::log(__('payplug_refund_disabled_error', 'payplug'), 'error');
366 return new \WP_Error('process_refund_error', __('payplug_refund_disabled_error', 'payplug'));
367 }
368
369 $customer_id = PayplugWoocommerceHelper::is_pre_30() ? $order->customer_user : $order->get_customer_id();
370 $data = [
371 'metadata' => [
372 'order_id' => $order_id,
373 'customer_id' => ((int) $customer_id > 0) ? $customer_id : 'guest',
374 'refund_from' => 'woocommerce',
375 ]
376 ];
377
378 if (!is_null($amount)) {
379 $data['amount'] = PayplugWoocommerceHelper::get_payplug_amount($amount);
380 }
381
382 if (!empty($reason)) {
383 $data['metadata']['reason'] = $reason;
384 }
385
386 /**
387 * Filter the refund data before it's used.
388 *
389 * @param array $data
390 * @param int $order_id
391 * @param string $transaction_id
392 */
393 $data = apply_filters('payplug_gateway_refund_data', $data, $order_id, $transaction_id);
394
395 try {
396 $refund = $this->api->refund_create($transaction_id, $data);
397
398 /**
399 * Fires once a refund has been created.
400 *
401 * @param int $order_id Order ID
402 * @param RefundResource $refund Refund resource
403 * @param string $transaction_id Transaction id
404 */
405 \do_action('payplug_gateway_refund_created', $order_id, $refund, $transaction_id);
406
407 $refund_meta_key = sprintf('_pr_%s', wc_clean($refund->id));
408 if (PayplugWoocommerceHelper::is_pre_30()) {
409 update_post_meta($order_id, $refund_meta_key, $refund->id);
410 } else {
411 $order->add_meta_data($refund_meta_key, $refund->id, true);
412 $order->save();
413 }
414
415 $note = sprintf(__('Refund %s : Refunded %s', 'payplug'), wc_clean($refund->id), wc_price(((int) $refund->amount) / 100));
416 if (!empty($refund->metadata['reason'])) {
417 $note .= sprintf(' (%s)', esc_html($refund->metadata['reason']));
418 }
419 $order->add_order_note($note);
420
421 try {
422 $payment = $this->api->payment_retrieve($transaction_id);
423 $metadata = PayplugWoocommerceHelper::extract_transaction_metadata($payment);
424 PayplugWoocommerceHelper::save_transaction_metadata($order, $metadata);
425 } catch (\Exception $e) {
426 }
427
428 PayplugGateway::log('Refund process complete for the order.');
429
430 return true;
431 } catch (HttpException $e) {
432 PayplugGateway::log(sprintf('Refund request error for the order %s from PayPlug API : %s', $order_id, wc_print_r($e->getErrorObject(), true)), 'error');
433
434 return new \WP_Error('process_refund_error', __('The transaction could not be refunded. Please try again.', 'payplug'));
435 } catch (\Exception $e) {
436 PayplugGateway::log(sprintf('Refund request error for the order %s : %s', $order_id, wc_clean($e->getMessage())), 'error');
437
438 return new \WP_Error('process_refund_error', __('The transaction could not be refunded. Please try again.', 'payplug'));
439 }
440
441
442
443 }
444
445
446 public function hide_wc_refund_button(){
447 global $post;
448
449 $payment_methods = ['satispay', 'sofort', 'ideal', 'mybank'];
450
451 if ( class_exists("OrderUtil") && OrderUtil::custom_orders_table_usage_is_enabled() ) {
452 $order_id = !empty($_GET["id"]) ? $_GET["id"] : null;
453
454 }else{
455
456 if(!empty($post->ID)){
457 $order_id = $post->ID;
458
459 }else if( !empty($_GET["id"]) ){
460 $order_id = $_GET["id"];
461
462 }else{
463 $order_id = null;
464
465 }
466 }
467
468 if(empty($order_id)){
469 return false;
470 }
471
472 $order = new \WC_Order($order_id);
473 if (in_array($order->get_payment_method(), $payment_methods)) {
474 ?>
475 <script>
476 jQuery(function () {
477 jQuery('.refund-items').attr("disabled", true);
478 });
479 </script>
480 <?php
481 }
482 }
483
484 /**
485 * refund not possible for PPRO payments
486 *
487 * @return void
488 */
489 public function refund_not_available($order)
490 {
491 if ($this->id === $order->get_payment_method() ) {
492 echo "<p style='color: red;'>" . __('payplug_refund_disabled_error', 'payplug') . "</p>";
493 }
494 }
495
496 /**
497 * Empty the cart and add all order_items
498 *
499 * @param $cart
500 * @param $items
501 * @return void
502 */
503 private function order_items_to_cart($cart, $items){
504 $cart->empty_cart();
505 foreach ($items as $item){
506 $cart->add_to_cart($item->get_product_id(), $item->get_quantity(), $item->get_variation_id());
507 }
508 }
509
510 /**
511 * get threshold values for the current payment method
512 * @param $account
513 * @return void
514 */
515 private function get_thresholds_values($account){
516
517 if(!empty($account["payment_methods"][$this->id]['min_amounts']['EUR'])){
518 $this->min_thresholds = floatval($account["payment_methods"][$this->id]['min_amounts']['EUR']/100);
519
520 }
521
522 if(!empty($account["payment_methods"][$this->id]['max_amounts']['EUR'])){
523 $this->max_thresholds = floatval($account["payment_methods"][$this->id]['max_amounts']['EUR']/100);
524
525 }
526
527 }
528
529 }
530