PluginProbe ʕ •ᴥ•ʔ
VikAppointments Services Booking Calendar / trunk
VikAppointments Services Booking Calendar vtrunk
trunk 1.2.17 1.2.18 1.2.19
vikappointments / site / controllers / packagesorder.php
vikappointments / site / controllers Last commit date
calendarweek.php 3 years ago cart.php 1 month ago confirmapp.php 2 years ago empattachser.php 4 years ago empeditcoupon.php 4 years ago empeditcustfield.php 4 years ago empeditlocation.php 4 years ago empeditpay.php 4 years ago empeditprofile.php 4 months ago empeditservice.php 4 years ago empeditwdays.php 4 years ago emplocwdays.php 4 years ago emplogin.php 2 years ago employeesearch.php 2 years ago employeeslist.php 4 years ago empmakerecur.php 1 month ago empmanres.php 1 month ago empsettings.php 2 years ago empsubscr.php 4 years ago empsubscrorder.php 1 year ago index.html 6 years ago modules.php 1 year ago order.php 4 months ago packages.php 4 years ago packagesconfirm.php 4 years ago packagesorder.php 1 year ago servicesearch.php 2 years ago subscriptions.php 4 years ago subscrpayment.php 1 year ago userprofile.php 4 months ago waitinglist.php 4 years ago
packagesorder.php
302 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.mvc.controllers.admin');
15
16 /**
17 * VikAppointments packages order controller.
18 *
19 * @since 1.7
20 */
21 class VikAppointmentsControllerPackagesorder extends VAPControllerAdmin
22 {
23 /**
24 * This is the end-point used by the gateway to validate a payment transaction.
25 * It is mandatory to send the following parameters (via GET or POST) in order to
26 * retrieve the correct details of the order transaction.
27 *
28 * @param integer ordnum The order number (ID).
29 * @param string ordkey The order key (SID).
30 *
31 * @return void
32 */
33 public function notifypayment()
34 {
35 $dispatcher = VAPFactory::getEventDispatcher();
36
37 $app = JFactory::getApplication();
38 $input = $app->input;
39
40 $oid = $input->getUint('ordnum');
41 $sid = $input->getAlnum('ordkey');
42
43 // Get order details (filter by ID and SID).
44 // In case the order doesn't exist, an exception will be thrown.
45 VAPLoader::import('libraries.order.factory');
46 $order = VAPOrderFactory::getPackages($oid, null, array('sid' => $sid));
47
48 /**
49 * This event is triggered every time a payment tries to validate a transaction made.
50 *
51 * DOES NOT trigger in case the order doesn't exist.
52 *
53 * @param mixed $order The details of the purchased package.
54 *
55 * @return void
56 *
57 * @since 1.6
58 */
59 $dispatcher->trigger('onReceivePaymentNotification', array($order));
60
61 // build return and error URL
62 $return_url = "index.php?option=com_vikappointments&view=packagesorder&ordnum={$oid}&ordkey={$sid}";
63 $error_url = "index.php?option=com_vikappointments&view=packagesorder&ordnum={$oid}&ordkey={$sid}";
64
65 /**
66 * If we are trying to validate an order already paid/confirmed, auto-redirect to
67 * the return URL instead of throwing an exception.
68 *
69 * @since 1.7.1
70 */
71 if ($order->statusRole == 'APPROVED')
72 {
73 $this->setRedirect(JRoute::rewrite($return_url, false));
74 return;
75 }
76
77 // make sure the order can be paid
78 if ($order->statusRole != 'PENDING')
79 {
80 // status not allowed
81 throw new Exception('The current status of the order does not allow any payments.', 403);
82 }
83
84 if (!$order->payment)
85 {
86 // payment method not found
87 throw new Exception('The selected payment does not exist', 404);
88 }
89
90 // reload payment details to access the parameters
91 $payment = JModelVAP::getInstance('payment')->getItem($order->payment->id);
92
93 $vik = VAPApplication::getInstance();
94
95 $config = VAPFactory::getConfig();
96
97 // fetch transaction data
98 $paymentData = array();
99
100 /**
101 * The payment URLs are correctly routed for external usage.
102 *
103 * @since 1.6
104 */
105 $return_url = $vik->routeForExternalUse($return_url, false);
106 $error_url = $vik->routeForExternalUse($error_url, false);
107
108 /**
109 * Include the Notification URL in both the PLAIN and ROUTED formats.
110 *
111 * @since 1.7
112 */
113 $notify_url = "index.php?option=com_vikappointments&task=packagesorder.notifypayment&ordnum={$oid}&ordkey={$sid}";
114
115 // subtract amount already paid
116 $total_to_pay = max(array(0, $order->totals->gross - $order->totals->paid));
117
118 $paymentData['type'] = 'packages';
119 $paymentData['action'] = 'validate';
120 $paymentData['oid'] = $order->id;
121 $paymentData['sid'] = $order->sid;
122 $paymentData['attempt'] = $order->payment_attempt;
123 $paymentData['transaction_name'] = JText::sprintf('VAPTRANSACTIONNAMEPACK', $config->get('agencyname'));
124 $paymentData['transaction_currency'] = $config->get('currencyname');
125 $paymentData['currency_symb'] = $config->get('currencysymb');
126 $paymentData['tax'] = 0;
127 $paymentData['return_url'] = $return_url;
128 $paymentData['error_url'] = $error_url;
129 $paymentData['notify_url'] = $vik->routeForExternalUse($notify_url, false);
130 $paymentData['notify_url_plain'] = JUri::root() . $notify_url;
131 $paymentData['total_to_pay'] = $total_to_pay;
132 $paymentData['total_net_price'] = $total_to_pay;
133 $paymentData['total_tax'] = 0;
134 $paymentData['payment_info'] = $payment;
135 $paymentData['details'] = array(
136 'purchaser_nominative' => $order->purchaser_nominative,
137 'purchaser_mail' => $order->purchaser_mail,
138 'purchaser_phone' => $order->purchaser_phone,
139 );
140
141 /**
142 * Added support for customer billing details.
143 *
144 * @since 1.7
145 */
146 $paymentData['billing'] = $order->billing;
147
148 /**
149 * Trigger event to manipulate the payment details.
150 *
151 * @param array &$order The transaction details.
152 * @param array &$params The payment configuration array.
153 *
154 * @return void
155 *
156 * @since 1.6
157 */
158 $dispatcher->trigger('onInitPaymentTransaction', array(&$paymentData, &$payment->params));
159
160 /**
161 * Instantiate the payment using the platform handler.
162 *
163 * @since 1.6.3
164 */
165 $obj = $vik->getPaymentInstance($payment->file, $paymentData, $payment->params);
166
167 try
168 {
169 // validate payment transaction
170 $result = $obj->validatePayment();
171 }
172 catch (Exception $e)
173 {
174 // catch any exceptions that might have been thrown by the gateway
175 $result = [];
176 $result['verified'] = 0;
177 $result['log'] = $e->getMessage();
178 }
179
180 // get order model
181 $model = JModelVAP::getInstance('packorder');
182
183 // successful response
184 if ($result['verified'])
185 {
186 if (!empty($result['tot_paid']))
187 {
188 // increase total amount paid
189 $order->totals->paid += (float) $result['tot_paid'];
190 }
191
192 if ($order->totals->paid >= $order->totals->gross)
193 {
194 // the whole amount has been paid, use the apposite PAID status
195 $order->status = JHtml::fetch('vaphtml.status.paid', 'packages', 'code');
196 }
197 else
198 {
199 // a deposit have been left, use CONFIRMED status
200 $order->status = JHtml::fetch('vaphtml.status.confirmed', 'packages', 'code');
201 }
202
203 // prepare data to save
204 $data = array(
205 'id' => $order->id,
206 'status' => $order->status,
207 'status_comment' => 'VAP_STATUS_CHANGED_FROM_PAY',
208 'tot_paid' => $order->totals->paid,
209 'paid' => $order->paid,
210 );
211
212 $model->save($data);
213
214 $mailOptions = array();
215 // validate e-mail rules before sending
216 $mailOptions['check'] = true;
217
218 // send e-mail notification to the customer
219 $model->sendEmailNotification($order->id, $mailOptions);
220
221 // send e-mail notification to the administrator(s)
222 $mailOptions['client'] = 'packadmin';
223 $model->sendEmailNotification($order->id, $mailOptions);
224
225 // try to auto-generate the invoice
226 VikAppointments::generateInvoice($order->id, 'packages');
227
228 /**
229 * Trigger event after the validation of a successful transaction.
230 *
231 * @param array $order The transaction details.
232 * @param array $args The response array.
233 *
234 * @return void
235 *
236 * @since 1.6
237 */
238 $dispatcher->trigger('onSuccessPaymentTransaction', array($paymentData, $result));
239 }
240 // failure response
241 else
242 {
243 // check if the payment registered any logs
244 if (!empty($result['log']))
245 {
246 $text = array(
247 'Order #' . $order->id . '-' . $order->sid . ' (Package)',
248 nl2br($result['log']),
249 );
250
251 // send error logs to administrator(s)
252 VikAppointments::sendAdminMailPaymentFailed($order->id, $text);
253
254 // get current date and time
255 $timeformat = preg_replace("/:i/", ':i:s', $config->get('timeformat'));
256 $now = JHtml::fetch('date', 'now', $config->get('dateformat') . ' ' . $timeformat, $app->get('offset', 'UTC'));
257
258 // build log string
259 $log = str_repeat('-', strlen($now) + 4) . "\n";
260 $log .= "| $now |\n";
261 $log .= str_repeat('-', strlen($now) + 4) . "\n";
262 $log .= "\n" . $result['log'];
263
264 if (!empty($order->log))
265 {
266 // always prepend new logs at the beginning
267 $log = $log . "\n\n" . $order->log;
268 }
269
270 // prepare save data
271 $data = array(
272 'id' => $order->id,
273 'log' => $log,
274 'payment_attempt' => ++$order->payment_attempt,
275 );
276
277 // update order logs
278 $model->save($data);
279 }
280
281 /**
282 * Trigger event after the validation of a failed transaction.
283 *
284 * @param array $order The transaction details.
285 * @param array $args The response array.
286 *
287 * @return void
288 *
289 * @since 1.6
290 */
291 $dispatcher->trigger('onFailPaymentTransaction', array($paymentData, $result));
292 }
293
294 // check whether the payment instance supports a method
295 // to be executed after the validation
296 if (method_exists($obj, 'afterValidation'))
297 {
298 $obj->afterValidation($result['verified'] ? 1 : 0);
299 }
300 }
301 }
302