PluginProbe
VikBooking Hotel Booking Engine & PMS / 1.8.16
VikBooking Hotel Booking Engine & PMS v1.8.16
1.8.16 1.8.15 1.8.14 1.8.13 1.8.12 1.8.11 1.8.10 1.8.9 1.8.6 1.8.7 1.8.8 trunk 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 All 37 releases
← All changes | libraries/adapter/payment/payment.php +983 -0 1.6.3 → 1.8.16 View file →
@@ -1,0 +1,983 @@
1 +<?php
2 +/**
3 + * @package VikWP - Libraries
4 + * @subpackage adapter.payment
5 + * @author E4J s.r.l.
6 + * @copyright Copyright (C) 2023 E4J s.r.l. All Rights Reserved.
7 + * @license http://www.gnu.org/licenses/gpl-2.0.html GNU/GPL
8 + * @link https://vikwp.com
9 + */
10 +
11 +// No direct access
12 +defined('ABSPATH') or die('No script kiddies please!');
13 +
14 +JLoader::import('adapter.payment.status');
15 +
16 +/**
17 + * This class describes the events that an abstract payment should handle.
18 + *
19 + * @since 10.1
20 + */
21 +abstract class JPayment
22 +{
23 + /**
24 + * The name of the plugin that has requested the payment.
25 + *
26 + * @var string
27 + */
28 + protected $caller;
29 +
30 + /**
31 + * The driver identifier of the gateway.
32 + *
33 + * @var string
34 + */
35 + protected $driver;
36 +
37 + /**
38 + * The order details.
39 + *
40 + * @var JObject
41 + */
42 + protected $order;
43 +
44 + /**
45 + * The payment configuration parameters.
46 + *
47 + * @var JObject
48 + */
49 + protected $params;
50 +
51 + /**
52 + * Class constructor.
53 + *
54 + * @param string $caller The name of the plugin that requested the payment.
55 + * @param mixed $order The order details to start the transaction.
56 + * @param mixed $params The configuration of the payment.
57 + */
58 + public function __construct($caller, $order, $params = array())
59 + {
60 + if (is_string($params))
61 + {
62 + $params = (array) json_decode($params);
63 + }
64 +
65 + $this->caller = $caller;
66 + $this->order = new JObject($order);
67 + $this->params = new JObject($params);
68 + }
69 +
70 + /**
71 + * Returns the name of the plugin that dispatched the payment.
72 + *
73 + * @return string
74 + */
75 + public function getCaller()
76 + {
77 + return $this->caller;
78 + }
79 +
80 + /**
81 + * Checks if the given caller matches the current one.
82 + *
83 + * @param string $caller The caller to check.
84 + *
85 + * @return boolean True if the callers are equal, otherwise false.
86 + *
87 + * @uses getCaller()
88 + *
89 + * @since 10.1.1
90 + */
91 + public function isCaller($caller)
92 + {
93 + return !strcasecmp($this->getCaller(), $caller);
94 + }
95 +
96 + /**
97 + * Returns the name of the driver.
98 + *
99 + * @return string
100 + */
101 + public function getDriver()
102 + {
103 + if (!$this->driver)
104 + {
105 + /**
106 + * Fixed driver name calculation, which was
107 + * based on the file name instead of the classname.
108 + *
109 + * @since 10.1.1
110 + */
111 + $class = get_class($this);
112 +
113 + // extract the string between the plugin name and "payment"
114 + $this->driver = preg_replace_callback("/{$this->caller}(.*?)Payment$/i", function($match)
115 + {
116 + return $match[1];
117 + }, $class);
118 +
119 + $this->driver = strtolower($this->driver);
120 + }
121 +
122 + return $this->driver;
123 + }
124 +
125 + /**
126 + * Checks if the given driver matches the current one.
127 + *
128 + * @param string $driver The driver to check.
129 + *
130 + * @return boolean True if the drivers are equal, otherwise false.
131 + *
132 + * @uses getDriver()
133 + */
134 + public function isDriver($driver)
135 + {
136 + return !strcasecmp($this->getDriver(), $driver);
137 + }
138 +
139 + /**
140 + * Returns the order detail related to the specified key.
141 + *
142 + * @param string $key The registry key.
143 + * @param mixed $def The default value if the key is not set.
144 + *
145 + * @return mixed The registry value, or the default one.
146 + */
147 + public function get($key, $def = null)
148 + {
149 + return $this->order->get($key, $def);
150 + }
151 +
152 + /**
153 + * Updates the specified key into the order details object.
154 + *
155 + * @param string $key The registry key.
156 + * @param mixed $val The value to update.
157 + *
158 + * @param mixed The old value.
159 + */
160 + public function set($key, $val)
161 + {
162 + return $this->order->set($key, $val);
163 + }
164 +
165 + /**
166 + * Returns an associative array containing the order details.
167 + *
168 + * @return array
169 + *
170 + * @since 10.1.30
171 + */
172 + public function getOrder()
173 + {
174 + return $this->order->getProperties();
175 + }
176 +
177 + /**
178 + * Returns the configuration parameter related to the specified key.
179 + *
180 + * @param string $key The registry key.
181 + * @param mixed $def The default value if the key is not set.
182 + *
183 + * @return mixed The registry value, or the default one.
184 + */
185 + public function getParam($key, $def = null)
186 + {
187 + return $this->params->get($key, $def);
188 + }
189 +
190 + /**
191 + * Updates the specified key into the configuration object.
192 + *
193 + * @param string $key The registry key.
194 + * @param mixed $val The value to update.
195 + *
196 + * @param mixed The old value.
197 + */
198 + public function setParam($key, $val)
199 + {
200 + return $this->params->set($key, $val);
201 + }
202 +
203 + /**
204 + * Returns an associative array containing the payments parameters.
205 + *
206 + * @return array
207 + *
208 + * @since 10.1.30
209 + */
210 + public function getParams()
211 + {
212 + return $this->params->getProperties();
213 + }
214 +
215 + /**
216 + * Returns an associative array containing the form
217 + * fields used to construct the configuration of the payment.
218 + *
219 + * This method triggers two ACTIONS to manipulate the
220 + * configuration array before it is returned:
221 + * - payment_before_admin_params
222 + * - payment_after_admin_params
223 + *
224 + * @return array The payment configuration.
225 + *
226 + * @uses buildAdminParameters()
227 + */
228 + public function getAdminParameters()
229 + {
230 + /**
231 + * Plugins can manipulate the properties of this object.
232 + * Fires before the configuration array is generated.
233 + * Global hook accessible by any drivers.
234 + *
235 + * @param self A reference to this object.
236 + *
237 + * @since 10.1.1
238 + */
239 + do_action($this->getHook('payment_before_admin_params'), array(&$this));
240 +
241 + /**
242 + * Plugins can manipulate the properties of this object.
243 + * Fires before the configuration array is generated.
244 + * Hook specific for the current driver.
245 + *
246 + * @param self A reference to this object.
247 + *
248 + * @since 10.1.32
249 + */
250 + do_action($this->getDriverHook('payment_before_admin_params'), array(&$this));
251 +
252 + // children payments will create the configuration form (as array)
253 + $config = $this->buildAdminParameters();
254 +
255 + /**
256 + * Plugins can manipulate the configuration form of the payment.
257 + * Fires after generating the config form.
258 + * Hook specific for the current driver.
259 + *
260 + * @param self A reference to this object.
261 + * @param array A reference to the configuration array.
262 + *
263 + * @since 10.1.32
264 + */
265 + do_action_ref_array($this->getDriverHook('payment_after_admin_params'), array(&$this, &$config));
266 +
267 + /**
268 + * Plugins can manipulate the configuration form of the payment.
269 + * Fires after generating the config form.
270 + * Global hook accessible by any drivers.
271 + *
272 + * @param self A reference to this object.
273 + * @param array A reference to the configuration array.
274 + *
275 + * @since 10.1.1
276 + */
277 + do_action_ref_array($this->getHook('payment_after_admin_params'), array(&$this, &$config));
278 +
279 + return $config;
280 + }
281 +
282 + /**
283 + * Abstract method used to build the associative array
284 + * to allow the plugins to construct a configuration form.
285 + *
286 + * In case the payment needs an API Key, the array should
287 + * be built as follows:
288 + *
289 + * {"apikey": {"type": "text", "label": "API Key"}}
290 + *
291 + * @return array The associative array.
292 + */
293 + protected function buildAdminParameters()
294 + {
295 + // return an empty array because a payment
296 + // may not need a configuration
297 + return array();
298 + }
299 +
300 + /**
301 + * Returns the HTML of the payment that should be used
302 + * to begin the transaction, such as a "Pay Now" button
303 + * for hosted integrations or a credit card form for seamleass
304 + * solutions.
305 + *
306 + * This method triggers the ACTION below to manipulate the payment details
307 + * before they are used to display the HTML form:
308 + * - payment_before_begin_transaction
309 + *
310 + * This method triggers the ACTION below to manipulate the HTML form
311 + * before it is returned to the plugin that requested it:
312 + * - payment_after_begin_transaction
313 + *
314 + * @return string The payment form.
315 + *
316 + * @uses beginTransaction()
317 + */
318 + public function showPayment()
319 + {
320 + /**
321 + * Plugins can manipulate the properties of this object.
322 + * Fires before the payment form is initiated.
323 + * Global hook accessible by any drivers.
324 + *
325 + * @param self A reference to this object.
326 + *
327 + * @since 10.1.1
328 + */
329 + do_action($this->getHook('payment_before_begin_transaction'), array(&$this));
330 +
331 + /**
332 + * Plugins can manipulate the properties of this object.
333 + * Fires before the payment form is initiated.
334 + * Hook specific for the current driver.
335 + *
336 + * @param self A reference to this object.
337 + *
338 + * @since 10.1.32
339 + */
340 + do_action($this->getDriverHook('payment_before_begin_transaction'), array(&$this));
341 +
342 + // start buffer
343 + ob_start();
344 + // children payments will start the transaction
345 + $this->beginTransaction();
346 + // get buffered contents
347 + $html = ob_get_contents();
348 + // clean buffer
349 + ob_end_clean();
350 +
351 + /**
352 + * Plugins can manipulate the generated HTML form.
353 + * Fires after generating the HTML payment form.
354 + * Hook specific for the current driver.
355 + *
356 + * @param self A reference to this object.
357 + * @param string A reference to the resulting HTML string.
358 + *
359 + * @since 10.1.32
360 + */
361 + do_action_ref_array($this->getDriverHook('payment_after_begin_transaction'), array(&$this, &$html));
362 +
363 + /**
364 + * Plugins can manipulate the generated HTML form.
365 + * Fires after generating the HTML payment form.
366 + * Global hook accessible by any drivers.
367 + *
368 + * @param self A reference to this object.
369 + * @param string A reference to the resulting HTML string.
370 + *
371 + * @since 10.1.1
372 + */
373 + do_action_ref_array($this->getHook('payment_after_begin_transaction'), array(&$this, &$html));
374 +
375 + return $html;
376 + }
377 +
378 + /**
379 + * Abstract method used to begin a payment transaction.
380 + * This method usually generates the HTML form of the payment.
381 + * The HTML contents can be echoed directly because this method
382 + * is executed always within a buffer.
383 + *
384 + * @return void
385 + */
386 + abstract protected function beginTransaction();
387 +
388 + /**
389 + * Provides the validation of the payment transaction.
390 + *
391 + * This method triggers the ACTION below to manipulate the payment details
392 + * before they are used to validate the transaction:
393 + * - payment_before_validate_transaction
394 + *
395 + * This method triggers the ACTION below to manipulate the
396 + * response evaluated by the payment:
397 + * - payment_after_validate_transaction
398 + *
399 + * @return mixed An object describing the status of the transaction.
400 + *
401 + * @uses validateTransaction()
402 + */
403 + public function validatePayment()
404 + {
405 + $status = new JPaymentStatus();
406 +
407 + /**
408 + * Plugins can manipulate the properties of this object.
409 + * Fires before the payment transaction is validated.
410 + * Global hook accessible by any drivers.
411 + *
412 + * @param self A reference to this object.
413 + *
414 + * @since 10.1.1
415 + */
416 + do_action($this->getHook('payment_before_validate_transaction'), array(&$this));
417 +
418 + /**
419 + * Plugins can manipulate the properties of this object.
420 + * Fires before the payment transaction is validated.
421 + * Hook specific for the current driver.
422 + *
423 + * @param self A reference to this object.
424 + *
425 + * @since 10.1.32
426 + */
427 + do_action($this->getDriverHook('payment_before_validate_transaction'), array(&$this));
428 +
429 + // children payments will validate the transaction to confirm the owner has been paid
430 + $this->validateTransaction($status);
431 +
432 + $response = null;
433 +
434 + /**
435 + * Plugins can manipulate the response object to return.
436 + * By filling the &$response variable, this method will return
437 + * it instead of the default &$status one.
438 + * Fires after validating the payment transaction.
439 + * Hook specific for the current driver.
440 + *
441 + * @param self A reference to this object.
442 + * @param JPaymentStatus A reference to the status object.
443 + * @param mixed A reference to the final response (null by default).
444 + *
445 + * @since 10.1.32
446 + */
447 + do_action_ref_array($this->getDriverHook('payment_after_validate_transaction'), array(&$this, &$status, &$response));
448 +
449 + /**
450 + * Plugins can manipulate the response object to return.
451 + * By filling the &$response variable, this method will return
452 + * it instead of the default &$status one.
453 + * Fires after validating the payment transaction.
454 + * Global hook accessible by any drivers.
455 + *
456 + * @param self A reference to this object.
457 + * @param JPaymentStatus A reference to the status object.
458 + * @param mixed A reference to the final response (null by default).
459 + *
460 + * @since 10.1.1
461 + */
462 + do_action_ref_array($this->getHook('payment_after_validate_transaction'), array(&$this, &$status, &$response));
463 +
464 + if (is_null($response))
465 + {
466 + // no hook fired, the response will be equals to the status object
467 + $response = $status;
468 + }
469 +
470 + return $response;
471 + }
472 +
473 + /**
474 + * Abstract method used to validate the payment transaction.
475 + * It is usually an end-point that the providers use to POST the
476 + * transaction data.
477 + *
478 + * @param JPaymentStatus &$status The status object. In case the payment was
479 + * successful, you should invoke: $status->verified().
480 + *
481 + * @return void
482 + *
483 + * @see JPaymentStatus
484 + */
485 + abstract protected function validateTransaction(JPaymentStatus &$status);
486 +
487 + /**
488 + * Method called to complete the transaction, for example to redirect
489 + * the customers to a specific landing page.
490 + *
491 + * This method triggers the ACTION below before the payment is finalised:
492 + * - payment_on_after_validation
493 + *
494 + * @param boolean $res True if the payment was successful, otherwise false.
495 + *
496 + * @return void
497 + *
498 + * @uses complete()
499 + */
500 + public function afterValidation($res = false)
501 + {
502 + /**
503 + * Plugins can manipulate the properties of this object.
504 + * Fires before the payment process is completed.
505 + * Global hook accessible by any drivers.
506 + *
507 + * @param self A reference to this object.
508 + * @param boolean The result of the transaction.
509 + *
510 + * @since 10.1.1
511 + */
512 + do_action_ref_array($this->getHook('payment_on_after_validation'), array(&$this, $res));
513 +
514 + /**
515 + * Plugins can manipulate the properties of this object.
516 + * Fires before the payment process is completed.
517 + * Hook specific for the current driver.
518 + *
519 + * @param self A reference to this object.
520 + * @param boolean The result of the transaction.
521 + *
522 + * @since 10.1.32
523 + */
524 + do_action_ref_array($this->getDriverHook('payment_on_after_validation'), array(&$this, $res));
525 +
526 + // finalise payment
527 + $this->complete($res);
528 + }
529 +
530 + /**
531 + * Abstract method used to finalise the payment.
532 + * e.g. enter here the code used to redirect the
533 + * customers to a specific landing page.
534 + *
535 + * @param boolean $res True if the payment was successful, otherwise false.
536 + *
537 + * @return void
538 + */
539 + protected function complete($res)
540 + {
541 + // do nothing as a plugin may
542 + // not need to finalise the payment
543 + }
544 +
545 + /**
546 + * Checks whether the payment method supports
547 + * refund requests (false by default).
548 + * Inherits method in children classes in case
549 + * the payment supports refunds.
550 + *
551 + * @return boolean
552 + *
553 + * @since 10.1.32
554 + */
555 + public function isRefundSupported()
556 + {
557 + // not supported by default
558 + return false;
559 + }
560 +
561 + /**
562 + * Performs the refund request of a payment.
563 + *
564 + * This method triggers the ACTION below to manipulate the payment details
565 + * before they are used to refund the transaction:
566 + * - payment_before_refund_transaction
567 + *
568 + * This method triggers the ACTION below to manipulate the
569 + * response evaluated by the refund:
570 + * - payment_after_refund_transaction
571 + *
572 + * @return mixed An object describing the status of the transaction.
573 + *
574 + * @uses isRefundSupported()
575 + * @uses doRefund()
576 + *
577 + * @since 10.1.32
578 + */
579 + public function refund()
580 + {
581 + // make sure the refund request is supported
582 + if (!$this->isRefundSupported())
583 + {
584 + // refund requests are not supported
585 + throw new Exception('Refund method not supported', 405);
586 + }
587 +
588 + $status = new JPaymentStatus();
589 +
590 + /**
591 + * Plugins can manipulate the properties of this object.
592 + * Fires before the refund request is made.
593 + * Global hook accessible by any drivers.
594 + *
595 + * @param self A reference to this object.
596 + *
597 + * @since 10.1.32
598 + */
599 + do_action($this->getHook('payment_before_refund_transaction'), array(&$this));
600 +
601 + /**
602 + * Plugins can manipulate the properties of this object.
603 + * Fires before the refund request is made.
604 + * Hook specific for the current driver.
605 + *
606 + * @param self A reference to this object.
607 + *
608 + * @since 10.1.32
609 + */
610 + do_action($this->getDriverHook('payment_before_refund_transaction'), array(&$this));
611 +
612 + // children payments will perform the refund request
613 + $this->doRefund($status);
614 +
615 + $response = null;
616 +
617 + /**
618 + * Plugins can manipulate the response object to return.
619 + * By filling the &$response variable, this method will return
620 + * it instead of the default &$status one.
621 + * Fires after completing the refund request.
622 + * Hook specific for the current driver.
623 + *
624 + * @param self A reference to this object.
625 + * @param JPaymentStatus A reference to the status object.
626 + * @param mixed A reference to the final response (null by default).
627 + *
628 + * @since 10.1.32
629 + */
630 + do_action_ref_array($this->getDriverHook('payment_after_refund_transaction'), array(&$this, &$status, &$response));
631 +
632 + /**
633 + * Plugins can manipulate the response object to return.
634 + * By filling the &$response variable, this method will return
635 + * it instead of the default &$status one.
636 + * Fires after completing the refund request.
637 + * Global hook accessible by any drivers.
638 + *
639 + * @param self A reference to this object.
640 + * @param JPaymentStatus A reference to the status object.
641 + * @param mixed A reference to the final response (null by default).
642 + *
643 + * @since 10.1.32
644 + */
645 + do_action_ref_array($this->getHook('payment_after_refund_transaction'), array(&$this, &$status, &$response));
646 +
647 + if (is_null($response))
648 + {
649 + // no hook fired, the response will be equals to the status object
650 + $response = $status;
651 + }
652 +
653 + return $response;
654 + }
655 +
656 + /**
657 + * Refund request implementor.
658 + * Children classes can inherit this method to use the API of the
659 + * payment in order to perform a refund request.
660 + *
661 + * @param JPaymentStatus &$status The status object. In case the refund was
662 + * successful, you should invoke: $status->verified().
663 + *
664 + * @return void
665 + *
666 + * @see JPaymentStatus
667 + *
668 + * @since 10.1.32
669 + */
670 + protected function doRefund(JPaymentStatus &$status)
671 + {
672 + // do nothing as a plugin may
673 + // not support refund requests
674 + }
675 +
676 + /**
677 + * Checks whether the payment method supports
678 + * direct charge requests (false by default).
679 + * Inherits method in children classes in case
680 + * the payment supports direct debits.
681 + *
682 + * @return boolean
683 + *
684 + * @since 10.1.46
685 + */
686 + public function isDirectChargeSupported()
687 + {
688 + // not supported by default
689 + return false;
690 + }
691 +
692 + /**
693 + * Performs the direct charge request of a CC.
694 + *
695 + * This method triggers the ACTION below to manipulate the payment details
696 + * before they are used to execute the direct charge:
697 + * - payment_before_direct_charge
698 + *
699 + * This method triggers the ACTION below to manipulate the
700 + * response evaluated by the direct charge:
701 + * - payment_after_direct_charge
702 + *
703 + * @return mixed An object describing the status of the transaction.
704 + *
705 + * @uses isDirectChargeSupported()
706 + * @uses doDirectCharge()
707 + *
708 + * @since 10.1.46
709 + */
710 + public function directCharge()
711 + {
712 + // make sure direct charge requests are supported
713 + if (!$this->isDirectChargeSupported())
714 + {
715 + // direct charge requests are not supported
716 + throw new Exception('Direct charge method not supported', 405);
717 + }
718 +
719 + $status = new JPaymentStatus();
720 +
721 + /**
722 + * Plugins can manipulate the properties of this object.
723 + * Fires before the direct charge request is made.
724 + * Global hook accessible by any drivers.
725 + *
726 + * @param self A reference to this object.
727 + *
728 + * @since 10.1.46
729 + */
730 + do_action($this->getHook('payment_before_direct_charge'), array($this));
731 +
732 + /**
733 + * Plugins can manipulate the properties of this object.
734 + * Fires before the direct charge request is made.
735 + * Hook specific for the current driver.
736 + *
737 + * @param self A reference to this object.
738 + *
739 + * @since 10.1.46
740 + */
741 + do_action($this->getDriverHook('payment_before_direct_charge'), array($this));
742 +
743 + // children payments will perform the direct charge
744 + $this->doDirectCharge($status);
745 +
746 + $response = null;
747 +
748 + /**
749 + * Plugins can manipulate the response object to return.
750 + * By filling the &$response variable, this method will return
751 + * it instead of the default &$status one.
752 + * Fires after completing the direct charge.
753 + * Hook specific for the current driver.
754 + *
755 + * @param self A reference to this object.
756 + * @param JPaymentStatus A reference to the status object.
757 + * @param mixed A reference to the final response (null by default).
758 + *
759 + * @since 10.1.32
760 + */
761 + do_action_ref_array($this->getDriverHook('payment_after_direct_charge'), array($this, $status, &$response));
762 +
763 + /**
764 + * Plugins can manipulate the response object to return.
765 + * By filling the &$response variable, this method will return
766 + * it instead of the default &$status one.
767 + * Fires after completing the direct charge.
768 + * Global hook accessible by any drivers.
769 + *
770 + * @param self A reference to this object.
771 + * @param JPaymentStatus A reference to the status object.
772 + * @param mixed A reference to the final response (null by default).
773 + *
774 + * @since 10.1.32
775 + */
776 + do_action_ref_array($this->getHook('payment_after_direct_charge'), array($this, $status, &$response));
777 +
778 + if (is_null($response))
779 + {
780 + // no hook fired, the response will be equal to the status object
781 + $response = $status;
782 + }
783 +
784 + return $response;
785 + }
786 +
787 + /**
788 + * Direct charge implementor.
789 + * Children classes can inherit this method to use the API of the
790 + * payment in order to perform a direct charge.
791 + *
792 + * @param JPaymentStatus $status The status object. In case the direct charge was
793 + * successful, you should invoke: $status->verified().
794 + *
795 + * @return void
796 + *
797 + * @see JPaymentStatus
798 + *
799 + * @since 10.1.46
800 + */
801 + protected function doDirectCharge(JPaymentStatus $status)
802 + {
803 + // do nothing as a plugin may
804 + // not support direct charges
805 + }
806 +
807 + /**
808 + * Checks whether the payment method allows off-session capturing.
809 + *
810 + * @return boolean
811 + *
812 + * @since 10.1.63
813 + */
814 + public function isOffSessionCaptureSupported()
815 + {
816 + // not supported by default
817 + return false;
818 + }
819 +
820 + /**
821 + * Performs the off-session capture transaction.
822 + *
823 + * This method triggers the ACTION below to manipulate the payment details
824 + * before they are used to execute the capture:
825 + * - payment_before_offsession_capture
826 + *
827 + * This method triggers the ACTION below to manipulate the
828 + * response evaluated by the capture:
829 + * - payment_after_offsession_capture
830 + *
831 + * @return mixed An object describing the status of the transaction.
832 + *
833 + * @uses isOffSessionCaptureSupported()
834 + * @uses doOffSessionCapture()
835 + *
836 + * @since 10.1.63
837 + */
838 + public function offSessionCapture()
839 + {
840 + // make sure off-session capturing is supported
841 + if (!$this->isOffSessionCaptureSupported())
842 + {
843 + // not supported
844 + throw new Exception('Off session capturing not supported', 405);
845 + }
846 +
847 + $status = new JPaymentStatus();
848 +
849 + /**
850 + * Plugins can manipulate the properties of this object.
851 + * Fires before the off-session capturing is made.
852 + * Global hook accessible by any drivers.
853 + *
854 + * @param self A reference to this object.
855 + *
856 + * @since 10.1.63
857 + */
858 + do_action($this->getHook('payment_before_offsession_capture'), array($this));
859 +
860 + /**
861 + * Plugins can manipulate the properties of this object.
862 + * Fires before the off-session capturing is made.
863 + * Hook specific for the current driver.
864 + *
865 + * @param self A reference to this object.
866 + *
867 + * @since 10.1.63
868 + */
869 + do_action($this->getDriverHook('payment_before_offsession_capture'), array($this));
870 +
871 + // children payments will perform the off-session capturing
872 + $this->doOffSessionCapture($status);
873 +
874 + $response = null;
875 +
876 + /**
877 + * Plugins can manipulate the response object to return.
878 + * By filling the &$response variable, this method will return
879 + * it instead of the default &$status one.
880 + * Fires after completing the off-session capturing.
881 + * Hook specific for the current driver.
882 + *
883 + * @param self A reference to this object.
884 + * @param JPaymentStatus A reference to the status object.
885 + * @param mixed A reference to the final response (null by default).
886 + *
887 + * @since 10.1.63
888 + */
889 + do_action_ref_array($this->getDriverHook('payment_after_offsession_capture'), array($this, $status, &$response));
890 +
891 + /**
892 + * Plugins can manipulate the response object to return.
893 + * By filling the &$response variable, this method will return
894 + * it instead of the default &$status one.
895 + * Fires after completing the off-session capturing.
896 + * Global hook accessible by any drivers.
897 + *
898 + * @param self A reference to this object.
899 + * @param JPaymentStatus A reference to the status object.
900 + * @param mixed A reference to the final response (null by default).
901 + *
902 + * @since 10.1.63
903 + */
904 + do_action_ref_array($this->getHook('payment_after_offsession_capture'), array($this, $status, &$response));
905 +
906 + if (is_null($response))
907 + {
908 + // no hook fired, the response will be equal to the status object
909 + $response = $status;
910 + }
911 +
912 + return $response;
913 + }
914 +
915 + /**
916 + * Off-session capturing implementor.
917 + * Children classes can inherit this method to use the API of the
918 + * payment in order to perform an off-session capturing.
919 + *
920 + * @param JPaymentStatus $status The status object. In case the capturing was
921 + * successful, you should invoke: $status->verified().
922 + *
923 + * @return void
924 + *
925 + * @see JPaymentStatus
926 + *
927 + * @see Visibility must be public.
928 + *
929 + * @since 10.1.63
930 + */
931 + public function doOffSessionCapture(JPaymentStatus $status)
932 + {
933 + // do nothing as a plugin may
934 + // not support off-session capturing
935 + }
936 +
937 + /**
938 + * Returns the final hook that will be used for actions
939 + * and filters. This hook can be accessed by any plugin.
940 + *
941 + * @param string $hook The base hook.
942 + *
943 + * @return string The final hook.
944 + *
945 + * @since 10.1.32
946 + */
947 + protected function getHook($hook)
948 + {
949 + // build the hook according to the latest standards, by adding the
950 + // plugin name at the beginning instead of at the end:
951 + // [PLUGIN]_[HOOK]
952 + $_hook = strtolower($this->caller) . '_' . $hook;
953 +
954 + // check if we have at least a plugin attached to this hook
955 + if (has_action($_hook))
956 + {
957 + // return hook as the plugins are already using it
958 + return $_hook;
959 + }
960 +
961 + // otherwise fallback to the old notation:
962 + // [HOOK]_[PLUGIN]
963 + return $hook . '_' . strtolower($this->caller);
964 + }
965 +
966 + /**
967 + * Returns the final hook that will be used for actions
968 + * and filters. This hook is related to the current driver.
969 + *
970 + * @param string $hook The base hook.
971 + *
972 + * @return string The final hook.
973 + *
974 + * @since 10.1.32
975 + */
976 + protected function getDriverHook($hook)
977 + {
978 + // build the hook according to the latest standards, in order
979 + // to avoid checking whether the drivers match:
980 + // [PLUGIN]_[HOOK]_[DRIVER]
981 + return strtolower($this->caller) . '_' . $hook . '_' . $this->getDriver();
982 + }
983 +}