PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / 1.2.21
VikAppointments Services Booking Calendar v1.2.21
1.2.21 1.2.20 trunk 1.2.17 1.2.18 1.2.19
vikappointments / site / controllers / empsubscrorder.php
vikappointments / site / controllers Last commit date
calendarweek.php 2 days ago cart.php 2 days ago confirmapp.php 2 days ago empattachser.php 2 days ago empeditcoupon.php 2 days ago empeditcustfield.php 2 days ago empeditlocation.php 2 days ago empeditpay.php 2 days ago empeditprofile.php 2 days ago empeditservice.php 2 days ago empeditwdays.php 2 days ago emplocwdays.php 2 days ago emplogin.php 2 days ago employeesearch.php 2 days ago employeeslist.php 2 days ago empmakerecur.php 2 days ago empmanres.php 2 days ago empsettings.php 2 days ago empsubscr.php 2 days ago empsubscrorder.php 2 days ago index.html 2 days ago modules.php 2 days ago order.php 2 days ago packages.php 2 days ago packagesconfirm.php 2 days ago packagesorder.php 2 days ago servicesearch.php 2 days ago subscriptions.php 2 days ago subscrpayment.php 2 days ago userprofile.php 2 days ago waitinglist.php 2 days ago
empsubscrorder.php
374 lines
1 <?php
2 /**
3 * @package VikAppointments
4 * @subpackage core
5 * @author E4J s.r.l.
6 * @copyright Copyright (C) 2021 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 VAPLoader::import('libraries.employee.area.controller');
15
16 /**
17 * Employee area subscription order controller.
18 *
19 * @since 1.6
20 */
21 class VikAppointmentsControllerEmpSubscrOrder extends VAPEmployeeAreaController
22 {
23 /**
24 * Activates the subscription trial.
25 *
26 * @return boolean
27 */
28 public function activatetrial()
29 {
30 // get view model
31 $model = $this->getModel('empsubscrcart');
32 // make sure the TRIAL subscription exists
33 $trial = $model->getTrial();
34
35 if ($trial === false)
36 {
37 $this->setRedirect('index.php?option=com_vikappointments&view=empsubscr');
38 return false;
39 }
40
41 // empty the cart
42 $model->emptyCart();
43
44 // set the TRIAL subscription into the cart
45 $model->setSubscription($trial['id']);
46
47 // dispatch saving process
48 $this->saveorder();
49 }
50
51 /**
52 * Saves the subscription that has been registered within the cart.
53 *
54 * @return boolean
55 */
56 public function saveorder()
57 {
58 $app = JFactory::getApplication();
59 $input = $app->input;
60
61 // prepare redirect URL
62 $this->setRedirect('index.php?option=com_vikappointments&view=empsubscr');
63
64 /**
65 * Validate session token before to proceed.
66 * Check token in both POST and GET because the trial activation
67 * is always reached via URL.
68 *
69 * @since 1.7
70 */
71 if (!JSession::checkToken() && !JSession::checkToken('GET'))
72 {
73 // invalid token, back to confirm page
74 $app->enqueueMessage(JText::translate('JINVALID_TOKEN'), 'error');
75 return false;
76 }
77
78 // load arguments from request
79 $args = array();
80 $args['itemid'] = $input->getUint('Itemid');
81 $args['billing'] = $input->get('billing', array(), 'array');
82
83 // get view model
84 $model = $this->getModel();
85
86 // try to save the subscription and get landing page
87 $url = $model->save($args);
88
89 // make sure we haven't faced any errors
90 if (!$url)
91 {
92 // get all registered errors
93 $errors = $model->getErrors();
94
95 foreach ($errors as $err)
96 {
97 // enqueue error message
98 $app->enqueueMessage($err, 'error');
99 }
100
101 return false;
102 }
103
104 // update redirect URL to reach the landing page
105 $this->setRedirect($url);
106 return true;
107 }
108
109 /**
110 * This is the end-point used by the gateway to validate a payment transaction.
111 * It is mandatory to send the following parameters (via GET or POST) in order to
112 * retrieve the correct details of the order transaction.
113 *
114 * @param integer ordnum The order number (ID).
115 * @param string ordkey The order key (SID).
116 *
117 * @return void
118 */
119 public function notifypayment()
120 {
121 $dispatcher = VAPFactory::getEventDispatcher();
122
123 $app = JFactory::getApplication();
124 $input = $app->input;
125
126 $oid = $input->getUint('ordnum');
127 $sid = $input->getAlnum('ordkey');
128
129 // Get order details (filter by ID and SID).
130 // In case the order doesn't exist, an exception will be thrown.
131 VAPLoader::import('libraries.order.factory');
132 $order = VAPOrderFactory::getEmployeeSubscription($oid, null, array('sid' => $sid));
133
134 /**
135 * This event is triggered every time a payment tries to validate a transaction made.
136 *
137 * DOES NOT trigger in case the order doesn't exist.
138 *
139 * @param mixed $order The details of the purchased subscription.
140 *
141 * @return void
142 *
143 * @since 1.6
144 */
145 $dispatcher->trigger('onReceivePaymentNotification', array($order));
146
147 // build return and error URL
148 $return_url = "index.php?option=com_vikappointments&view=empsubscrorder&id={$oid}";
149 $error_url = "index.php?option=com_vikappointments&view=empsubscrorder&id={$oid}";
150
151 /**
152 * If we are trying to validate an order already paid/confirmed, auto-redirect to
153 * the return URL instead of throwing an exception.
154 *
155 * @since 1.7.1
156 */
157 if ($order->statusRole == 'APPROVED')
158 {
159 $this->setRedirect(JRoute::rewrite($return_url, false));
160 return;
161 }
162
163 // make sure the order can be paid
164 if ($order->statusRole != 'PENDING')
165 {
166 // status not allowed
167 throw new Exception('The current status of the order does not allow any payments.', 403);
168 }
169
170 if (!$order->payment)
171 {
172 // payment method not found
173 throw new Exception('The selected payment does not exist', 404);
174 }
175
176 // reload payment details to access the parameters
177 $payment = JModelVAP::getInstance('payment')->getItem($order->payment->id);
178
179 $vik = VAPApplication::getInstance();
180
181 $config = VAPFactory::getConfig();
182
183 // fetch transaction data
184 $paymentData = array();
185
186 // the payment URLs are correctly routed for external usage
187 $return_url = $vik->routeForExternalUse($return_url, false);
188 $error_url = $vik->routeForExternalUse($error_url, false);
189
190 // include the Notification URL in both the PLAIN and ROUTED formats
191 $notify_url = "index.php?option=com_vikappointments&task=empsubscrorder.notifypayment&ordnum={$oid}&ordkey={$sid}";
192
193 // subtract amount already paid
194 $total_to_pay = max(array(0, $order->totals->gross - $order->totals->paid));
195
196 $paymentData['type'] = 'subscriptions';
197 $paymentData['action'] = 'validate';
198 $paymentData['oid'] = $order->id;
199 $paymentData['sid'] = $order->sid;
200 $paymentData['attempt'] = $order->payment_attempt;
201 $paymentData['transaction_name'] = JText::sprintf('VAPTRANSACTIONNAMESUBSCR', $order->subscription->name, $config->get('agencyname'));
202 $paymentData['transaction_currency'] = $config->get('currencyname');
203 $paymentData['currency_symb'] = $config->get('currencysymb');
204 $paymentData['tax'] = 0;
205 $paymentData['return_url'] = $return_url;
206 $paymentData['error_url'] = $error_url;
207 $paymentData['notify_url'] = $vik->routeForExternalUse($notify_url, false);
208 $paymentData['notify_url_plain'] = JUri::root() . $notify_url;
209 $paymentData['total_to_pay'] = $total_to_pay;
210 $paymentData['total_net_price'] = $total_to_pay;
211 $paymentData['total_tax'] = 0;
212 $paymentData['payment_info'] = $payment;
213 $paymentData['billing'] = $order->billing;
214 $paymentData['details'] = array(
215 'purchaser_nominative' => $order->billing->billing_name,
216 'purchaser_mail' => $order->billing->billing_mail,
217 'purchaser_phone' => $order->billing->billing_phone,
218 );
219
220 /**
221 * Trigger event to manipulate the payment details.
222 *
223 * @param array &$order The transaction details.
224 * @param array &$params The payment configuration array.
225 *
226 * @return void
227 *
228 * @since 1.6
229 */
230 $dispatcher->trigger('onInitPaymentTransaction', array(&$paymentData, &$payment->params));
231
232 /**
233 * Instantiate the payment using the platform handler.
234 *
235 * @since 1.6.3
236 */
237 $obj = $vik->getPaymentInstance($payment->file, $paymentData, $payment->params);
238
239 try
240 {
241 // validate payment transaction
242 $result = $obj->validatePayment();
243 }
244 catch (Exception $e)
245 {
246 // catch any exceptions that might have been thrown by the gateway
247 $result = [];
248 $result['verified'] = 0;
249 $result['log'] = $e->getMessage();
250 }
251
252 // get order model
253 $model = JModelVAP::getInstance('subscrorder');
254
255 // successful response
256 if ($result['verified'])
257 {
258 if (!empty($result['tot_paid']))
259 {
260 // increase total amount paid
261 $order->totals->paid += (float) $result['tot_paid'];
262 }
263
264 if ($order->totals->paid >= $order->totals->gross)
265 {
266 // the whole amount has been paid, use the apposite PAID status
267 $order->status = JHtml::fetch('vaphtml.status.paid', 'subscriptions', 'code');
268 }
269 else
270 {
271 // a deposit have been left, use CONFIRMED status
272 $order->status = JHtml::fetch('vaphtml.status.confirmed', 'subscriptions', 'code');
273 }
274
275 // prepare data to save
276 $data = array(
277 'id' => $order->id,
278 'status' => $order->status,
279 'status_comment' => 'VAP_STATUS_CHANGED_FROM_PAY',
280 'tot_paid' => $order->totals->paid,
281 'paid' => $order->paid,
282 );
283
284 $model->save($data);
285
286 // $mailOptions = array();
287 // validate e-mail rules before sending
288 // $mailOptions['check'] = true;
289
290 // send e-mail notification to the employee
291 // $model->sendEmailNotification($order->id, $mailOptions);
292
293 // send e-mail notification to the administrator(s)
294 // $mailOptions['client'] = 'subscradmin';
295 // $model->sendEmailNotification($order->id, $mailOptions);
296
297 // try to auto-generate the invoice
298 VikAppointments::generateInvoice($order->id, 'subscriptions');
299
300 /**
301 * Trigger event after the validation of a successful transaction.
302 *
303 * @param array $order The transaction details.
304 * @param array $args The response array.
305 *
306 * @return void
307 *
308 * @since 1.6
309 */
310 $dispatcher->trigger('onSuccessPaymentTransaction', array($paymentData, $result));
311 }
312 // failure response
313 else
314 {
315 // check if the payment registered any logs
316 if (!empty($result['log']))
317 {
318 $text = array(
319 'Order #' . $order->id . '-' . $order->sid . ' (Subscription)',
320 nl2br($result['log']),
321 );
322
323 // send error logs to administrator(s)
324 VikAppointments::sendAdminMailPaymentFailed($order->id, $text);
325
326 // get current date and time
327 $timeformat = preg_replace("/:i/", ':i:s', $config->get('timeformat'));
328 $now = JHtml::fetch('date', 'now', $config->get('dateformat') . ' ' . $timeformat, $app->get('offset', 'UTC'));
329
330 // build log string
331 $log = str_repeat('-', strlen($now) + 4) . "\n";
332 $log .= "| $now |\n";
333 $log .= str_repeat('-', strlen($now) + 4) . "\n";
334 $log .= "\n" . $result['log'];
335
336 if (!empty($order->log))
337 {
338 // always prepend new logs at the beginning
339 $log = $log . "\n\n" . $order->log;
340 }
341
342 // prepare save data
343 $data = array(
344 'id' => $order->id,
345 'log' => $log,
346 'payment_attempt' => ++$order->payment_attempt,
347 );
348
349 // update order logs
350 $model->save($data);
351 }
352
353 /**
354 * Trigger event after the validation of a failed transaction.
355 *
356 * @param array $order The transaction details.
357 * @param array $args The response array.
358 *
359 * @return void
360 *
361 * @since 1.6
362 */
363 $dispatcher->trigger('onFailPaymentTransaction', array($paymentData, $result));
364 }
365
366 // check whether the payment instance supports a method
367 // to be executed after the validation
368 if (method_exists($obj, 'afterValidation'))
369 {
370 $obj->afterValidation($result['verified'] ? 1 : 0);
371 }
372 }
373 }
374