1<?php
2/**
3 * @package tikiwiki
4 */
5// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
6//
7// All Rights Reserved. See copyright.txt for details and a complete list of authors.
8// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
9// $Id$
10
11// Data sent by the IPN must be left unharmed
12if (isset($_GET['ipn'])) {
13	$ipn_data = $_POST;
14}
15$inputConfiguration = [
16	[
17		'staticKeyFilters' => [
18			'amount' => 'text',
19			'manual_amount' => 'text',
20			'description' => 'text',
21			'request' => 'alpha',
22			'payable' => 'digits',
23			'offset_outstanding' => 'digits',
24			'offset_overdue' => 'digits',
25			'offset_past' => 'digits',
26			'offset_canceled' => 'digits',
27			'offset_authorized' => 'digits',
28			'invoice' => 'digits',
29			'cancel' => 'digits',
30			'note' => 'striptags',
31			'detail' => 'wikicontent',
32			'cclite_payment_amount' => 'text',    // params for cart module
33			'tiki_credit_amount' => 'text',
34			'tiki_credit_pay' => 'text',
35			'tiki_credit_type' => 'text',
36			'checkout' => 'text',
37			'update' => 'word',
38			'returnurl' => 'url',
39			'tsAjax' => 'word',
40			'list_type' => 'word',
41			'sort_mode' => 'text',
42			'numrows' => 'digits',
43			'filter_paymentRequestId' => 'digits',
44			'filter_description' => 'text',
45			'filter_detail' => 'text',
46			'filter_amount' => 'text',
47			//need to allow <= and >= for these - will filter later
48			'filter_request_date' => 'none',
49			'filter_payment_date' => 'none',
50			'filter_type' => 'text',
51			'filter_login' => 'text',
52			'filter_payer' => 'text',
53			'st' => 'text',
54			'tx' => 'text',
55		],
56		'staticKeyFiltersForArrays' => ['cart' => 'digits',],    // params for cart module
57		'catchAllUnset' => null,
58	],
59];
60
61require_once 'tiki-setup.php';
62$categlib = TikiLib::lib('categ');
63$paymentlib = TikiLib::lib('payment');
64$access->check_feature('payment_feature');
65
66$auto_query_args = [
67	'offset_outstanding',
68	'offset_overdue',
69	'offset_past',
70	'offset_canceled',
71];
72
73if (isset($_POST['tiki_credit_pay'])
74	&& isset($_POST['tiki_credit_amount'])
75	&& isset($_POST['tiki_credit_type'])
76	&& isset($_POST['invoice'])
77) {
78	require_once 'lib/payment/creditspaylib.php';
79	$userpaycredits = new UserPayCredits;
80	$userpaycredits->payAmount($_POST['tiki_credit_type'], $_POST['tiki_credit_amount'], $_POST['invoice']);
81}
82
83if (isset($_GET['tx'])) {
84	$tx_token = $_GET['tx'];
85	$access->check_feature('payment_paypal_pdt');
86	require_once 'lib/payment/paypallib.php';
87	$paypal_data = $paypallib->confirm_pdt($tx_token);
88
89	if ($paypal_data !== false) {
90		$invoice = $paypallib->get_invoice($paypal_data);
91		if (is_numeric($invoice) && $inputConfiguration >= 1) {
92			$info = $paymentlib->get_payment($invoice);
93			if (isset($info) && $paypallib->is_valid_for_payment($paypal_data, $info)) {
94				$amount = $paypallib->get_amount($paypal_data);
95				$paymentlib->enter_payment($invoice, $amount, 'paypal', $paypal_data);
96			}
97			if (isset($info)
98				&& $paypallib->is_valid_for_payment($paypal_data, $info, false)
99				&& isset($prefs['payment_paypal_pdt_redirect'])
100				&& $prefs['payment_paypal_pdt_redirect']
101			) {
102				$access->redirect($prefs['payment_paypal_pdt_redirect'] . '?invoice=' . $invoice);
103			}
104		}
105	}
106}
107
108if (isset($ipn_data)) {
109	$access->check_feature('payment_paypal_ipn');
110	require_once 'lib/payment/paypallib.php';
111
112	$invoice = $paypallib->get_invoice($ipn_data);
113	if (! is_numeric($invoice) || $invoice < 1) {
114		echo 'Payment response was not correctly formatted';    // goes back to PayPal server - for debugging mainly
115		exit;
116	}
117	$info = $paymentlib->get_payment($invoice);
118
119	// Important to check with paypal first
120	$valid = false;
121	if (isset($info)) {
122		try {
123			$valid = $paypallib->is_valid($ipn_data, $info);
124		} catch (\Exception $e) {
125			$logslib = TikiLib::lib('logs');
126			$logslib->add_log('Paypal', tra('Error while processing payment: ') . $e->getMessage());
127		}
128	}
129
130	if (isset($info) && $valid) {
131		$amount = $paypallib->get_amount($ipn_data);
132		$paymentlib->enter_payment($invoice, $amount, 'paypal', $ipn_data);
133	} else {
134		echo 'Payment ' . $invoice . ' was not verified';    // goes back to PayPal server
135		exit;
136	}
137
138	exit;
139}
140
141if ($prefs['payment_system'] == 'israelpost' && isset($_GET['invoice']) && $jitGet->OKauthentication->word()) {
142	$gateway = $paymentlib->gateway('israelpost');
143	// Return URL - check payment right away through APIs
144	$id = $_GET['invoice'];
145	$verified = $gateway->check_payment($id, $jitGet, $jitPost);
146
147	if ($verified) {
148		$access->redirect('tiki-payment.php?invoice=' . $id, tra('Payment has been confirmed.'));
149	} else {
150		$access->redirect('tiki-payment.php?invoice=' . $id, tra('Payment confirmation has not been received yet.'));
151	}
152}
153
154if (isset($_POST['manual_amount'], $_POST['invoice']) && preg_match('/^\d+(\.\d{2})?$/', $_POST['manual_amount'])) {
155	$objectperms = Perms::get('payment', $_REQUEST['invoice']);
156
157	if ($objectperms->payment_manual) {
158		$paymentlib->enter_payment(
159			$_POST['invoice'],
160			$_POST['manual_amount'],
161			'user',
162			[
163				'user' => $user,
164				'note' => $_POST['note'],
165			]
166		);
167		if (isset($_POST['returnurl'])) {
168			header('Location: ' . $_POST['returnurl']);
169			exit;
170		}
171
172		$access->redirect('tiki-payment.php?invoice=' . $_POST['invoice'], tra('Manual payment entered.'));
173	} else {
174		$access->redirect(
175			'tiki-payment.php?invoice=' . $_POST['invoice'],
176			tra('You do not have permission to enter payment.')
177		);
178	}
179}
180
181if (isset($_POST['request']) && $globalperms->request_payment) {
182	// Create new payment request
183
184	if (! empty($_POST['description']) && preg_match('/^\d+(\.\d{2})?$/', $_POST['amount']) && $_POST['payable'] > 0) {
185		$id = $paymentlib->request_payment(
186			$_POST['description'],
187			$_POST['amount'],
188			(int)$_POST['payable'],
189			$_POST['detail']
190		);
191
192		if ($prefs['feature_categories'] == 'y') {
193			$cat_objid = $id;
194			$cat_type = 'payment';
195			$cat_desc = $_POST['description'];
196			$cat_name = $_POST['description'];
197			$cat_href = 'tiki-payment.php?invoice=' . $id;
198			require 'categorize.php';
199		}
200
201		$access->redirect('tiki-payment.php?invoice=' . $id, tra('New payment requested.'));
202	}
203}
204
205if (isset($_REQUEST['cancel'])) {
206	$objectperms = Perms::get('payment', $_REQUEST['cancel']);
207	$info = $paymentlib->get_payment($_REQUEST['cancel']);
208
209	if ($objectperms->payment_admin || $info['user'] == $user) {
210		$access->check_authenticity(tr('Cancel payment %0?', $_REQUEST['cancel']));
211		$paymentlib->cancel_payment($_REQUEST['cancel']);
212		$access->redirect('tiki-payment.php?invoice=' . $_REQUEST['cancel'], tra('Payment canceled.'));
213	}
214}
215
216// Obtain information
217/**
218 * @param $type
219 */
220function fetch_payment_list($type)
221{
222	global $globalperms, $user, $prefs;
223	$smarty = TikiLib::lib('smarty');
224	$paymentlib = TikiLib::lib('payment');
225	$offsetKey = 'offset_' . $type;
226	$method = 'get_' . $type;
227	$offset = isset($_REQUEST[$offsetKey]) ? (int)$_REQUEST[$offsetKey] : 0;
228	$max = ! empty($_REQUEST['numrows']) ? $_REQUEST['numrows'] : (int)$prefs['maxRecords'];
229
230	if (! empty($_REQUEST)) {
231		$fields = array_keys($paymentlib->fieldmap);
232		foreach ($fields as $field) {
233			if (array_key_exists('filter_' . $field, $_REQUEST)) {
234				$filter[$field] = $_REQUEST['filter_' . $field];
235			}
236		}
237	}
238	$filter = ! empty($filter) ? $filter : [];
239	$dfields = ['request_date', 'payment_date'];
240	foreach ($dfields as $dfield) {
241		if (! empty($filter[$dfield])) {
242			$datefilter = explode(' - ', $filter[$dfield]);
243			if (count($datefilter) === 2) {
244				$tsfrom = (int)substr($datefilter[0], 0, 10);
245				$fromobj = new DateTime("@$tsfrom");
246				$tsto = (int)substr($datefilter[1], 0, 10);
247				$toobj = new DateTime("@$tsto");
248				$filter[$dfield] = '>= \'' . $fromobj->format('Y-m-d H:i:s') . '\' AND '
249					. $paymentlib->fieldmap[$dfield]['table'] . '.`' . $dfield . '` <= \''
250					. $toobj->format('Y-m-d H:i:s') . '\'';
251			} else {
252				$ts = (int)substr($filter[$dfield], 2, 10);
253				$dateobj = new DateTime("@$ts");
254				$op = substr($filter[$dfield], 0, 2);
255				$op = in_array($op, ['<=', '>=']) ? $op : '';
256				if ($op) {
257					$filter[$dfield] = substr($filter[$dfield], 0, 2) . ' \'' . $dateobj->format('Y-m-d H:i:s') . '\'';
258				} else {
259					unset($filter[$dfield]);
260				}
261			}
262		}
263	}
264
265	$sort = ! empty($_REQUEST['sort_mode']) ? $_REQUEST['sort_mode'] : null;
266
267	$forUser = '';
268	if (! $globalperms->payment_admin
269		&& (
270			($type == 'outstanding' || $type == 'overdue')
271			&& $prefs['payment_user_only_his_own'] == 'y'
272			|| $type != 'outstanding'
273			&& $type != 'overdue'
274			&& $prefs['payment_user_only_his_own_past'] == 'y'
275		)
276	) {
277		$forUser = $user;
278	}
279	$data = $paymentlib->$method($offset, $max, $forUser, $filter, $sort);
280	$data['offset'] = $offset;
281	$data['offset_arg'] = "offset_$type";
282	$data['max'] = $max;
283	$smarty->assign($type, $data);
284
285	//add tablesorter sorting and filtering
286	$ts = Table_Check::setVars('pmt_' . $type, true);
287	if ($ts['enabled'] && ! $ts['ajax']) {
288		$tableclass = $type == 'past' ? 'TikiPaymentPast' : 'TikiPayment';
289		Table_Factory::build(
290			$tableclass,
291			[
292				'id' => 'pmt_' . $type,
293				'total' => $data['cant'],
294				'ajax' => [
295					'requiredparams' => [
296						'list_type' => $type,
297					],
298				],
299			]
300		);
301	}
302}
303
304if ($prefs['feature_categories'] == 'y' && $globalperms->payment_request) {
305	$cat_type = 'payment';
306	$cat_objid = '';
307	$cat_object_exists = false;
308	$smarty->assign('section', 'payment');
309	require 'categorize_list.php';
310}
311
312if (isset($_REQUEST['invoice'])) {
313	$smarty->assign('invoice', $_REQUEST['invoice']);
314}
315
316if (Table_Check::isEnabled(true) && Table_Check::isAjaxCall()) {
317	$types = ['outstanding', 'overdue', 'past', 'canceled', 'authorized'];
318	if (! empty($_REQUEST['list_type']) && in_array($_REQUEST['list_type'], $types)) {
319		fetch_payment_list($_REQUEST['list_type']);
320	}
321	$smarty->display('tiki-payment.tpl');
322} else {
323	fetch_payment_list('outstanding');
324	fetch_payment_list('overdue');
325	fetch_payment_list('past');
326	fetch_payment_list('canceled');
327	fetch_payment_list('authorized');
328	$smarty->assign('mid', 'tiki-payment.tpl');
329	$smarty->display('tiki.tpl');
330}
331