dolibarr 20.0.4
newpayment.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2001-2002 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2006-2017 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2009-2012 Regis Houssin <regis.houssin@inodbox.com>
5 * Copyright (C) 2018 Juanjo Menent <jmenent@2byte.es>
6 * Copyright (C) 2018-2021 Thibault FOUCART <support@ptibogxiv.net>
7 * Copyright (C) 2021 Waël Almoman <info@almoman.com>
8 * Copyright (C) 2021 Dorian Vabre <dorian.vabre@gmail.com>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <https://www.gnu.org/licenses/>.
22 *
23 * For Paypal test: https://developer.paypal.com/
24 * For Paybox test: ???
25 * For Stripe test: Use credit card 4242424242424242 .More example on https://stripe.com/docs/testing
26 *
27 * Variants:
28 * - When option STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION is on, we use the new PaymentIntent API
29 * - When option STRIPE_USE_NEW_CHECKOUT is on, we use the new checkout API
30 * - If no option set, we use old APIS (charge)
31 */
32
39if (!defined('NOLOGIN')) {
40 define("NOLOGIN", 1); // This means this output page does not require to be logged.
41}
42if (!defined('NOCSRFCHECK')) {
43 define("NOCSRFCHECK", 1); // We accept to go on this page from external web site.
44}
45if (!defined('NOIPCHECK')) {
46 define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip
47}
48if (!defined('NOBROWSERNOTIF')) {
49 define('NOBROWSERNOTIF', '1');
50}
51
52// For MultiCompany module.
53// Do not use GETPOST here, function is not defined and get of entity must be done before including main.inc.php
54// Because 2 entities can have the same ref.
55$entity = (!empty($_GET['entity']) ? (int) $_GET['entity'] : (!empty($_POST['entity']) ? (int) $_POST['entity'] : (!empty($_GET['e']) ? (int) $_GET['e'] : (!empty($_POST['e']) ? (int) $_POST['e'] : 1))));
56if (is_numeric($entity)) {
57 define("DOLENTITY", $entity);
58}
59
60// Load Dolibarr environment
61require '../../main.inc.php';
62require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
63require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
64require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
65require_once DOL_DOCUMENT_ROOT.'/eventorganization/class/conferenceorboothattendee.class.php';
66require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
67require_once DOL_DOCUMENT_ROOT.'/societe/class/societeaccount.class.php';
68require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
69require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
70
71// Hook to be used by external payment modules (ie Payzen, ...)
72$hookmanager = new HookManager($db);
73$hookmanager->initHooks(array('newpayment'));
74
75// Load translation files
76$langs->loadLangs(array("main", "other", "dict", "bills", "companies", "errors", "paybox", "paypal", "stripe")); // File with generic data
77
78// Security check
79// No check on module enabled. Done later according to $validpaymentmethod
80
81$action = GETPOST('action', 'aZ09');
82
83// Input are:
84// type ('invoice','order','contractline'),
85// id (object id),
86// amount (required if id is empty),
87// tag (a free text, required if type is empty)
88// currency (iso code)
89
90$suffix = GETPOST("suffix", 'aZ09');
91$amount = price2num(GETPOST("amount", 'alpha'));
92if (!GETPOST("currency", 'alpha')) {
93 $currency = $conf->currency;
94} else {
95 $currency = GETPOST("currency", 'aZ09');
96}
97$source = GETPOST("s", 'aZ09') ? GETPOST("s", 'aZ09') : GETPOST("source", 'aZ09');
98$getpostlang = GETPOST('lang', 'aZ09');
99$ws = GETPOSTINT("ws"); // Website reference where the newpayment page is embedded
100
101if (!$action) {
102 if (!GETPOST("amount", 'alpha') && !$source) {
103 print $langs->trans('ErrorBadParameters')." - amount or source";
104 exit;
105 }
106 if (is_numeric($amount) && !GETPOST("tag", 'alpha') && !$source) {
107 print $langs->trans('ErrorBadParameters')." - tag or source";
108 exit;
109 }
110 if ($source && !GETPOST("ref", 'alpha')) {
111 print $langs->trans('ErrorBadParameters')." - ref";
112 exit;
113 }
114}
115
116if ($source == 'organizedeventregistration') {
117 // Finding the Attendee
118 $attendee = new ConferenceOrBoothAttendee($db);
119
120 $invoiceid = GETPOSTINT('ref');
121 $invoice = new Facture($db);
122
123 $resultinvoice = $invoice->fetch($invoiceid);
124
125 if ($resultinvoice <= 0) {
126 setEventMessages(null, $invoice->errors, "errors");
127 } else {
128 /*
129 $attendeeid = 0;
130
131 $invoice->fetchObjectLinked();
132 $linkedAttendees = $invoice->linkedObjectsIds['conferenceorboothattendee'];
133
134 if (is_array($linkedAttendees)) {
135 $linkedAttendees = array_values($linkedAttendees);
136 $attendeeid = $linkedAttendees[0];
137 }*/
138 $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."eventorganization_conferenceorboothattendee";
139 $sql .= " WHERE fk_invoice = ".((int) $invoiceid);
140 $resql = $db->query($sql);
141 if ($resql) {
142 $obj = $db->fetch_object($resql);
143 if ($obj) {
144 $attendeeid = $obj->rowid;
145 }
146 }
147
148 if ($attendeeid > 0) {
149 $resultattendee = $attendee->fetch($attendeeid);
150
151 if ($resultattendee <= 0) {
152 setEventMessages(null, $attendee->errors, "errors");
153 } else {
154 $attendee->fetch_projet();
155
156 $amount = price2num($invoice->total_ttc);
157 // Finding the associated thirdparty
158 $thirdparty = new Societe($db);
159 $resultthirdparty = $thirdparty->fetch($invoice->socid);
160 if ($resultthirdparty <= 0) {
161 setEventMessages(null, $thirdparty->errors, "errors");
162 }
163 $object = $thirdparty;
164 }
165 }
166 }
167} elseif ($source == 'boothlocation') {
168 // Getting the amount to pay, the invoice, finding the thirdparty
169 $invoiceid = GETPOST('ref');
170 $invoice = new Facture($db);
171 $resultinvoice = $invoice->fetch($invoiceid);
172 if ($resultinvoice <= 0) {
173 setEventMessages(null, $invoice->errors, "errors");
174 } else {
175 $amount = price2num($invoice->total_ttc);
176 // Finding the associated thirdparty
177 $thirdparty = new Societe($db);
178 $resultthirdparty = $thirdparty->fetch($invoice->socid);
179 if ($resultthirdparty <= 0) {
180 setEventMessages(null, $thirdparty->errors, "errors");
181 }
182 $object = $thirdparty;
183 }
184}
185
186
187$paymentmethod = GETPOST('paymentmethod', 'alphanohtml') ? GETPOST('paymentmethod', 'alphanohtml') : ''; // Empty in most cases. Defined when a payment mode is forced
188$validpaymentmethod = array();
189
190// Detect $paymentmethod
191foreach ($_POST as $key => $val) {
192 $reg = array();
193 if (preg_match('/^dopayment_(.*)$/', $key, $reg)) {
194 $paymentmethod = $reg[1];
195 break;
196 }
197}
198
199
200// Define $urlwithroot
201//$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root));
202//$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
203$urlwithroot = DOL_MAIN_URL_ROOT; // This is to use same domain name than current. For Paypal payment, we can use internal URL like localhost.
204
205$urlok = $urlwithroot.'/public/payment/paymentok.php?';
206$urlko = $urlwithroot.'/public/payment/paymentko.php?';
207
208// Complete urls for post treatment
209$ref = $REF = GETPOST('ref', 'alpha');
210$TAG = GETPOST("tag", 'alpha');
211$FULLTAG = GETPOST("fulltag", 'alpha'); // fulltag is tag with more information
212$SECUREKEY = GETPOST("securekey"); // Secure key
213
214if ($paymentmethod && !preg_match('/'.preg_quote('PM='.$paymentmethod, '/').'/', $FULLTAG)) {
215 $FULLTAG .= ($FULLTAG ? '.' : '').'PM='.$paymentmethod;
216}
217
218if ($ws) {
219 $FULLTAG .= ($FULLTAG ? '.' : '').'WS='.$ws;
220}
221
222if (!empty($suffix)) {
223 $urlok .= 'suffix='.urlencode($suffix).'&';
224 $urlko .= 'suffix='.urlencode($suffix).'&';
225}
226if ($source) {
227 $urlok .= 's='.urlencode($source).'&';
228 $urlko .= 's='.urlencode($source).'&';
229}
230if (!empty($REF)) {
231 $urlok .= 'ref='.urlencode($REF).'&';
232 $urlko .= 'ref='.urlencode($REF).'&';
233}
234if (!empty($TAG)) {
235 $urlok .= 'tag='.urlencode($TAG).'&';
236 $urlko .= 'tag='.urlencode($TAG).'&';
237}
238if (!empty($FULLTAG)) {
239 $urlok .= 'fulltag='.urlencode($FULLTAG).'&';
240 $urlko .= 'fulltag='.urlencode($FULLTAG).'&';
241}
242if (!empty($SECUREKEY)) {
243 $urlok .= 'securekey='.urlencode($SECUREKEY).'&';
244 $urlko .= 'securekey='.urlencode($SECUREKEY).'&';
245}
246if (!empty($entity)) {
247 $urlok .= 'e='.urlencode((string) ($entity)).'&';
248 $urlko .= 'e='.urlencode((string) ($entity)).'&';
249}
250if (!empty($getpostlang)) {
251 $urlok .= 'lang='.urlencode($getpostlang).'&';
252 $urlko .= 'lang='.urlencode($getpostlang).'&';
253}
254$urlok = preg_replace('/&$/', '', $urlok); // Remove last &
255$urlko = preg_replace('/&$/', '', $urlko); // Remove last &
256
257
258// Make special controls
259
260if ((empty($paymentmethod) || $paymentmethod == 'paypal') && isModEnabled('paypal')) {
261 require_once DOL_DOCUMENT_ROOT.'/paypal/lib/paypal.lib.php';
262 require_once DOL_DOCUMENT_ROOT.'/paypal/lib/paypalfunctions.lib.php';
263
264 // Check parameters
265 $PAYPAL_API_OK = "";
266 if ($urlok) {
267 $PAYPAL_API_OK = $urlok;
268 }
269 $PAYPAL_API_KO = "";
270 if ($urlko) {
271 $PAYPAL_API_KO = $urlko;
272 }
273 if (empty($PAYPAL_API_USER)) {
274 print 'Paypal parameter PAYPAL_API_USER is not defined. Please <a href="'.DOL_URL_ROOT.'/paypal/admin/paypal.php">complete the setup of module PayPal first</a>.';
275 exit;
276 }
277 if (empty($PAYPAL_API_PASSWORD)) {
278 print 'Paypal parameter PAYPAL_API_PASSWORD is not defined. Please <a href="'.DOL_URL_ROOT.'/paypal/admin/paypal.php">complete the setup of module PayPal first</a>.';
279 exit;
280 }
281 if (empty($PAYPAL_API_SIGNATURE)) {
282 print 'Paypal parameter PAYPAL_API_SIGNATURE is not defined. Please <a href="'.DOL_URL_ROOT.'/paypal/admin/paypal.php">complete the setup of module PayPal first</a>.';
283 exit;
284 }
285}
286if ((empty($paymentmethod) || $paymentmethod == 'paybox') && isModEnabled('paybox')) {
287 // No specific test for the moment
288}
289if ((empty($paymentmethod) || $paymentmethod == 'stripe') && isModEnabled('stripe')) {
290 require_once DOL_DOCUMENT_ROOT.'/stripe/config.php'; // This include also /stripe/lib/stripe.lib.php, /includes/stripe/stripe-php/init.php, ...
291}
292
293// Initialize $validpaymentmethod
294// The list can be complete by the hook 'doValidatePayment' executed inside getValidOnlinePaymentMethods()
295$validpaymentmethod = getValidOnlinePaymentMethods($paymentmethod);
296
297// Check security token
298$tmpsource = $source;
299if ($tmpsource == 'membersubscription') {
300 $tmpsource = 'member';
301}
302$valid = true;
303if (getDolGlobalString('PAYMENT_SECURITY_TOKEN')) {
304 $tokenisok = false;
305 if (getDolGlobalString('PAYMENT_SECURITY_TOKEN_UNIQUE')) {
306 if ($tmpsource && $REF) {
307 // Use the source in the hash to avoid duplicates if the references are identical
308 $tokenisok = dol_verifyHash(getDolGlobalString('PAYMENT_SECURITY_TOKEN') . $tmpsource.$REF, $SECUREKEY, '2');
309 // Do a second test for retro-compatibility (token may have been hashed with membersubscription in external module)
310 if ($tmpsource != $source) {
311 $tokenisok = dol_verifyHash(getDolGlobalString('PAYMENT_SECURITY_TOKEN') . $source.$REF, $SECUREKEY, '2');
312 }
313 } else {
314 $tokenisok = dol_verifyHash($conf->global->PAYMENT_SECURITY_TOKEN, $SECUREKEY, '2');
315 }
316 } else {
317 $tokenisok = ($conf->global->PAYMENT_SECURITY_TOKEN == $SECUREKEY);
318 }
319
320 if (! $tokenisok) {
321 if (!getDolGlobalString('PAYMENT_SECURITY_ACCEPT_ANY_TOKEN')) {
322 $valid = false; // PAYMENT_SECURITY_ACCEPT_ANY_TOKEN is for backward compatibility
323 } else {
324 dol_syslog("Warning: PAYMENT_SECURITY_ACCEPT_ANY_TOKEN is on", LOG_WARNING);
325 }
326 }
327
328 if (!$valid) {
329 print '<div class="error">Bad value for key.</div>';
330 //print 'SECUREKEY='.$SECUREKEY.' valid='.$valid;
331 exit;
332 }
333}
334
335if (!empty($paymentmethod) && empty($validpaymentmethod[$paymentmethod])) {
336 print 'Payment module for payment method '.$paymentmethod.' is not active';
337 exit;
338}
339if (empty($validpaymentmethod)) {
340 print 'No active payment module (Paypal, Stripe, Paybox, ...)';
341 exit;
342}
343
344// Common variables
345$creditor = $mysoc->name;
346$paramcreditor = 'ONLINE_PAYMENT_CREDITOR';
347$paramcreditorlong = 'ONLINE_PAYMENT_CREDITOR_'.$suffix;
348if (!empty($conf->global->$paramcreditorlong)) {
349 $creditor = getDolGlobalString($paramcreditorlong); // use label long of the seller to show
350} elseif (!empty($conf->global->$paramcreditor)) {
351 $creditor = getDolGlobalString($paramcreditor); // use label short of the seller to show
352}
353
354$mesg = '';
355
356
357/*
358 * Actions
359 */
360
361// First log into the dolibarr_payment.log file
362dol_syslog("--- newpayment.php action = ".$action." paymentmethod=".$paymentmethod.' amount='.$amount.' newamount='.GETPOST("newamount", 'alpha'), LOG_DEBUG, 0, '_payment');
363
364// Action dopayment is called after clicking/choosing the payment mode
365if ($action == 'dopayment') {
366 if ($paymentmethod == 'paypal') {
367 $PAYPAL_API_PRICE = price2num(GETPOST("newamount", 'alpha'), 'MT');
368 $PAYPAL_PAYMENT_TYPE = 'Sale';
369
370 // Vars that are used as global var later in print_paypal_redirect()
371 $origfulltag = GETPOST("fulltag", 'alpha');
372 $shipToName = GETPOST("shipToName", 'alpha');
373 $shipToStreet = GETPOST("shipToStreet", 'alpha');
374 $shipToCity = GETPOST("shipToCity", 'alpha');
375 $shipToState = GETPOST("shipToState", 'alpha');
376 $shipToCountryCode = GETPOST("shipToCountryCode", 'alpha');
377 $shipToZip = GETPOST("shipToZip", 'alpha');
378 $shipToStreet2 = GETPOST("shipToStreet2", 'alpha');
379 $phoneNum = GETPOST("phoneNum", 'alpha');
380 $email = GETPOST("email", 'alpha');
381 $desc = GETPOST("desc", 'alpha');
382 $thirdparty_id = GETPOSTINT('thirdparty_id');
383
384 // Special case for Paypal-Indonesia
385 if ($shipToCountryCode == 'ID' && !preg_match('/\-/', $shipToState)) {
386 $shipToState = 'ID-'.$shipToState;
387 }
388
389 if (empty($PAYPAL_API_PRICE) || !is_numeric($PAYPAL_API_PRICE)) {
390 $mesg = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Amount"));
391 $action = '';
392 // } elseif (empty($EMAIL)) { $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("YourEMail"));
393 // } elseif (! isValidEmail($EMAIL)) { $mesg=$langs->trans("ErrorBadEMail",$EMAIL);
394 } elseif (!$origfulltag) {
395 $mesg = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("PaymentCode"));
396 $action = '';
397 }
398
399 if (empty($mesg)) {
400 dol_syslog("newpayment.php call paypal api and do redirect", LOG_DEBUG);
401
402 // Other
403 $PAYPAL_API_DEVISE = "USD";
404 if (!empty($currency)) {
405 $PAYPAL_API_DEVISE = $currency;
406 }
407
408 // Show var initialized by inclusion of paypal lib at start of this file
409 dol_syslog("Submit Paypal form", LOG_DEBUG);
410 dol_syslog("PAYPAL_API_USER: $PAYPAL_API_USER", LOG_DEBUG);
411 dol_syslog("PAYPAL_API_PASSWORD: ".preg_replace('/./', '*', $PAYPAL_API_PASSWORD), LOG_DEBUG); // No password into log files
412 dol_syslog("PAYPAL_API_SIGNATURE: $PAYPAL_API_SIGNATURE", LOG_DEBUG);
413 dol_syslog("PAYPAL_API_SANDBOX: $PAYPAL_API_SANDBOX", LOG_DEBUG);
414 dol_syslog("PAYPAL_API_OK: $PAYPAL_API_OK", LOG_DEBUG);
415 dol_syslog("PAYPAL_API_KO: $PAYPAL_API_KO", LOG_DEBUG);
416 dol_syslog("PAYPAL_API_PRICE: $PAYPAL_API_PRICE", LOG_DEBUG);
417 dol_syslog("PAYPAL_API_DEVISE: $PAYPAL_API_DEVISE", LOG_DEBUG);
418 // All those fields may be empty when making a payment for a free amount for example
419 dol_syslog("shipToName: $shipToName", LOG_DEBUG);
420 dol_syslog("shipToStreet: $shipToStreet", LOG_DEBUG);
421 dol_syslog("shipToCity: $shipToCity", LOG_DEBUG);
422 dol_syslog("shipToState: $shipToState", LOG_DEBUG);
423 dol_syslog("shipToCountryCode: $shipToCountryCode", LOG_DEBUG);
424 dol_syslog("shipToZip: $shipToZip", LOG_DEBUG);
425 dol_syslog("shipToStreet2: $shipToStreet2", LOG_DEBUG);
426 dol_syslog("phoneNum: $phoneNum", LOG_DEBUG);
427 dol_syslog("email: $email", LOG_DEBUG);
428 dol_syslog("desc: $desc", LOG_DEBUG);
429
430 dol_syslog("SCRIPT_URI: ".(empty($_SERVER["SCRIPT_URI"]) ? '' : $_SERVER["SCRIPT_URI"]), LOG_DEBUG); // If defined script uri must match domain of PAYPAL_API_OK and PAYPAL_API_KO
431
432 // A redirect is added if API call successful
433 $mesg = print_paypal_redirect($PAYPAL_API_PRICE, $PAYPAL_API_DEVISE, $PAYPAL_PAYMENT_TYPE, $PAYPAL_API_OK, $PAYPAL_API_KO, $FULLTAG);
434
435 // If we are here, it means the Paypal redirect was not done, so we show error message
436 $action = '';
437 }
438 }
439
440 if ($paymentmethod == 'paybox') {
441 $PRICE = price2num(GETPOST("newamount"), 'MT');
442 $email = getDolGlobalString('ONLINE_PAYMENT_SENDEMAIL');
443 $thirdparty_id = GETPOSTINT('thirdparty_id');
444
445 $origfulltag = GETPOST("fulltag", 'alpha');
446
447 // Securekey into back url useless for back url and we need an url lower than 150.
448 $urlok = preg_replace('/securekey=[^&]+&?/', '', $urlok);
449 $urlko = preg_replace('/securekey=[^&]+&?/', '', $urlko);
450
451 if (empty($PRICE) || !is_numeric($PRICE)) {
452 $mesg = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Amount"));
453 } elseif (empty($email)) {
454 $mesg = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ONLINE_PAYMENT_SENDEMAIL"));
455 } elseif (!isValidEmail($email)) {
456 $mesg = $langs->trans("ErrorBadEMail", $email);
457 } elseif (!$origfulltag) {
458 $mesg = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("PaymentCode"));
459 } elseif (dol_strlen($urlok) > 150) {
460 $mesg = 'Error urlok too long '.$urlok.' (Paybox requires 150, found '.strlen($urlok).')';
461 } elseif (dol_strlen($urlko) > 150) {
462 $mesg = 'Error urlko too long '.$urlko.' (Paybox requires 150, found '.strlen($urlok).')';
463 }
464
465 if (empty($mesg)) {
466 dol_syslog("newpayment.php call paybox api and do redirect", LOG_DEBUG);
467
468 include_once DOL_DOCUMENT_ROOT.'/paybox/lib/paybox.lib.php';
469 print_paybox_redirect($PRICE, $conf->currency, $email, $urlok, $urlko, $FULLTAG);
470
471 session_destroy();
472 exit;
473 }
474 }
475
476 if ($paymentmethod == 'stripe') {
477 if (GETPOST('newamount', 'alpha')) {
478 $amount = price2num(GETPOST('newamount', 'alpha'), 'MT');
479 } else {
480 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Amount")), null, 'errors');
481 $action = '';
482 }
483 }
484}
485
486
487// Called when choosing Stripe mode.
488// When using the old Charge API architecture, this code is called after clicking the 'dopayment' with the Charge API architecture.
489// When using the PaymentIntent API architecture, the Stripe customer was already created when creating PaymentIntent when showing payment page, and the payment is already ok when action=charge.
490if ($action == 'charge' && isModEnabled('stripe')) {
491 $amountstripe = $amount;
492
493 // Correct the amount according to unit of currency
494 // See https://support.stripe.com/questions/which-zero-decimal-currencies-does-stripe-support
495 $arrayzerounitcurrency = array('BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'VND', 'VUV', 'XAF', 'XOF', 'XPF');
496 if (!in_array($currency, $arrayzerounitcurrency)) {
497 $amountstripe = $amountstripe * 100;
498 }
499
500 dol_syslog("--- newpayment.php Execute action = ".$action." STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION=".getDolGlobalInt('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION'), LOG_DEBUG, 0, '_payment');
501 dol_syslog("GET=".var_export($_GET, true), LOG_DEBUG, 0, '_payment');
502 dol_syslog("POST=".var_export($_POST, true), LOG_DEBUG, 0, '_payment');
503
504 $stripeToken = GETPOST("stripeToken", 'alpha');
505 $email = GETPOST("email", 'alpha');
506 $thirdparty_id = GETPOSTINT('thirdparty_id'); // Note that for payment following online registration for members, this is empty because thirdparty is created once payment is confirmed by paymentok.php
507 $dol_type = (GETPOST('s', 'alpha') ? GETPOST('s', 'alpha') : GETPOST('source', 'alpha'));
508 $dol_id = GETPOSTINT('dol_id');
509 $vatnumber = GETPOST('vatnumber', 'alpha');
510 $savesource = GETPOSTISSET('savesource') ? GETPOSTINT('savesource') : 1;
511
512 dol_syslog("POST stripeToken = ".$stripeToken, LOG_DEBUG, 0, '_payment');
513 dol_syslog("POST email = ".$email, LOG_DEBUG, 0, '_payment');
514 dol_syslog("POST thirdparty_id = ".$thirdparty_id, LOG_DEBUG, 0, '_payment');
515 dol_syslog("POST vatnumber = ".$vatnumber, LOG_DEBUG, 0, '_payment');
516
517 $error = 0;
518 $errormessage = '';
519
520 // When using the old Charge API architecture
521 if (!getDolGlobalInt('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION')) {
522 try {
523 $metadata = array(
524 'dol_version' => DOL_VERSION,
525 'dol_entity' => $conf->entity,
526 'dol_company' => $mysoc->name, // Useful when using multicompany
527 'dol_tax_num' => $vatnumber,
528 'ipaddress' => getUserRemoteIP()
529 );
530
531 if (!empty($thirdparty_id)) {
532 $metadata["dol_thirdparty_id"] = $thirdparty_id;
533 }
534
535 if ($thirdparty_id > 0) {
536 dol_syslog("Search existing Stripe customer profile for thirdparty_id=".$thirdparty_id, LOG_DEBUG, 0, '_payment');
537
538 $service = 'StripeTest';
539 $servicestatus = 0;
540 if (getDolGlobalString('STRIPE_LIVE') && !GETPOSTINT('forcesandbox')) {
541 $service = 'StripeLive';
542 $servicestatus = 1;
543 }
544
545 $thirdparty = new Societe($db);
546 $thirdparty->fetch($thirdparty_id);
547
548 // Create Stripe customer
549 include_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php';
550 $stripe = new Stripe($db);
551 $stripeacc = $stripe->getStripeAccount($service);
552 $customer = $stripe->customerStripe($thirdparty, $stripeacc, $servicestatus, 1);
553 if (empty($customer)) {
554 $error++;
555 dol_syslog('Failed to get/create stripe customer for thirdparty id = '.$thirdparty_id.' and servicestatus = '.$servicestatus.': '.$stripe->error, LOG_ERR, 0, '_payment');
556 setEventMessages('Failed to get/create stripe customer for thirdparty id = '.$thirdparty_id.' and servicestatus = '.$servicestatus.': '.$stripe->error, null, 'errors');
557 $action = '';
558 }
559
560 // Create Stripe card from Token
561 if (!$error) {
562 if ($savesource) {
563 $card = $customer->sources->create(array("source" => $stripeToken, "metadata" => $metadata));
564 } else {
565 $card = $stripeToken;
566 }
567
568 if (empty($card)) {
569 $error++;
570 dol_syslog('Failed to create card record', LOG_WARNING, 0, '_payment');
571 setEventMessages('Failed to create card record', null, 'errors');
572 $action = '';
573 } else {
574 if (!empty($FULLTAG)) {
575 $metadata["FULLTAG"] = $FULLTAG;
576 }
577 if (!empty($dol_id)) {
578 $metadata["dol_id"] = $dol_id;
579 }
580 if (!empty($dol_type)) {
581 $metadata["dol_type"] = $dol_type;
582 }
583
584 dol_syslog("Create charge on card ".$card->id, LOG_DEBUG, 0, '_payment');
585 $charge = \Stripe\Charge::create(array(
586 'amount' => price2num($amountstripe, 'MU'),
587 'currency' => $currency,
588 'capture' => true, // Charge immediately
589 'description' => 'Stripe payment: '.$FULLTAG.' ref='.$ref,
590 'metadata' => $metadata,
591 'customer' => $customer->id,
592 'source' => $card,
593 'statement_descriptor_suffix' => dol_trunc($FULLTAG, 10, 'right', 'UTF-8', 1), // 22 chars that appears on bank receipt (company + description)
594 ), array("idempotency_key" => "$FULLTAG", "stripe_account" => "$stripeacc"));
595 // Return $charge = array('id'=>'ch_XXXX', 'status'=>'succeeded|pending|failed', 'failure_code'=>, 'failure_message'=>...)
596 if (empty($charge)) {
597 $error++;
598 dol_syslog('Failed to charge card', LOG_WARNING, 0, '_payment');
599 setEventMessages('Failed to charge card', null, 'errors');
600 $action = '';
601 }
602 }
603 }
604 } else {
605 $vatcleaned = $vatnumber ? $vatnumber : null;
606
607 /*$taxinfo = array('type'=>'vat');
608 if ($vatcleaned)
609 {
610 $taxinfo["tax_id"] = $vatcleaned;
611 }
612 // We force data to "null" if not defined as expected by Stripe
613 if (empty($vatcleaned)) $taxinfo=null;
614 */
615
616 dol_syslog("Create anonymous customer card profile", LOG_DEBUG, 0, '_payment');
617
618 $customer = \Stripe\Customer::create(array(
619 'email' => $email,
620 'description' => ($email ? 'Anonymous customer for '.$email : 'Anonymous customer'),
621 'metadata' => $metadata,
622 'source' => $stripeToken // source can be a token OR array('object'=>'card', 'exp_month'=>xx, 'exp_year'=>xxxx, 'number'=>xxxxxxx, 'cvc'=>xxx, 'name'=>'Cardholder's full name', zip ?)
623 ));
624 // Return $customer = array('id'=>'cus_XXXX', ...)
625
626 // Create the VAT record in Stripe
627 /* We don't know country of customer, so we can't create tax
628 if (!empty($conf->global->STRIPE_SAVE_TAX_IDS)) // We setup to save Tax info on Stripe side. Warning: This may result in error when saving customer
629 {
630 if (!empty($vatcleaned))
631 {
632 $isineec=isInEEC($object);
633 if ($object->country_code && $isineec)
634 {
635 //$taxids = $customer->allTaxIds($customer->id);
636 $customer->createTaxId($customer->id, array('type'=>'eu_vat', 'value'=>$vatcleaned));
637 }
638 }
639 }*/
640
641 if (!empty($FULLTAG)) {
642 $metadata["FULLTAG"] = $FULLTAG;
643 }
644 if (!empty($dol_id)) {
645 $metadata["dol_id"] = $dol_id;
646 }
647 if (!empty($dol_type)) {
648 $metadata["dol_type"] = $dol_type;
649 }
650
651 // The customer was just created with a source, so we can make a charge
652 // with no card defined, the source just used for customer creation will be used.
653 dol_syslog("Create charge", LOG_DEBUG, 0, '_payment');
654 $charge = \Stripe\Charge::create(array(
655 'customer' => $customer->id,
656 'amount' => price2num($amountstripe, 'MU'),
657 'currency' => $currency,
658 'capture' => true, // Charge immediately
659 'description' => 'Stripe payment: '.$FULLTAG.' ref='.$ref,
660 'metadata' => $metadata,
661 'statement_descriptor' => dol_trunc($FULLTAG, 10, 'right', 'UTF-8', 1), // 22 chars that appears on bank receipt (company + description)
662 ), array("idempotency_key" => "$FULLTAG", "stripe_account" => "$stripeacc"));
663 // Return $charge = array('id'=>'ch_XXXX', 'status'=>'succeeded|pending|failed', 'failure_code'=>, 'failure_message'=>...)
664 if (empty($charge)) {
665 $error++;
666 dol_syslog('Failed to charge card', LOG_WARNING, 0, '_payment');
667 setEventMessages('Failed to charge card', null, 'errors');
668 $action = '';
669 }
670 }
671 } catch (\Stripe\Exception\CardException $e) {
672 // Since it's a decline, \Stripe\Exception\Card will be caught
673 $body = $e->getJsonBody();
674 $err = $body['error'];
675
676 print('Status is:'.$e->getHttpStatus()."\n");
677 print('Type is:'.$err['type']."\n");
678 print('Code is:'.$err['code']."\n");
679 // param is '' in this case
680 print('Param is:'.$err['param']."\n");
681 print('Message is:'.$err['message']."\n");
682
683 $error++;
684 $errormessage = "ErrorCard ".$e->getMessage()." err=".var_export($err, true);
685 dol_syslog($errormessage, LOG_WARNING, 0, '_payment');
686 setEventMessages($e->getMessage(), null, 'errors');
687 $action = '';
688 } catch (\Stripe\Exception\RateLimitException $e) {
689 // Too many requests made to the API too quickly
690 $error++;
691 $errormessage = "ErrorRateLimit ".$e->getMessage();
692 dol_syslog($errormessage, LOG_WARNING, 0, '_payment');
693 setEventMessages($e->getMessage(), null, 'errors');
694 $action = '';
695 } catch (\Stripe\Exception\InvalidRequestException $e) {
696 // Invalid parameters were supplied to Stripe's API
697 $error++;
698 $errormessage = "ErrorInvalidRequest ".$e->getMessage();
699 dol_syslog($errormessage, LOG_WARNING, 0, '_payment');
700 setEventMessages($e->getMessage(), null, 'errors');
701 $action = '';
702 } catch (\Stripe\Exception\AuthenticationException $e) {
703 // Authentication with Stripe's API failed
704 // (maybe you changed API keys recently)
705 $error++;
706 $errormessage = "ErrorAuthentication ".$e->getMessage();
707 dol_syslog($errormessage, LOG_WARNING, 0, '_payment');
708 setEventMessages($e->getMessage(), null, 'errors');
709 $action = '';
710 } catch (\Stripe\Exception\ApiConnectionException $e) {
711 // Network communication with Stripe failed
712 $error++;
713 $errormessage = "ErrorApiConnection ".$e->getMessage();
714 dol_syslog($errormessage, LOG_WARNING, 0, '_payment');
715 setEventMessages($e->getMessage(), null, 'errors');
716 $action = '';
717 } catch (\Stripe\Exception\ExceptionInterface $e) {
718 // Display a very generic error to the user, and maybe send
719 // yourself an email
720 $error++;
721 $errormessage = "ErrorBase ".$e->getMessage();
722 dol_syslog($errormessage, LOG_WARNING, 0, '_payment');
723 setEventMessages($e->getMessage(), null, 'errors');
724 $action = '';
725 } catch (Exception $e) {
726 // Something else happened, completely unrelated to Stripe
727 $error++;
728 $errormessage = "ErrorException ".$e->getMessage();
729 dol_syslog($errormessage, LOG_WARNING, 0, '_payment');
730 setEventMessages($e->getMessage(), null, 'errors');
731 $action = '';
732 }
733 }
734
735 // When using the PaymentIntent API architecture (mode set on by default into conf.class.php)
736 if (getDolGlobalInt('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION')) {
737 $service = 'StripeTest';
738 $servicestatus = 0;
739 if (getDolGlobalString('STRIPE_LIVE') && !GETPOSTINT('forcesandbox')) {
740 $service = 'StripeLive';
741 $servicestatus = 1;
742 }
743 include_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php';
744 $stripe = new Stripe($db);
745 $stripeacc = $stripe->getStripeAccount($service);
746
747 // We go here if $conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION is set.
748 // In such a case, payment is always ok when we call the "charge" action.
749 $paymentintent_id = GETPOST("paymentintent_id", "alpha");
750
751 // Force to use the correct API key
752 global $stripearrayofkeysbyenv;
753 \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$servicestatus]['secret_key']);
754
755 try {
756 if (empty($stripeacc)) { // If the Stripe connect account not set, we use common API usage
757 $paymentintent = \Stripe\PaymentIntent::retrieve($paymentintent_id);
758 } else {
759 $paymentintent = \Stripe\PaymentIntent::retrieve($paymentintent_id, array("stripe_account" => $stripeacc));
760 }
761 } catch (Exception $e) {
762 $error++;
763 $errormessage = "CantRetrievePaymentIntent ".$e->getMessage();
764 dol_syslog($errormessage, LOG_WARNING, 0, '_payment');
765 setEventMessages($e->getMessage(), null, 'errors');
766 $action = '';
767 }
768
769 if ($paymentintent->status != 'succeeded') {
770 $error++;
771 $errormessage = "StatusOfRetrievedIntent is not succeeded: ".$paymentintent->status;
772 dol_syslog($errormessage, LOG_WARNING, 0, '_payment');
773 setEventMessages($paymentintent->status, null, 'errors');
774 $action = '';
775 } else {
776 // TODO We can also record the payment mode into llx_societe_rib with stripe $paymentintent->payment_method
777 // Note that with other old Stripe architecture (using Charge API), the payment mode was not recorded, so it is not mandatory to do it here.
778 //dol_syslog("Create payment_method for ".$paymentintent->payment_method, LOG_DEBUG, 0, '_payment');
779
780 // Get here amount and currency used for payment and force value into $amount and $currency so the real amount is saved into session instead
781 // of the amount and currency retrieved from the POST.
782 if (!empty($paymentintent->currency) && !empty($paymentintent->amount)) {
783 $currency = strtoupper($paymentintent->currency);
784 $amount = $paymentintent->amount;
785
786 // Correct the amount according to unit of currency
787 // See https://support.stripe.com/questions/which-zero-decimal-currencies-does-stripe-support
788 $arrayzerounitcurrency = array('BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'VND', 'VUV', 'XAF', 'XOF', 'XPF');
789 if (!in_array($currency, $arrayzerounitcurrency)) {
790 $amount = $amount / 100;
791 }
792 }
793 }
794 }
795
796
797 $remoteip = getUserRemoteIP();
798
799 $_SESSION["onlinetoken"] = $stripeToken;
800 $_SESSION["FinalPaymentAmt"] = $amount; // amount really paid (coming from Stripe). Will be used for check in paymentok.php.
801 $_SESSION["currencyCodeType"] = $currency; // currency really used for payment (coming from Stripe). Will be used for check in paymentok.php.
802 $_SESSION["paymentType"] = '';
803 $_SESSION['ipaddress'] = ($remoteip ? $remoteip : 'unknown'); // Payer ip
804 $_SESSION['payerID'] = is_object($customer) ? $customer->id : '';
805 $_SESSION['TRANSACTIONID'] = (is_object($charge) ? $charge->id : (is_object($paymentintent) ? $paymentintent->id : ''));
806 $_SESSION['errormessage'] = $errormessage;
807
808 dol_syslog("Action charge stripe STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION=".getDolGlobalInt('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION')." ip=".$remoteip, LOG_DEBUG, 0, '_payment');
809 dol_syslog("onlinetoken=".$_SESSION["onlinetoken"]." FinalPaymentAmt=".$_SESSION["FinalPaymentAmt"]." currencyCodeType=".$_SESSION["currencyCodeType"]." payerID=".$_SESSION['payerID']." TRANSACTIONID=".$_SESSION['TRANSACTIONID'], LOG_DEBUG, 0, '_payment');
810 dol_syslog("FULLTAG=".$FULLTAG, LOG_DEBUG, 0, '_payment');
811 dol_syslog("error=".$error." errormessage=".$errormessage, LOG_DEBUG, 0, '_payment');
812 dol_syslog("_SERVER[SERVER_NAME] = ".(empty($_SERVER["SERVER_NAME"]) ? '' : dol_escape_htmltag($_SERVER["SERVER_NAME"])), LOG_DEBUG, 0, '_payment');
813 dol_syslog("_SERVER[SERVER_ADDR] = ".(empty($_SERVER["SERVER_ADDR"]) ? '' : dol_escape_htmltag($_SERVER["SERVER_ADDR"])), LOG_DEBUG, 0, '_payment');
814 dol_syslog("Now call the redirect to paymentok or paymentko, URL = ".($error ? $urlko : $urlok), LOG_DEBUG, 0, '_payment');
815
816 if ($error) {
817 header("Location: ".$urlko);
818 exit;
819 } else {
820 header("Location: ".$urlok);
821 exit;
822 }
823}
824
825// This hook is used to push to $validpaymentmethod by external payment modules (ie Payzen, ...)
826$parameters = array(
827 'paymentmethod' => $paymentmethod,
828 'validpaymentmethod' => &$validpaymentmethod
829);
830$reshook = $hookmanager->executeHooks('doPayment', $parameters, $object, $action);
831if ($reshook < 0) {
832 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
833} elseif ($reshook > 0) {
834 print $hookmanager->resPrint;
835}
836
837
838
839/*
840 * View
841 */
842
843$form = new Form($db);
844
845$head = '';
846if (getDolGlobalString('ONLINE_PAYMENT_CSS_URL')) {
847 $head = '<link rel="stylesheet" type="text/css" href="' . getDolGlobalString('ONLINE_PAYMENT_CSS_URL').'?lang='.(!empty($getpostlang) ? $getpostlang : $langs->defaultlang).'">'."\n";
848}
849
850$conf->dol_hide_topmenu = 1;
851$conf->dol_hide_leftmenu = 1;
852
853$replacemainarea = (empty($conf->dol_hide_leftmenu) ? '<div>' : '').'<div>';
854llxHeader($head, $langs->trans("PaymentForm"), '', '', 0, 0, '', '', '', 'onlinepaymentbody', $replacemainarea);
855
856dol_syslog("newpayment.php show page source=".$source." paymentmethod=".$paymentmethod.' amount='.$amount.' newamount='.GETPOST("newamount", 'alpha')." ref=".$ref, LOG_DEBUG, 0, '_payment');
857dol_syslog("_SERVER[SERVER_NAME] = ".(empty($_SERVER["SERVER_NAME"]) ? '' : dol_escape_htmltag($_SERVER["SERVER_NAME"])), LOG_DEBUG, 0, '_payment');
858dol_syslog("_SERVER[SERVER_ADDR] = ".(empty($_SERVER["SERVER_ADDR"]) ? '' : dol_escape_htmltag($_SERVER["SERVER_ADDR"])), LOG_DEBUG, 0, '_payment');
859
860// Check link validity
861if ($source && in_array($ref, array('member_ref', 'contractline_ref', 'invoice_ref', 'order_ref', 'donation_ref', ''))) {
862 $langs->load("errors");
863 dol_print_error_email('BADREFINPAYMENTFORM', $langs->trans("ErrorBadLinkSourceSetButBadValueForRef", $source, $ref));
864 // End of page
865 llxFooter();
866 $db->close();
867 exit;
868}
869
870
871// Show sandbox warning
872if ((empty($paymentmethod) || $paymentmethod == 'paypal') && isModEnabled('paypal') && (getDolGlobalString('PAYPAL_API_SANDBOX') || GETPOSTINT('forcesandbox'))) { // We can force sand box with param 'forcesandbox'
873 dol_htmloutput_mesg($langs->trans('YouAreCurrentlyInSandboxMode', 'Paypal'), '', 'warning');
874}
875if ((empty($paymentmethod) || $paymentmethod == 'stripe') && isModEnabled('stripe') && (!getDolGlobalString('STRIPE_LIVE') || GETPOSTINT('forcesandbox'))) {
876 dol_htmloutput_mesg($langs->trans('YouAreCurrentlyInSandboxMode', 'Stripe'), '', 'warning');
877}
878
879
880print '<span id="dolpaymentspan"></span>'."\n";
881print '<div class="center">'."\n";
882print '<form id="dolpaymentform" class="center" name="paymentform" action="'.$_SERVER["PHP_SELF"].'" method="POST">'."\n";
883print '<input type="hidden" name="token" value="'.newToken().'">'."\n";
884print '<input type="hidden" name="action" value="dopayment">'."\n";
885print '<input type="hidden" name="tag" value="'.GETPOST("tag", 'alpha').'">'."\n";
886print '<input type="hidden" name="suffix" value="'.dol_escape_htmltag($suffix).'">'."\n";
887print '<input type="hidden" name="securekey" value="'.dol_escape_htmltag($SECUREKEY).'">'."\n";
888print '<input type="hidden" name="e" value="'.$entity.'" />';
889print '<input type="hidden" name="forcesandbox" value="'.GETPOSTINT('forcesandbox').'" />';
890print '<input type="hidden" name="lang" value="'.$getpostlang.'">';
891print '<input type="hidden" name="ws" value="'.$ws.'">';
892print "\n";
893
894
895// Show logo (search order: logo defined by PAYMENT_LOGO_suffix, then PAYMENT_LOGO, then small company logo, large company logo, theme logo, common logo)
896// Define logo and logosmall
897$logosmall = $mysoc->logo_small;
898$logo = $mysoc->logo;
899$paramlogo = 'ONLINE_PAYMENT_LOGO_'.$suffix;
900if (!empty($conf->global->$paramlogo)) {
901 $logosmall = getDolGlobalString($paramlogo);
902} elseif (getDolGlobalString('ONLINE_PAYMENT_LOGO')) {
903 $logosmall = getDolGlobalString('ONLINE_PAYMENT_LOGO');
904}
905//print '<!-- Show logo (logosmall='.$logosmall.' logo='.$logo.') -->'."\n";
906// Define urllogo
907$urllogo = '';
908$urllogofull = '';
909if (!empty($logosmall) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$logosmall)) {
910 $urllogo = DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;entity='.$conf->entity.'&amp;file='.urlencode('logos/thumbs/'.$logosmall);
911 $urllogofull = $dolibarr_main_url_root.'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.'&file='.urlencode('logos/thumbs/'.$logosmall);
912} elseif (!empty($logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$logo)) {
913 $urllogo = DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;entity='.$conf->entity.'&amp;file='.urlencode('logos/'.$logo);
914 $urllogofull = $dolibarr_main_url_root.'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.'&file='.urlencode('logos/'.$logo);
915}
916
917// Output html code for logo
918if ($urllogo && !$ws) {
919 print '<div class="backgreypublicpayment">';
920 print '<div class="logopublicpayment">';
921 print '<img id="dolpaymentlogo" src="'.$urllogo.'"';
922 print '>';
923 print '</div>';
924 if (!getDolGlobalString('MAIN_HIDE_POWERED_BY')) {
925 print '<div class="poweredbypublicpayment opacitymedium right"><a class="poweredbyhref" href="https://www.dolibarr.org?utm_medium=website&utm_source=poweredby" target="dolibarr" rel="noopener">'.$langs->trans("PoweredBy").'<br><img class="poweredbyimg" src="'.DOL_URL_ROOT.'/theme/dolibarr_logo.svg" width="80px"></a></div>';
926 }
927 print '</div>';
928} elseif ($creditor && !$ws) {
929 print '<div class="backgreypublicpayment">';
930 print '<div class="logopublicpayment">';
931 print $creditor;
932 print '</div>';
933 print '</div>';
934}
935if (getDolGlobalString('MAIN_IMAGE_PUBLIC_PAYMENT')) {
936 print '<div class="backimagepublicpayment">';
937 print '<img id="idMAIN_IMAGE_PUBLIC_PAYMENT" src="'.getDolGlobalString('MAIN_IMAGE_PUBLIC_PAYMENT').'">';
938 print '</div>';
939}
940
941
942
943
944print '<!-- Form to send a payment -->'."\n";
945print '<!-- creditor = '.dol_escape_htmltag($creditor).' -->'."\n";
946// Additional information for each payment system
947if (isModEnabled('paypal')) {
948 print '<!-- PAYPAL_API_SANDBOX = '.getDolGlobalString('PAYPAL_API_SANDBOX').' -->'."\n";
949 print '<!-- PAYPAL_API_INTEGRAL_OR_PAYPALONLY = '.getDolGlobalString('PAYPAL_API_INTEGRAL_OR_PAYPALONLY').' -->'."\n";
950}
951if (isModEnabled('paybox')) {
952 print '<!-- PAYBOX_CGI_URL = '.getDolGlobalString('PAYBOX_CGI_URL_V2').' -->'."\n";
953}
954if (isModEnabled('stripe')) {
955 print '<!-- STRIPE_LIVE = '.getDolGlobalString('STRIPE_LIVE').' -->'."\n";
956}
957print '<!-- urlok = '.$urlok.' -->'."\n";
958print '<!-- urlko = '.$urlko.' -->'."\n";
959print "\n";
960
961// Section with payment informationsummary
962print '<table id="dolpublictable" summary="Payment form" class="center">'."\n";
963
964// Output introduction text
965$text = '';
966if (getDolGlobalString('PAYMENT_NEWFORM_TEXT')) {
967 $langs->load("members");
968 if (preg_match('/^\‍((.*)\‍)$/', $conf->global->PAYMENT_NEWFORM_TEXT, $reg)) {
969 $text .= $langs->trans($reg[1])."<br>\n";
970 } else {
971 $text .= getDolGlobalString('PAYMENT_NEWFORM_TEXT') . "<br>\n";
972 }
973 $text = '<tr><td align="center"><br>'.$text.'<br></td></tr>'."\n";
974}
975if (empty($text)) {
976 $text .= '<tr><td class="textpublicpayment"><br><strong>'.$langs->trans("WelcomeOnPaymentPage").'</strong></td></tr>'."\n";
977 $text .= '<tr><td class="textpublicpayment"><span class="opacitymedium">'.$langs->trans("ThisScreenAllowsYouToPay", $creditor).'</span><br><br></td></tr>'."\n";
978}
979print $text;
980
981// Output payment summary form
982print '<tr><td align="center">'; // class=center does not have the payment button centered so we keep align here.
983print '<table class="centpercent left" id="tablepublicpayment">';
984print '<tr class="hideonsmartphone"><td colspan="2" align="left" class="opacitymedium">'.$langs->trans("ThisIsInformationOnPayment").' :</td></tr>'."\n";
985
986$found = false;
987$error = 0;
988
989$object = null;
990
991
992// Free payment
993if (!$source) {
994 $found = true;
995 $tag = GETPOST("tag", 'alpha');
996 if (GETPOST('fulltag', 'alpha')) {
997 $fulltag = GETPOST('fulltag', 'alpha');
998 } else {
999 $fulltag = "TAG=".$tag;
1000 }
1001
1002 // Creditor
1003 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Creditor");
1004 print '</td><td class="CTableRow2">';
1005 print img_picto('', 'company', 'class="pictofixedwidth"');
1006 print '<b>'.$creditor.'</b>';
1007 print '<input type="hidden" name="creditor" value="'.$creditor.'">';
1008 print '</td></tr>'."\n";
1009
1010 // Amount
1011 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Amount");
1012 if (empty($amount)) {
1013 print ' ('.$langs->trans("ToComplete").')';
1014 }
1015 print '</td><td class="CTableRow2">';
1016 if (empty($amount) || !is_numeric($amount)) {
1017 print '<input type="hidden" name="amount" value="'.price2num(GETPOST("amount", 'alpha'), 'MT').'">';
1018 print '<input class="flat maxwidth75" type="text" name="newamount" value="'.price2num(GETPOST("newamount", "alpha"), 'MT').'">';
1019 // Currency
1020 print ' <b>'.$langs->trans("Currency".$currency).'</b>';
1021 } else {
1022 print '<b class="amount">'.price($amount, 1, $langs, 1, -1, -1, $currency).'</b>'; // Price with currency
1023 print '<input type="hidden" name="amount" value="'.$amount.'">';
1024 print '<input type="hidden" name="newamount" value="'.$amount.'">';
1025 }
1026 print '<input type="hidden" name="currency" value="'.$currency.'">';
1027 print '</td></tr>'."\n";
1028
1029 // Tag
1030 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("PaymentCode");
1031 print '</td><td class="CTableRow2"><b style="word-break: break-all;">'.$fulltag.'</b>';
1032 print '<input type="hidden" name="tag" value="'.$tag.'">';
1033 print '<input type="hidden" name="fulltag" value="'.$fulltag.'">';
1034 print '</td></tr>'."\n";
1035
1036 // We do not add fields shipToName, shipToStreet, shipToCity, shipToState, shipToCountryCode, shipToZip, shipToStreet2, phoneNum
1037 // as they don't exists (buyer is unknown, tag is free).
1038}
1039
1040
1041// Payment on a Sale Order
1042if ($source == 'order') {
1043 $found = true;
1044 $langs->load("orders");
1045
1046 require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
1047
1048 $order = new Commande($db);
1049 $result = $order->fetch('', $ref);
1050 if ($result <= 0) {
1051 $mesg = $order->error;
1052 $error++;
1053 } else {
1054 $result = $order->fetch_thirdparty($order->socid);
1055 }
1056 $object = $order;
1057
1058 if ($action != 'dopayment') { // Do not change amount if we just click on first dopayment
1059 $amount = $order->total_ttc;
1060 if (GETPOST("amount", 'alpha')) {
1061 $amount = GETPOST("amount", 'alpha');
1062 }
1063 $amount = price2num($amount);
1064 }
1065
1066 $tag = '';
1067 if (GETPOST('fulltag', 'alpha')) {
1068 $fulltag = GETPOST('fulltag', 'alpha');
1069 } else {
1070 $fulltag = 'ORD='.$order->id.'.CUS='.$order->thirdparty->id;
1071 if (!empty($TAG)) {
1072 $tag = $TAG;
1073 $fulltag .= '.TAG='.$TAG;
1074 }
1075 }
1076 $fulltag = dol_string_unaccent($fulltag);
1077
1078 // Creditor
1079 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Creditor");
1080 print '</td><td class="CTableRow2">';
1081 print img_picto('', 'company', 'class="pictofixedwidth"');
1082 print '<b>'.$creditor.'</b>';
1083 print '<input type="hidden" name="creditor" value="'.$creditor.'">';
1084 print '</td></tr>'."\n";
1085
1086 // Debitor
1087 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("ThirdParty");
1088 print '</td><td class="CTableRow2">';
1089 print img_picto('', 'company', 'class="pictofixedwidth"');
1090 print '<b>'.$order->thirdparty->name.'</b>';
1091 print '</td></tr>'."\n";
1092
1093 // Object
1094 $text = '<b>'.$langs->trans("PaymentOrderRef", $order->ref).'</b>';
1095 if (GETPOST('desc', 'alpha')) {
1096 $text = '<b>'.$langs->trans(GETPOST('desc', 'alpha')).'</b>';
1097 }
1098 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Designation");
1099 print '</td><td class="CTableRow2">'.$text;
1100 print '<input type="hidden" name="s" value="'.dol_escape_htmltag($source).'">';
1101 print '<input type="hidden" name="ref" value="'.dol_escape_htmltag($order->ref).'">';
1102 print '<input type="hidden" name="dol_id" value="'.dol_escape_htmltag($order->id).'">';
1103 $directdownloadlink = $order->getLastMainDocLink('commande');
1104 if ($directdownloadlink) {
1105 print '<br><a href="'.$directdownloadlink.'" rel="nofollow noopener">';
1106 print img_mime($order->last_main_doc, '');
1107 print $langs->trans("DownloadDocument").'</a>';
1108 }
1109 print '</td></tr>'."\n";
1110
1111 // Amount
1112 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Amount");
1113 if (empty($amount)) {
1114 print ' ('.$langs->trans("ToComplete").')';
1115 }
1116 print '</td><td class="CTableRow2">';
1117 if (empty($amount) || !is_numeric($amount)) {
1118 print '<input type="hidden" name="amount" value="'.price2num(GETPOST("amount", 'alpha'), 'MT').'">';
1119 print '<input class="flat maxwidth75" type="text" name="newamount" value="'.price2num(GETPOST("newamount", "alpha"), 'MT').'">';
1120 // Currency
1121 print ' <b>'.$langs->trans("Currency".$currency).'</b>';
1122 } else {
1123 print '<b class="amount">'.price($amount, 1, $langs, 1, -1, -1, $currency).'</b>'; // Price with currency
1124 print '<input type="hidden" name="amount" value="'.$amount.'">';
1125 print '<input type="hidden" name="newamount" value="'.$amount.'">';
1126 }
1127 print '<input type="hidden" name="currency" value="'.$currency.'">';
1128 print '</td></tr>'."\n";
1129
1130 // Tag
1131 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("PaymentCode");
1132 print '</td><td class="CTableRow2"><b style="word-break: break-all;">'.$fulltag.'</b>';
1133 print '<input type="hidden" name="tag" value="'.dol_escape_htmltag($tag).'">';
1134 print '<input type="hidden" name="fulltag" value="'.dol_escape_htmltag($fulltag).'">';
1135 print '</td></tr>'."\n";
1136
1137 // Shipping address
1138 $shipToName = $order->thirdparty->name;
1139 $shipToStreet = $order->thirdparty->address;
1140 $shipToCity = $order->thirdparty->town;
1141 $shipToState = $order->thirdparty->state_code;
1142 $shipToCountryCode = $order->thirdparty->country_code;
1143 $shipToZip = $order->thirdparty->zip;
1144 $shipToStreet2 = '';
1145 $phoneNum = $order->thirdparty->phone;
1146 if ($shipToName && $shipToStreet && $shipToCity && $shipToCountryCode && $shipToZip) {
1147 print '<input type="hidden" name="shipToName" value="'.dol_escape_htmltag($shipToName).'">'."\n";
1148 print '<input type="hidden" name="shipToStreet" value="'.dol_escape_htmltag($shipToStreet).'">'."\n";
1149 print '<input type="hidden" name="shipToCity" value="'.dol_escape_htmltag($shipToCity).'">'."\n";
1150 print '<input type="hidden" name="shipToState" value="'.dol_escape_htmltag($shipToState).'">'."\n";
1151 print '<input type="hidden" name="shipToCountryCode" value="'.dol_escape_htmltag($shipToCountryCode).'">'."\n";
1152 print '<input type="hidden" name="shipToZip" value="'.dol_escape_htmltag($shipToZip).'">'."\n";
1153 print '<input type="hidden" name="shipToStreet2" value="'.dol_escape_htmltag($shipToStreet2).'">'."\n";
1154 print '<input type="hidden" name="phoneNum" value="'.dol_escape_htmltag($phoneNum).'">'."\n";
1155 } else {
1156 print '<!-- Shipping address not complete, so we don t use it -->'."\n";
1157 }
1158 if (is_object($order->thirdparty)) {
1159 print '<input type="hidden" name="thirdparty_id" value="'.$order->thirdparty->id.'">'."\n";
1160 }
1161 print '<input type="hidden" name="email" value="'.$order->thirdparty->email.'">'."\n";
1162 print '<input type="hidden" name="vatnumber" value="'.dol_escape_htmltag($order->thirdparty->tva_intra).'">'."\n";
1163 $labeldesc = $langs->trans("Order").' '.$order->ref;
1164 if (GETPOST('desc', 'alpha')) {
1165 $labeldesc = GETPOST('desc', 'alpha');
1166 }
1167 print '<input type="hidden" name="desc" value="'.dol_escape_htmltag($labeldesc).'">'."\n";
1168}
1169
1170
1171// Payment on a Customer Invoice
1172if ($source == 'invoice') {
1173 $found = true;
1174 $langs->load("bills");
1175 $form->load_cache_types_paiements();
1176
1177 require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
1178
1179 $invoice = new Facture($db);
1180 $result = $invoice->fetch('', $ref);
1181 if ($result <= 0) {
1182 $mesg = $invoice->error;
1183 $error++;
1184 } else {
1185 $result = $invoice->fetch_thirdparty($invoice->socid);
1186 }
1187 $object = $invoice;
1188
1189 if ($action != 'dopayment') { // Do not change amount if we just click on first dopayment
1190 $amount = price2num($invoice->total_ttc - ($invoice->getSommePaiement() + $invoice->getSumCreditNotesUsed() + $invoice->getSumDepositsUsed()));
1191 if (GETPOST("amount", 'alpha')) {
1192 $amount = GETPOST("amount", 'alpha');
1193 }
1194 $amount = price2num($amount);
1195 }
1196
1197 if (GETPOST('fulltag', 'alpha')) {
1198 $fulltag = GETPOST('fulltag', 'alpha');
1199 } else {
1200 $fulltag = 'INV='.$invoice->id.'.CUS='.$invoice->thirdparty->id;
1201 if (!empty($TAG)) {
1202 $tag = $TAG;
1203 $fulltag .= '.TAG='.$TAG;
1204 }
1205 }
1206 $fulltag = dol_string_unaccent($fulltag);
1207
1208 // Creditor
1209 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Creditor");
1210 print '</td><td class="CTableRow2">';
1211 print img_picto('', 'company', 'class="pictofixedwidth"');
1212 print '<b>'.$creditor.'</b>';
1213 print '<input type="hidden" name="creditor" value="'.dol_escape_htmltag($creditor).'">';
1214 print '</td></tr>'."\n";
1215
1216 // Debitor
1217 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("ThirdParty");
1218 print '</td><td class="CTableRow2">';
1219 print img_picto('', 'company', 'class="pictofixedwidth"');
1220 print '<b>'.$invoice->thirdparty->name.'</b>';
1221 print '</td></tr>'."\n";
1222
1223 // Object
1224 $text = '<b>'.$langs->trans("PaymentInvoiceRef", $invoice->ref).'</b>';
1225 if (GETPOST('desc', 'alpha')) {
1226 $text = '<b>'.$langs->trans(GETPOST('desc', 'alpha')).'</b>';
1227 }
1228 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Designation");
1229 print '</td><td class="CTableRow2">'.$text;
1230 print '<input type="hidden" name="s" value="'.dol_escape_htmltag($source).'">';
1231 print '<input type="hidden" name="ref" value="'.dol_escape_htmltag($invoice->ref).'">';
1232 print '<input type="hidden" name="dol_id" value="'.dol_escape_htmltag($invoice->id).'">';
1233 $directdownloadlink = $invoice->getLastMainDocLink('facture');
1234 if ($directdownloadlink) {
1235 print '<br><a href="'.$directdownloadlink.'">';
1236 print img_mime($invoice->last_main_doc, '');
1237 print $langs->trans("DownloadDocument").'</a>';
1238 }
1239 print '</td></tr>'."\n";
1240
1241 // Amount
1242 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("PaymentAmount");
1243 if (empty($amount) && empty($object->paye)) {
1244 print ' ('.$langs->trans("ToComplete").')';
1245 }
1246 print '</td><td class="CTableRow2">';
1247 if ($object->type == $object::TYPE_CREDIT_NOTE) {
1248 print '<b>'.$langs->trans("CreditNote").'</b>';
1249 } elseif (empty($object->paye)) {
1250 if (empty($amount) || !is_numeric($amount)) {
1251 print '<input type="hidden" name="amount" value="'.price2num(GETPOST("amount", 'alpha'), 'MT').'">';
1252 print '<input class="flat maxwidth75" type="text" name="newamount" value="'.price2num(GETPOST("newamount", "alpha"), 'MT').'">';
1253 print ' <b>'.$langs->trans("Currency".$currency).'</b>';
1254 } else {
1255 print '<b class="amount">'.price($amount, 1, $langs, 1, -1, -1, $currency).'</b>'; // Price with currency
1256 print '<input type="hidden" name="amount" value="'.$amount.'">';
1257 print '<input type="hidden" name="newamount" value="'.$amount.'">';
1258 }
1259 } else {
1260 print '<b class="amount">'.price($object->total_ttc, 1, $langs, 1, -1, -1, $currency).'</b>'; // Price with currency
1261 }
1262 print '<input type="hidden" name="currency" value="'.$currency.'">';
1263 print '</td></tr>'."\n";
1264
1265 // Tag
1266 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("PaymentCode");
1267 print '</td><td class="CTableRow2"><b style="word-break: break-all;">'.$fulltag.'</b>';
1268 print '<input type="hidden" name="tag" value="'.(empty($tag) ? '' : $tag).'">';
1269 print '<input type="hidden" name="fulltag" value="'.$fulltag.'">';
1270 print '</td></tr>'."\n";
1271
1272 // Add a warning if we try to pay an invoice set to be paid in credit transfer
1273 if ($invoice->status == $invoice::STATUS_VALIDATED && $invoice->mode_reglement_id > 0 && $form->cache_types_paiements[$invoice->mode_reglement_id]["code"] == "VIR") {
1274 print '<tr class="CTableRow2 center"><td class="CTableRow2" colspan="2">';
1275 print '<div class="warning maxwidth1000">';
1276 print $langs->trans("PayOfBankTransferInvoice");
1277 print '</div>';
1278 print '</td></tr>'."\n";
1279 }
1280
1281 // Shipping address
1282 $shipToName = $invoice->thirdparty->name;
1283 $shipToStreet = $invoice->thirdparty->address;
1284 $shipToCity = $invoice->thirdparty->town;
1285 $shipToState = $invoice->thirdparty->state_code;
1286 $shipToCountryCode = $invoice->thirdparty->country_code;
1287 $shipToZip = $invoice->thirdparty->zip;
1288 $shipToStreet2 = '';
1289 $phoneNum = $invoice->thirdparty->phone;
1290 if ($shipToName && $shipToStreet && $shipToCity && $shipToCountryCode && $shipToZip) {
1291 print '<input type="hidden" name="shipToName" value="'.$shipToName.'">'."\n";
1292 print '<input type="hidden" name="shipToStreet" value="'.$shipToStreet.'">'."\n";
1293 print '<input type="hidden" name="shipToCity" value="'.$shipToCity.'">'."\n";
1294 print '<input type="hidden" name="shipToState" value="'.$shipToState.'">'."\n";
1295 print '<input type="hidden" name="shipToCountryCode" value="'.$shipToCountryCode.'">'."\n";
1296 print '<input type="hidden" name="shipToZip" value="'.$shipToZip.'">'."\n";
1297 print '<input type="hidden" name="shipToStreet2" value="'.$shipToStreet2.'">'."\n";
1298 print '<input type="hidden" name="phoneNum" value="'.$phoneNum.'">'."\n";
1299 } else {
1300 print '<!-- Shipping address not complete, so we don t use it -->'."\n";
1301 }
1302 if (is_object($invoice->thirdparty)) {
1303 print '<input type="hidden" name="thirdparty_id" value="'.$invoice->thirdparty->id.'">'."\n";
1304 }
1305 print '<input type="hidden" name="email" value="'.$invoice->thirdparty->email.'">'."\n";
1306 print '<input type="hidden" name="vatnumber" value="'.$invoice->thirdparty->tva_intra.'">'."\n";
1307 $labeldesc = $langs->trans("Invoice").' '.$invoice->ref;
1308 if (GETPOST('desc', 'alpha')) {
1309 $labeldesc = GETPOST('desc', 'alpha');
1310 }
1311 print '<input type="hidden" name="desc" value="'.dol_escape_htmltag($labeldesc).'">'."\n";
1312}
1313
1314// Payment on a Contract line
1315if ($source == 'contractline') {
1316 $found = true;
1317 $langs->load("contracts");
1318
1319 require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
1320
1321 $contract = new Contrat($db);
1322 $contractline = new ContratLigne($db);
1323
1324 $result = $contractline->fetch('', $ref);
1325 if ($result <= 0) {
1326 $mesg = $contractline->error;
1327 $error++;
1328 } else {
1329 if ($contractline->fk_contrat > 0) {
1330 $result = $contract->fetch($contractline->fk_contrat);
1331 if ($result > 0) {
1332 $result = $contract->fetch_thirdparty($contract->socid);
1333 } else {
1334 $mesg = $contract->error;
1335 $error++;
1336 }
1337 } else {
1338 $mesg = 'ErrorRecordNotFound';
1339 $error++;
1340 }
1341 }
1342 $object = $contractline;
1343
1344 if ($action != 'dopayment') { // Do not change amount if we just click on first dopayment
1345 $amount = $contractline->total_ttc;
1346
1347 if ($contractline->fk_product && getDolGlobalString('PAYMENT_USE_NEW_PRICE_FOR_CONTRACTLINES')) {
1348 $product = new Product($db);
1349 $result = $product->fetch($contractline->fk_product);
1350
1351 // We define price for product (TODO Put this in a method in product class)
1352 if (getDolGlobalString('PRODUIT_MULTIPRICES')) {
1353 $pu_ht = $product->multiprices[$contract->thirdparty->price_level];
1354 $pu_ttc = $product->multiprices_ttc[$contract->thirdparty->price_level];
1355 $price_base_type = $product->multiprices_base_type[$contract->thirdparty->price_level];
1356 } else {
1357 $pu_ht = $product->price;
1358 $pu_ttc = $product->price_ttc;
1359 $price_base_type = $product->price_base_type;
1360 }
1361
1362 $amount = $pu_ttc;
1363 if (empty($amount)) {
1364 dol_print_error(null, 'ErrorNoPriceDefinedForThisProduct');
1365 exit;
1366 }
1367 }
1368
1369 if (GETPOST("amount", 'alpha')) {
1370 $amount = GETPOST("amount", 'alpha');
1371 }
1372 $amount = price2num($amount);
1373 }
1374
1375 if (GETPOST('fulltag', 'alpha')) {
1376 $fulltag = GETPOST('fulltag', 'alpha');
1377 } else {
1378 $fulltag = 'COL='.$contractline->id.'.CON='.$contract->id.'.CUS='.$contract->thirdparty->id.'.DAT='.dol_print_date(dol_now(), '%Y%m%d%H%M%S');
1379 if (!empty($TAG)) {
1380 $tag = $TAG;
1381 $fulltag .= '.TAG='.$TAG;
1382 }
1383 }
1384 $fulltag = dol_string_unaccent($fulltag);
1385
1386 $qty = 1;
1387 if (GETPOST('qty')) {
1388 $qty = price2num(GETPOST('qty', 'alpha'), 'MS');
1389 }
1390
1391 // Creditor
1392 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Creditor");
1393 print '</td><td class="CTableRow2"><b>'.$creditor.'</b>';
1394 print '<input type="hidden" name="creditor" value="'.$creditor.'">';
1395 print '</td></tr>'."\n";
1396
1397 // Debitor
1398 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("ThirdParty");
1399 print '</td><td class="CTableRow2"><b>'.$contract->thirdparty->name.'</b>';
1400 print '</td></tr>'."\n";
1401
1402 // Object
1403 $text = '<b>'.$langs->trans("PaymentRenewContractId", $contract->ref, $contractline->ref).'</b>';
1404 if ($contractline->fk_product > 0) {
1405 $contractline->fetch_product();
1406 $text .= '<br>'.$contractline->product->ref.($contractline->product->label ? ' - '.$contractline->product->label : '');
1407 }
1408 if ($contractline->description) {
1409 $text .= '<br>'.dol_htmlentitiesbr($contractline->description);
1410 }
1411 if ($contractline->date_end) {
1412 $text .= '<br>'.$langs->trans("ExpiredSince").': '.dol_print_date($contractline->date_end);
1413 }
1414 if (GETPOST('desc', 'alpha')) {
1415 $text = '<b>'.$langs->trans(GETPOST('desc', 'alpha')).'</b>';
1416 }
1417 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Designation");
1418 print '</td><td class="CTableRow2">'.$text;
1419 print '<input type="hidden" name="source" value="'.dol_escape_htmltag($source).'">';
1420 print '<input type="hidden" name="ref" value="'.dol_escape_htmltag($contractline->ref).'">';
1421 print '<input type="hidden" name="dol_id" value="'.dol_escape_htmltag($contractline->id).'">';
1422 $directdownloadlink = $contract->getLastMainDocLink('contract');
1423 if ($directdownloadlink) {
1424 print '<br><a href="'.$directdownloadlink.'">';
1425 print img_mime($contract->last_main_doc, '');
1426 print $langs->trans("DownloadDocument").'</a>';
1427 }
1428 print '</td></tr>'."\n";
1429
1430 // Quantity
1431 $label = $langs->trans("Quantity");
1432 $qty = 1;
1433 $duration = '';
1434 if ($contractline->fk_product) {
1435 if ($contractline->product->isService() && $contractline->product->duration_value > 0) {
1436 $label = $langs->trans("Duration");
1437
1438 // TODO Put this in a global method
1439 if ($contractline->product->duration_value > 1) {
1440 $dur = array("h" => $langs->trans("Hours"), "d" => $langs->trans("DurationDays"), "w" => $langs->trans("DurationWeeks"), "m" => $langs->trans("DurationMonths"), "y" => $langs->trans("DurationYears"));
1441 } else {
1442 $dur = array("h" => $langs->trans("Hour"), "d" => $langs->trans("DurationDay"), "w" => $langs->trans("DurationWeek"), "m" => $langs->trans("DurationMonth"), "y" => $langs->trans("DurationYear"));
1443 }
1444 $duration = $contractline->product->duration_value.' '.$dur[$contractline->product->duration_unit];
1445 }
1446 }
1447 print '<tr class="CTableRow2"><td class="CTableRow2">'.$label.'</td>';
1448 print '<td class="CTableRow2"><b>'.($duration ? $duration : $qty).'</b>';
1449 print '<input type="hidden" name="newqty" value="'.dol_escape_htmltag($qty).'">';
1450 print '</b></td></tr>'."\n";
1451
1452 // Amount
1453 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Amount");
1454 if (empty($amount)) {
1455 print ' ('.$langs->trans("ToComplete").')';
1456 }
1457 print '</td><td class="CTableRow2">';
1458 if (empty($amount) || !is_numeric($amount)) {
1459 print '<input type="hidden" name="amount" value="'.price2num(GETPOST("amount", 'alpha'), 'MT').'">';
1460 print '<input class="flat maxwidth75" type="text" name="newamount" value="'.price2num(GETPOST("newamount", "alpha"), 'MT').'">';
1461 // Currency
1462 print ' <b>'.$langs->trans("Currency".$currency).'</b>';
1463 } else {
1464 print '<b class="amount">'.price($amount, 1, $langs, 1, -1, -1, $currency).'</b>'; // Price with currency
1465 print '<input type="hidden" name="amount" value="'.$amount.'">';
1466 print '<input type="hidden" name="newamount" value="'.$amount.'">';
1467 }
1468 print '<input type="hidden" name="currency" value="'.$currency.'">';
1469 print '</td></tr>'."\n";
1470
1471 // Tag
1472 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("PaymentCode");
1473 print '</td><td class="CTableRow2"><b style="word-break: break-all;">'.$fulltag.'</b>';
1474 print '<input type="hidden" name="tag" value="'.$tag.'">';
1475 print '<input type="hidden" name="fulltag" value="'.$fulltag.'">';
1476 print '</td></tr>'."\n";
1477
1478 // Shipping address
1479 $shipToName = $contract->thirdparty->name;
1480 $shipToStreet = $contract->thirdparty->address;
1481 $shipToCity = $contract->thirdparty->town;
1482 $shipToState = $contract->thirdparty->state_code;
1483 $shipToCountryCode = $contract->thirdparty->country_code;
1484 $shipToZip = $contract->thirdparty->zip;
1485 $shipToStreet2 = '';
1486 $phoneNum = $contract->thirdparty->phone;
1487 if ($shipToName && $shipToStreet && $shipToCity && $shipToCountryCode && $shipToZip) {
1488 print '<input type="hidden" name="shipToName" value="'.$shipToName.'">'."\n";
1489 print '<input type="hidden" name="shipToStreet" value="'.$shipToStreet.'">'."\n";
1490 print '<input type="hidden" name="shipToCity" value="'.$shipToCity.'">'."\n";
1491 print '<input type="hidden" name="shipToState" value="'.$shipToState.'">'."\n";
1492 print '<input type="hidden" name="shipToCountryCode" value="'.$shipToCountryCode.'">'."\n";
1493 print '<input type="hidden" name="shipToZip" value="'.$shipToZip.'">'."\n";
1494 print '<input type="hidden" name="shipToStreet2" value="'.$shipToStreet2.'">'."\n";
1495 print '<input type="hidden" name="phoneNum" value="'.$phoneNum.'">'."\n";
1496 } else {
1497 print '<!-- Shipping address not complete, so we don t use it -->'."\n";
1498 }
1499 if (is_object($contract->thirdparty)) {
1500 print '<input type="hidden" name="thirdparty_id" value="'.$contract->thirdparty->id.'">'."\n";
1501 }
1502 print '<input type="hidden" name="email" value="'.$contract->thirdparty->email.'">'."\n";
1503 print '<input type="hidden" name="vatnumber" value="'.$contract->thirdparty->tva_intra.'">'."\n";
1504 $labeldesc = $langs->trans("Contract").' '.$contract->ref;
1505 if (GETPOST('desc', 'alpha')) {
1506 $labeldesc = GETPOST('desc', 'alpha');
1507 }
1508 print '<input type="hidden" name="desc" value="'.dol_escape_htmltag($labeldesc).'">'."\n";
1509}
1510
1511// Payment on a Member subscription
1512if ($source == 'member' || $source == 'membersubscription') {
1513 $newsource = 'member';
1514
1515 $tag = "";
1516 $found = true;
1517 $langs->load("members");
1518
1519 require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
1520 require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php';
1521 require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
1522
1523 $member = new Adherent($db);
1524 $adht = new AdherentType($db);
1525
1526 $result = $member->fetch('', $ref, 0, '', true, true); // This fetch also ->last_subscription_amount
1527 if ($result <= 0) {
1528 $mesg = $member->error;
1529 $error++;
1530 } else {
1531 $member->fetch_thirdparty();
1532
1533 $adht->fetch($member->typeid);
1534 }
1535 $object = $member;
1536
1537 if ($action != 'dopayment') { // Do not change amount if we just click on first dopayment
1538 $amount = $member->last_subscription_amount;
1539 if (GETPOST("amount", 'alpha')) {
1540 $amount = price2num(GETPOST("amount", 'alpha'), 'MT', 2);
1541 }
1542 // If amount still not defined, we take amount of the type of member
1543 if (empty($amount)) {
1544 $amount = $adht->amount;
1545 }
1546
1547 $amount = max(0, price2num($amount, 'MT'));
1548 }
1549
1550 if (GETPOST('fulltag', 'alpha')) {
1551 $fulltag = GETPOST('fulltag', 'alpha');
1552 } else {
1553 $fulltag = 'MEM='.$member->id.'.DAT='.dol_print_date(dol_now(), '%Y%m%d%H%M%S');
1554 if (!empty($TAG)) {
1555 $tag = $TAG;
1556 $fulltag .= '.TAG='.$TAG;
1557 }
1558 }
1559 $fulltag = dol_string_unaccent($fulltag);
1560
1561 // Creditor
1562 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Creditor");
1563 print '</td><td class="CTableRow2"><b>'.$creditor.'</b>';
1564 print '<input type="hidden" name="creditor" value="'.$creditor.'">';
1565 print '</td></tr>'."\n";
1566
1567 // Debitor
1568 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Member");
1569 print '</td><td class="CTableRow2">';
1570 print '<b>';
1571 if ($member->morphy == 'mor' && !empty($member->company)) {
1572 print img_picto('', 'company', 'class="pictofixedwidth"');
1573 print $member->company;
1574 } else {
1575 print img_picto('', 'member', 'class="pictofixedwidth"');
1576 print $member->getFullName($langs);
1577 }
1578 print '</b>';
1579 print '</td></tr>'."\n";
1580
1581 // Object
1582 $text = '<b>'.$langs->trans("PaymentSubscription").'</b>';
1583 if (GETPOST('desc', 'alpha')) {
1584 $text = '<b>'.$langs->trans(GETPOST('desc', 'alpha')).'</b>';
1585 }
1586 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Designation");
1587 print '</td><td class="CTableRow2">'.$text;
1588 print '<input type="hidden" name="source" value="'.dol_escape_htmltag($newsource).'">';
1589 print '<input type="hidden" name="ref" value="'.dol_escape_htmltag($member->ref).'">';
1590 print '</td></tr>'."\n";
1591
1592 if ($object->datefin > 0) {
1593 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("DateEndSubscription");
1594 print '</td><td class="CTableRow2">'.dol_print_date($member->datefin, 'day');
1595 print '</td></tr>'."\n";
1596 }
1597
1598 if ($member->last_subscription_date || $member->last_subscription_amount) {
1599 // Last subscription date
1600
1601 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("LastSubscriptionDate");
1602 print '</td><td class="CTableRow2">'.dol_print_date($member->last_subscription_date, 'day');
1603 print '</td></tr>'."\n";
1604
1605 // Last subscription amount
1606
1607 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("LastSubscriptionAmount");
1608 print '</td><td class="CTableRow2">'.price($member->last_subscription_amount);
1609 print '</td></tr>'."\n";
1610
1611 if (empty($amount) && !GETPOST('newamount', 'alpha')) {
1612 $_GET['newamount'] = $member->last_subscription_amount;
1613 $_GET['amount'] = $member->last_subscription_amount;
1614 }
1615 if (!empty($member->last_subscription_amount) && !GETPOSTISSET('newamount') && is_numeric($amount)) {
1616 $amount = max($member->last_subscription_amount, $amount);
1617 }
1618 }
1619
1620 $amountbytype = $adht->amountByType(1);
1621
1622 $typeid = $adht->id;
1623 $caneditamount = $adht->caneditamount;
1624
1625 if ($member->type) {
1626 $oldtypeid = $member->typeid;
1627 $newtypeid = (int) (GETPOSTISSET("typeid") ? GETPOSTINT("typeid") : $member->typeid);
1628 if (getDolGlobalString('MEMBER_ALLOW_CHANGE_OF_TYPE')) {
1629 $typeid = $newtypeid;
1630 $adht->fetch($typeid); // Reload with the new type id
1631 }
1632
1633 $caneditamount = $adht->caneditamount;
1634
1635 if (getDolGlobalString('MEMBER_ALLOW_CHANGE_OF_TYPE')) {
1636 // Last member type
1637 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("LastMemberType");
1638 print '</td><td class="CTableRow2">'.dol_escape_htmltag($member->type);
1639 print "</td></tr>\n";
1640
1641 // Set the new member type
1642 $member->typeid = $newtypeid;
1643 $member->type = (string) dol_getIdFromCode($db, $newtypeid, 'adherent_type', 'rowid', 'libelle');
1644
1645 // list member type
1646 if (!$action) {
1647 // Set amount for the subscription.
1648 // If we change the type, we use the amount of the new type and not the amount of last subscription.
1649 $amount = (!empty($amountbytype[$member->typeid])) ? $amountbytype[$member->typeid] : $member->last_subscription_amount;
1650
1651 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("NewSubscription");
1652 print '</td><td class="CTableRow2">';
1653 print $form->selectarray("typeid", $adht->liste_array(1), $member->typeid, 0, 0, 0, 'onchange="window.location.replace(\''.$urlwithroot.'/public/payment/newpayment.php?source='.urlencode($source).'&ref='.urlencode($ref).'&amount='.urlencode($amount).'&typeid=\' + this.value + \'&securekey='.urlencode($SECUREKEY).'\');"', 0, 0, 0, '', '', 1);
1654 print "</td></tr>\n";
1655 } elseif ($action == 'dopayment') {
1656 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("NewMemberType");
1657 print '</td><td class="CTableRow2">'.dol_escape_htmltag($member->type);
1658 print '<input type="hidden" name="membertypeid" value="'.$member->typeid.'">';
1659 print "</td></tr>\n";
1660 }
1661 } else {
1662 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("MemberType");
1663 print '</td><td class="CTableRow2">'.dol_escape_htmltag($member->type);
1664 print "</td></tr>\n";
1665 }
1666 }
1667
1668 // Set amount for the subscription from the the type and options:
1669 // - First check the amount of the member type if not previous payment.
1670 $amount = ($member->last_subscription_amount ? $member->last_subscription_amount : (empty($amountbytype[$typeid]) ? 0 : $amountbytype[$typeid]));
1671 // - If not found, take the default amount
1672 if (empty($amount) && getDolGlobalString('MEMBER_NEWFORM_AMOUNT')) {
1673 $amount = getDolGlobalString('MEMBER_NEWFORM_AMOUNT');
1674 }
1675 // - If an amount was posted from the form (for example from page with types of membership)
1676 if ($caneditamount && GETPOSTISSET('amount') && GETPOSTFLOAT('amount', 'MT') > 0) {
1677 $amount = GETPOSTFLOAT('amount', 'MT');
1678 }
1679 // - If a new amount was posted from the form
1680 if ($caneditamount && GETPOSTISSET('newamount') && GETPOSTFLOAT('newamount', 'MT') > 0) {
1681 $amount = GETPOSTFLOAT('newamount', 'MT');
1682 }
1683 // - If a min is set or an amount from the posted form, we take them into account
1684 $amount = max(0, (float) $amount, (float) getDolGlobalInt("MEMBER_MIN_AMOUNT"));
1685
1686 // Amount
1687 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Amount");
1688 // This place no longer allows amount edition
1689 if (getDolGlobalString('MEMBER_EXT_URL_SUBSCRIPTION_INFO')) {
1690 print ' - <a href="' . getDolGlobalString('MEMBER_EXT_URL_SUBSCRIPTION_INFO').'" rel="external" target="_blank" rel="noopener noreferrer">'.$langs->trans("SeeHere").'</a>';
1691 }
1692 print '</td><td class="CTableRow2">';
1693
1694 $caneditamount = $adht->caneditamount;
1695 $minimumamount = !getDolGlobalString('MEMBER_MIN_AMOUNT') ? $adht->amount : max(getDolGlobalString('MEMBER_MIN_AMOUNT'), $adht->amount, $amount);
1696
1697 if ($caneditamount && $action != 'dopayment') {
1698 if (GETPOSTISSET('newamount')) {
1699 print '<input type="text" class="width75" name="newamount" value="'.price(price2num(GETPOST('newamount'), '', 2), 1, $langs, 1, -1, -1).'">';
1700 } else {
1701 print '<input type="text" class="width75" name="newamount" value="'.price($amount, 1, $langs, 1, -1, -1).'">';
1702 }
1703 } else {
1704 print '<b class="amount">'.price($amount, 1, $langs, 1, -1, -1, $currency).'</b>'; // Price with currency
1705 if ($minimumamount > $amount) {
1706 print ' &nbsp; <span class="opacitymedium small">'. $langs->trans("AmountIsLowerToMinimumNotice", price($minimumamount, 1, $langs, 1, -1, -1, $currency)).'</span>';
1707 }
1708 print '<input type="hidden" name="newamount" value="'.$amount.'">';
1709 }
1710 print '<input type="hidden" name="amount" value="'.$amount.'">';
1711 print '<input type="hidden" name="currency" value="'.$currency.'">';
1712 print '</td></tr>'."\n";
1713
1714 // Tag
1715 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("PaymentCode");
1716 print '</td><td class="CTableRow2"><b style="word-break: break-all;">'.$fulltag.'</b>';
1717 print '<input type="hidden" name="tag" value="'.$tag.'">';
1718 print '<input type="hidden" name="fulltag" value="'.$fulltag.'">';
1719 print '</td></tr>'."\n";
1720
1721 // Shipping address
1722 $shipToName = $member->getFullName($langs);
1723 $shipToStreet = $member->address;
1724 $shipToCity = $member->town;
1725 $shipToState = $member->state_code;
1726 $shipToCountryCode = $member->country_code;
1727 $shipToZip = $member->zip;
1728 $shipToStreet2 = '';
1729 $phoneNum = $member->phone;
1730 if ($shipToName && $shipToStreet && $shipToCity && $shipToCountryCode && $shipToZip) {
1731 print '<!-- Shipping address information -->';
1732 print '<input type="hidden" name="shipToName" value="'.$shipToName.'">'."\n";
1733 print '<input type="hidden" name="shipToStreet" value="'.$shipToStreet.'">'."\n";
1734 print '<input type="hidden" name="shipToCity" value="'.$shipToCity.'">'."\n";
1735 print '<input type="hidden" name="shipToState" value="'.$shipToState.'">'."\n";
1736 print '<input type="hidden" name="shipToCountryCode" value="'.$shipToCountryCode.'">'."\n";
1737 print '<input type="hidden" name="shipToZip" value="'.$shipToZip.'">'."\n";
1738 print '<input type="hidden" name="shipToStreet2" value="'.$shipToStreet2.'">'."\n";
1739 print '<input type="hidden" name="phoneNum" value="'.$phoneNum.'">'."\n";
1740 } else {
1741 print '<!-- Shipping address not complete, so we don t use it -->'."\n";
1742 }
1743 if (is_object($member->thirdparty)) {
1744 print '<input type="hidden" name="thirdparty_id" value="'.$member->thirdparty->id.'">'."\n";
1745 }
1746 print '<input type="hidden" name="email" value="'.$member->email.'">'."\n";
1747 $labeldesc = $langs->trans("PaymentSubscription");
1748 if (GETPOST('desc', 'alpha')) {
1749 $labeldesc = GETPOST('desc', 'alpha');
1750 }
1751 print '<input type="hidden" name="desc" value="'.dol_escape_htmltag($labeldesc).'">'."\n";
1752}
1753
1754// Payment on donation
1755if ($source == 'donation') {
1756 $found = true;
1757 $langs->load("don");
1758
1759 require_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php';
1760
1761 $don = new Don($db);
1762 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
1763 $result = $don->fetch($ref);
1764 if ($result <= 0) {
1765 $mesg = $don->error;
1766 $error++;
1767 } else {
1768 $don->fetch_thirdparty();
1769 }
1770 $object = $don;
1771
1772 if ($action != 'dopayment') { // Do not change amount if we just click on first dopayment
1773 if (GETPOST("amount", 'alpha')) {
1774 $amount = GETPOST("amount", 'alpha');
1775 } else {
1776 $amount = $don->getRemainToPay();
1777 }
1778 $amount = price2num($amount);
1779 }
1780
1781 if (GETPOST('fulltag', 'alpha')) {
1782 $fulltag = GETPOST('fulltag', 'alpha');
1783 } else {
1784 $fulltag = 'DON='.$don->ref.'.DAT='.dol_print_date(dol_now(), '%Y%m%d%H%M%S');
1785 if (!empty($TAG)) {
1786 $tag = $TAG;
1787 $fulltag .= '.TAG='.$TAG;
1788 }
1789 }
1790 $fulltag = dol_string_unaccent($fulltag);
1791
1792 // Creditor
1793 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Creditor");
1794 print '</td><td class="CTableRow2"><b>'.$creditor.'</b>';
1795 print '<input type="hidden" name="creditor" value="'.$creditor.'">';
1796 print '</td></tr>'."\n";
1797
1798 // Debitor
1799 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("ThirdParty");
1800 print '</td><td class="CTableRow2"><b>';
1801 if ($don->morphy == 'mor' && !empty($don->societe)) {
1802 print $don->societe;
1803 } else {
1804 print $don->getFullName($langs);
1805 }
1806 print '</b>';
1807 print '</td></tr>'."\n";
1808
1809 // Object
1810 $text = '<b>'.$langs->trans("PaymentDonation").'</b>';
1811 if (GETPOST('desc', 'alpha')) {
1812 $text = '<b>'.$langs->trans(GETPOST('desc', 'alpha')).'</b>';
1813 }
1814 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Designation");
1815 print '</td><td class="CTableRow2">'.$text;
1816 print '<input type="hidden" name="source" value="'.dol_escape_htmltag($source).'">';
1817 print '<input type="hidden" name="ref" value="'.dol_escape_htmltag($don->ref).'">';
1818 print '</td></tr>'."\n";
1819
1820 // Amount
1821 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Amount");
1822 if (empty($amount)) {
1823 if (!getDolGlobalString('DONATION_NEWFORM_AMOUNT')) {
1824 print ' ('.$langs->trans("ToComplete");
1825 }
1826 if (getDolGlobalString('DONATION_EXT_URL_SUBSCRIPTION_INFO')) {
1827 print ' - <a href="' . getDolGlobalString('DONATION_EXT_URL_SUBSCRIPTION_INFO').'" rel="external" target="_blank" rel="noopener noreferrer">'.$langs->trans("SeeHere").'</a>';
1828 }
1829 if (!getDolGlobalString('DONATION_NEWFORM_AMOUNT')) {
1830 print ')';
1831 }
1832 }
1833 print '</td><td class="CTableRow2">';
1834 $valtoshow = '';
1835 if (empty($amount) || !is_numeric($amount)) {
1836 $valtoshow = price2num(GETPOST("newamount", 'alpha'), 'MT');
1837 // force default subscription amount to value defined into constant...
1838 if (empty($valtoshow)) {
1839 if (getDolGlobalString('DONATION_NEWFORM_EDITAMOUNT')) {
1840 if (getDolGlobalString('DONATION_NEWFORM_AMOUNT')) {
1841 $valtoshow = getDolGlobalString('DONATION_NEWFORM_AMOUNT');
1842 }
1843 } else {
1844 if (getDolGlobalString('DONATION_NEWFORM_AMOUNT')) {
1845 $amount = getDolGlobalString('DONATION_NEWFORM_AMOUNT');
1846 }
1847 }
1848 }
1849 }
1850 if (empty($amount) || !is_numeric($amount)) {
1851 //$valtoshow=price2num(GETPOST("newamount",'alpha'),'MT');
1852 if (getDolGlobalString('DONATION_MIN_AMOUNT') && $valtoshow) {
1853 $valtoshow = max(getDolGlobalString('DONATION_MIN_AMOUNT'), $valtoshow);
1854 }
1855 print '<input type="hidden" name="amount" value="'.price2num(GETPOST("amount", 'alpha'), 'MT').'">';
1856 print '<input class="flat maxwidth75" type="text" name="newamount" value="'.$valtoshow.'">';
1857 // Currency
1858 print ' <b>'.$langs->trans("Currency".$currency).'</b>';
1859 } else {
1860 $valtoshow = $amount;
1861 if (getDolGlobalString('DONATION_MIN_AMOUNT') && $valtoshow) {
1862 $valtoshow = max(getDolGlobalString('DONATION_MIN_AMOUNT'), $valtoshow);
1863 $amount = $valtoshow;
1864 }
1865 print '<b class="amount">'.price($valtoshow, 1, $langs, 1, -1, -1, $currency).'</b>'; // Price with currency
1866 print '<input type="hidden" name="amount" value="'.$valtoshow.'">';
1867 print '<input type="hidden" name="newamount" value="'.$valtoshow.'">';
1868 }
1869 print '<input type="hidden" name="currency" value="'.$currency.'">';
1870 print '</td></tr>'."\n";
1871
1872 // Tag
1873 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("PaymentCode");
1874 print '</td><td class="CTableRow2"><b style="word-break: break-all;">'.$fulltag.'</b>';
1875 print '<input type="hidden" name="tag" value="'.$tag.'">';
1876 print '<input type="hidden" name="fulltag" value="'.$fulltag.'">';
1877 print '</td></tr>'."\n";
1878
1879 // Shipping address
1880 $shipToName = $don->getFullName($langs);
1881 $shipToStreet = $don->address;
1882 $shipToCity = $don->town;
1883 $shipToState = $don->state_code;
1884 $shipToCountryCode = $don->country_code;
1885 $shipToZip = $don->zip;
1886 $shipToStreet2 = '';
1887 $phoneNum = $don->phone;
1888 if ($shipToName && $shipToStreet && $shipToCity && $shipToCountryCode && $shipToZip) {
1889 print '<!-- Shipping address information -->';
1890 print '<input type="hidden" name="shipToName" value="'.$shipToName.'">'."\n";
1891 print '<input type="hidden" name="shipToStreet" value="'.$shipToStreet.'">'."\n";
1892 print '<input type="hidden" name="shipToCity" value="'.$shipToCity.'">'."\n";
1893 print '<input type="hidden" name="shipToState" value="'.$shipToState.'">'."\n";
1894 print '<input type="hidden" name="shipToCountryCode" value="'.$shipToCountryCode.'">'."\n";
1895 print '<input type="hidden" name="shipToZip" value="'.$shipToZip.'">'."\n";
1896 print '<input type="hidden" name="shipToStreet2" value="'.$shipToStreet2.'">'."\n";
1897 print '<input type="hidden" name="phoneNum" value="'.$phoneNum.'">'."\n";
1898 } else {
1899 print '<!-- Shipping address not complete, so we don t use it -->'."\n";
1900 }
1901 if (is_object($don->thirdparty)) {
1902 print '<input type="hidden" name="thirdparty_id" value="'.$don->thirdparty->id.'">'."\n";
1903 }
1904 print '<input type="hidden" name="email" value="'.$don->email.'">'."\n";
1905 $labeldesc = $langs->trans("PaymentSubscription");
1906 if (GETPOST('desc', 'alpha')) {
1907 $labeldesc = GETPOST('desc', 'alpha');
1908 }
1909 print '<input type="hidden" name="desc" value="'.dol_escape_htmltag($labeldesc).'">'."\n";
1910}
1911
1912if ($source == 'organizedeventregistration') {
1913 $found = true;
1914 $langs->loadLangs(array("members", "eventorganization"));
1915
1916 if (GETPOST('fulltag', 'alpha')) {
1917 $fulltag = GETPOST('fulltag', 'alpha');
1918 } else {
1919 $fulltag = 'ATT='.$attendee->id.'.DAT='.dol_print_date(dol_now(), '%Y%m%d%H%M%S');
1920 if (!empty($TAG)) {
1921 $tag = $TAG;
1922 $fulltag .= '.TAG='.$TAG;
1923 }
1924 }
1925 $fulltag = dol_string_unaccent($fulltag);
1926
1927 // Creditor
1928 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Creditor");
1929 print '</td><td class="CTableRow2"><b>'.$creditor.'</b>';
1930 print '<input type="hidden" name="creditor" value="'.$creditor.'">';
1931 print '</td></tr>'."\n";
1932
1933 // Debitor
1934 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Attendee");
1935 print '</td><td class="CTableRow2"><b>';
1936 print $attendee->email;
1937 print($thirdparty->name ? ' ('.$thirdparty->name.')' : '');
1938 print '</b>';
1939 print '</td></tr>'."\n";
1940
1941 if (! is_object($attendee->project)) {
1942 $text = 'ErrorProjectNotFound';
1943 } else {
1944 $text = $langs->trans("PaymentEvent").' - '.$attendee->project->title;
1945 }
1946
1947 // Object
1948 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Designation");
1949 print '</td><td class="CTableRow2"><b>'.$text.'</b>';
1950 print '<input type="hidden" name="source" value="'.dol_escape_htmltag($source).'">';
1951 print '<input type="hidden" name="ref" value="'.dol_escape_htmltag($invoice->id).'">';
1952 print '</td></tr>'."\n";
1953
1954 // Amount
1955 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Amount");
1956 print '</td><td class="CTableRow2">';
1957 $valtoshow = $amount;
1958 print '<b class="amount">'.price($valtoshow, 1, $langs, 1, -1, -1, $currency).'</b>'; // Price with currency
1959 print '<input type="hidden" name="amount" value="'.$valtoshow.'">';
1960 print '<input type="hidden" name="newamount" value="'.$valtoshow.'">';
1961 print '<input type="hidden" name="currency" value="'.$currency.'">';
1962 print '</td></tr>'."\n";
1963
1964 // Tag
1965 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("PaymentCode");
1966 print '</td><td class="CTableRow2"><b style="word-break: break-all;">'.$fulltag.'</b>';
1967 print '<input type="hidden" name="tag" value="'.$tag.'">';
1968 print '<input type="hidden" name="fulltag" value="'.$fulltag.'">';
1969 print '</td></tr>'."\n";
1970
1971 // Shipping address
1972 $shipToName = $thirdparty->getFullName($langs);
1973 $shipToStreet = $thirdparty->address;
1974 $shipToCity = $thirdparty->town;
1975 $shipToState = $thirdparty->state_code;
1976 $shipToCountryCode = $thirdparty->country_code;
1977 $shipToZip = $thirdparty->zip;
1978 $shipToStreet2 = '';
1979 $phoneNum = $thirdparty->phone;
1980 if ($shipToName && $shipToStreet && $shipToCity && $shipToCountryCode && $shipToZip) {
1981 print '<!-- Shipping address information -->';
1982 print '<input type="hidden" name="shipToName" value="'.$shipToName.'">'."\n";
1983 print '<input type="hidden" name="shipToStreet" value="'.$shipToStreet.'">'."\n";
1984 print '<input type="hidden" name="shipToCity" value="'.$shipToCity.'">'."\n";
1985 print '<input type="hidden" name="shipToState" value="'.$shipToState.'">'."\n";
1986 print '<input type="hidden" name="shipToCountryCode" value="'.$shipToCountryCode.'">'."\n";
1987 print '<input type="hidden" name="shipToZip" value="'.$shipToZip.'">'."\n";
1988 print '<input type="hidden" name="shipToStreet2" value="'.$shipToStreet2.'">'."\n";
1989 print '<input type="hidden" name="phoneNum" value="'.$phoneNum.'">'."\n";
1990 } else {
1991 print '<!-- Shipping address not complete, so we don t use it -->'."\n";
1992 }
1993 print '<input type="hidden" name="thirdparty_id" value="'.$thirdparty->id.'">'."\n";
1994 print '<input type="hidden" name="email" value="'.$thirdparty->email.'">'."\n";
1995 $labeldesc = $langs->trans("PaymentSubscription");
1996 if (GETPOST('desc', 'alpha')) {
1997 $labeldesc = GETPOST('desc', 'alpha');
1998 }
1999 print '<input type="hidden" name="desc" value="'.dol_escape_htmltag($labeldesc).'">'."\n";
2000}
2001
2002if ($source == 'boothlocation') {
2003 $found = true;
2004 $langs->load("members");
2005
2006 if (GETPOST('fulltag', 'alpha')) {
2007 $fulltag = GETPOST('fulltag', 'alpha');
2008 } else {
2009 $fulltag = 'BOO='.GETPOST("booth").'.DAT='.dol_print_date(dol_now(), '%Y%m%d%H%M%S');
2010 if (!empty($TAG)) {
2011 $tag = $TAG;
2012 $fulltag .= '.TAG='.$TAG;
2013 }
2014 }
2015 $fulltag = dol_string_unaccent($fulltag);
2016
2017 // Creditor
2018 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Creditor");
2019 print '</td><td class="CTableRow2"><b>'.$creditor.'</b>';
2020 print '<input type="hidden" name="creditor" value="'.$creditor.'">';
2021 print '</td></tr>'."\n";
2022
2023 // Debitor
2024 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Attendee");
2025 print '</td><td class="CTableRow2"><b>';
2026 print $thirdparty->name;
2027 print '</b>';
2028 print '</td></tr>'."\n";
2029
2030 // Object
2031 $text = '<b>'.$langs->trans("PaymentBoothLocation").'</b>';
2032 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Designation");
2033 print '</td><td class="CTableRow2">'.$text;
2034 print '<input type="hidden" name="source" value="'.dol_escape_htmltag($source).'">';
2035 print '<input type="hidden" name="ref" value="'.dol_escape_htmltag($invoice->id).'">';
2036 print '</td></tr>'."\n";
2037
2038 // Amount
2039 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("Amount");
2040 print '</td><td class="CTableRow2">';
2041 $valtoshow = $amount;
2042 print '<b class="amount">'.price($valtoshow, 1, $langs, 1, -1, -1, $currency).'</b>'; // Price with currency
2043 print '<input type="hidden" name="amount" value="'.$valtoshow.'">';
2044 print '<input type="hidden" name="newamount" value="'.$valtoshow.'">';
2045 print '<input type="hidden" name="currency" value="'.$currency.'">';
2046 print '</td></tr>'."\n";
2047
2048 // Tag
2049 print '<tr class="CTableRow2"><td class="CTableRow2">'.$langs->trans("PaymentCode");
2050 print '</td><td class="CTableRow2"><b style="word-break: break-all;">'.$fulltag.'</b>';
2051 print '<input type="hidden" name="tag" value="'.$tag.'">';
2052 print '<input type="hidden" name="fulltag" value="'.$fulltag.'">';
2053 print '</td></tr>'."\n";
2054
2055 // Shipping address
2056 $shipToName = $thirdparty->getFullName($langs);
2057 $shipToStreet = $thirdparty->address;
2058 $shipToCity = $thirdparty->town;
2059 $shipToState = $thirdparty->state_code;
2060 $shipToCountryCode = $thirdparty->country_code;
2061 $shipToZip = $thirdparty->zip;
2062 $shipToStreet2 = '';
2063 $phoneNum = $thirdparty->phone;
2064 if ($shipToName && $shipToStreet && $shipToCity && $shipToCountryCode && $shipToZip) {
2065 print '<!-- Shipping address information -->';
2066 print '<input type="hidden" name="shipToName" value="'.$shipToName.'">'."\n";
2067 print '<input type="hidden" name="shipToStreet" value="'.$shipToStreet.'">'."\n";
2068 print '<input type="hidden" name="shipToCity" value="'.$shipToCity.'">'."\n";
2069 print '<input type="hidden" name="shipToState" value="'.$shipToState.'">'."\n";
2070 print '<input type="hidden" name="shipToCountryCode" value="'.$shipToCountryCode.'">'."\n";
2071 print '<input type="hidden" name="shipToZip" value="'.$shipToZip.'">'."\n";
2072 print '<input type="hidden" name="shipToStreet2" value="'.$shipToStreet2.'">'."\n";
2073 print '<input type="hidden" name="phoneNum" value="'.$phoneNum.'">'."\n";
2074 } else {
2075 print '<!-- Shipping address not complete, so we don t use it -->'."\n";
2076 }
2077 print '<input type="hidden" name="thirdparty_id" value="'.$thirdparty->id.'">'."\n";
2078 print '<input type="hidden" name="email" value="'.$thirdparty->email.'">'."\n";
2079 $labeldesc = $langs->trans("PaymentSubscription");
2080 if (GETPOST('desc', 'alpha')) {
2081 $labeldesc = GETPOST('desc', 'alpha');
2082 }
2083 print '<input type="hidden" name="desc" value="'.dol_escape_htmltag($labeldesc).'">'."\n";
2084}
2085
2086if (!$found && !$mesg) {
2087 $mesg = $langs->trans("ErrorBadParameters");
2088}
2089
2090if ($mesg) {
2091 print '<tr><td align="center" colspan="2"><br><div class="warning">'.dol_escape_htmltag($mesg, 1, 1, 'br').'</div></td></tr>'."\n";
2092}
2093
2094print '</table>'."\n";
2095print "\n";
2096
2097
2098// Show all payment mode buttons (Stripe, Paypal, ...)
2099if ($action != 'dopayment') {
2100 if ($found && !$error) { // We are in a management option and no error
2101 // Check status of the object (Invoice) to verify if it is paid by external payment modules (ie Payzen, ...)
2102 $parameters = [
2103 'source' => $source,
2104 'object' => $object
2105 ];
2106 $reshook = $hookmanager->executeHooks('doCheckStatus', $parameters, $object, $action);
2107 if ($reshook < 0) {
2108 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2109 } elseif ($reshook > 0) {
2110 print $hookmanager->resPrint;
2111 }
2112
2113 if ($source == 'order' && $object->billed) {
2114 print '<br><br><div class="amountpaymentcomplete size12x wrapimp">'.$langs->trans("OrderBilled").'</div>';
2115 } elseif ($source == 'invoice' && $object->paye) {
2116 print '<br><br><div class="amountpaymentcomplete size12x wrapimp">'.$langs->trans("InvoicePaid").'</div>';
2117 } elseif ($source == 'donation' && $object->paid) {
2118 print '<br><br><div class="amountpaymentcomplete size12x wrapimp">'.$langs->trans("DonationPaid").'</div>';
2119 } else {
2120 // Membership can be paid and we still allow to make renewal
2121 if (($source == 'member' || $source == 'membersubscription') && $object->datefin > dol_now()) {
2122 $langs->load("members");
2123 print '<br><div class="amountpaymentcomplete size12x wrapimp">';
2124 $s = $langs->trans("MembershipPaid", '{s1}');
2125 print str_replace('{s1}', '<span class="nobold">'.dol_print_date($object->datefin, 'day').'</span>', $s);
2126 print '</div>';
2127 print '<div class="opacitymedium margintoponly">'.$langs->trans("PaymentWillBeRecordedForNextPeriod").'</div>';
2128 print '<br>';
2129 }
2130
2131 // Buttons for all payments registration methods
2132
2133 // This hook is used to add Button to newpayment.php for external payment modules (ie Payzen, ...)
2134 $parameters = [
2135 'paymentmethod' => $paymentmethod
2136 ];
2137 $reshook = $hookmanager->executeHooks('doAddButton', $parameters, $object, $action);
2138 if ($reshook < 0) {
2139 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2140 } elseif ($reshook > 0) {
2141 print $hookmanager->resPrint;
2142 }
2143
2144 if ((empty($paymentmethod) || $paymentmethod == 'paybox') && isModEnabled('paybox')) {
2145 print '<div class="button buttonpayment" id="div_dopayment_paybox"><span class="fa fa-credit-card"></span> <input class="" type="submit" id="dopayment_paybox" name="dopayment_paybox" value="'.$langs->trans("PayBoxDoPayment").'">';
2146 print '<br>';
2147 print '<span class="buttonpaymentsmall">'.$langs->trans("CreditOrDebitCard").'</span>';
2148 print '</div>';
2149 print '<script>
2150 $( document ).ready(function() {
2151 $("#div_dopayment_paybox").click(function(){
2152 $("#dopayment_paybox").click();
2153 });
2154 $("#dopayment_paybox").click(function(e){
2155 $("#div_dopayment_paybox").css( \'cursor\', \'wait\' );
2156 e.stopPropagation();
2157 });
2158 });
2159 </script>
2160 ';
2161 }
2162
2163 if ((empty($paymentmethod) || $paymentmethod == 'stripe') && isModEnabled('stripe')) {
2164 $showbutton = 1;
2165 if (getDolGlobalString(strtoupper($source).'_FORCE_DISABLE_STRIPE')) { // Example: MEMBER_FORCE_DISABLE_STRIPE
2166 $showbutton = 0;
2167 }
2168
2169 if ($showbutton) {
2170 // By default noidempotency is set to 1, to avoid the error "Keys for idempotant requests...". It means we can pay several times the same tag/ref.
2171 // If STRIPE_USE_IDEMPOTENCY_BY_DEFAULT is set or param noidempotency=0 is added, then with add an idempotent key, so we must use a different tag/ref for each payment (if not we will get an error).
2172 $noidempotency_key = (GETPOSTISSET('noidempotency') ? GETPOSTINT('noidempotency') : (getDolGlobalInt('STRIPE_USE_IDEMPOTENCY_BY_DEFAULT') ? 0 : 1));
2173
2174 print '<div class="button buttonpayment" id="div_dopayment_stripe"><span class="fa fa-credit-card"></span> <input class="" type="submit" id="dopayment_stripe" name="dopayment_stripe" value="'.$langs->trans("StripeDoPayment").'">';
2175 print '<input type="hidden" name="noidempotency" value="'.$noidempotency_key.'">';
2176 print '<br>';
2177 print '<span class="buttonpaymentsmall">'.$langs->trans("CreditOrDebitCard").'</span>';
2178 print '</div>';
2179 print '<script>
2180 $( document ).ready(function() {
2181 $("#div_dopayment_stripe").click(function(){
2182 $("#dopayment_stripe").click();
2183 });
2184 $("#dopayment_stripe").click(function(e){
2185 $("#div_dopayment_stripe").css( \'cursor\', \'wait\' );
2186 e.stopPropagation();
2187 return true;
2188 });
2189 });
2190 </script>
2191 ';
2192 }
2193 }
2194
2195 if ((empty($paymentmethod) || $paymentmethod == 'paypal') && isModEnabled('paypal')) {
2196 if (!getDolGlobalString('PAYPAL_API_INTEGRAL_OR_PAYPALONLY')) {
2197 $conf->global->PAYPAL_API_INTEGRAL_OR_PAYPALONLY = 'integral';
2198 }
2199
2200 $showbutton = 1;
2201 if (getDolGlobalString(strtoupper($source).'_FORCE_DISABLE_PAYPAL')) { // Example: MEMBER_FORCE_DISABLE_PAYPAL
2202 $showbutton = 0;
2203 }
2204
2205 if ($showbutton) {
2206 print '<div class="button buttonpayment" id="div_dopayment_paypal">';
2207 if (getDolGlobalString('PAYPAL_API_INTEGRAL_OR_PAYPALONLY') != 'integral') {
2208 print '<div style="line-height: 1em">&nbsp;</div>';
2209 }
2210 print '<span class="fab fa-paypal"></span> <input class="" type="submit" id="dopayment_paypal" name="dopayment_paypal" value="'.$langs->trans("PaypalDoPayment").'">';
2211 if (getDolGlobalString('PAYPAL_API_INTEGRAL_OR_PAYPALONLY') == 'integral') {
2212 print '<br>';
2213 print '<span class="buttonpaymentsmall">'.$langs->trans("CreditOrDebitCard").'</span><span class="buttonpaymentsmall"> - </span>';
2214 print '<span class="buttonpaymentsmall">'.$langs->trans("PayPalBalance").'</span>';
2215 }
2216 if (getDolGlobalString('PAYPAL_API_INTEGRAL_OR_PAYPALONLY') == 'paypalonly') {
2217 //print '<br>';
2218 //print '<span class="buttonpaymentsmall">'.$langs->trans("PayPalBalance").'"></span>';
2219 }
2220 print '</div>';
2221 print '<script>
2222 $( document ).ready(function() {
2223 $("#div_dopayment_paypal").click(function(){
2224 $("#dopayment_paypal").click();
2225 });
2226 $("#dopayment_paypal").click(function(e){
2227 $("#div_dopayment_paypal").css( \'cursor\', \'wait\' );
2228 e.stopPropagation();
2229 return true;
2230 });
2231 });
2232 </script>
2233 ';
2234 }
2235 }
2236 }
2237 } else {
2238 dol_print_error_email('ERRORNEWPAYMENT');
2239 }
2240} else {
2241 // Print
2242}
2243
2244print '</td></tr>'."\n";
2245
2246print '</table>'."\n";
2247
2248print '</form>'."\n";
2249print '</div>'."\n";
2250
2251print '<br>';
2252
2253
2254
2255// Add more content on page for some services
2256if (preg_match('/^dopayment/', $action)) { // If we chose/clicked on the payment mode
2257 // Save some data for the paymentok
2258 $remoteip = getUserRemoteIP();
2259 $_SESSION["currencyCodeType"] = $currency;
2260 $_SESSION["FinalPaymentAmt"] = $amount;
2261 $_SESSION['ipaddress'] = ($remoteip ? $remoteip : 'unknown'); // Payer ip
2262 $_SESSION["paymentType"] = '';
2263
2264 // For Stripe
2265 if (GETPOST('dopayment_stripe', 'alpha')) {
2266 // Personalized checkout
2267 print '<style>
2272 .StripeElement {
2273 background-color: white;
2274 padding: 8px 12px;
2275 border-radius: 4px;
2276 border: 1px solid transparent;
2277 box-shadow: 0 1px 3px 0 #e6ebf1;
2278 -webkit-transition: box-shadow 150ms ease;
2279 transition: box-shadow 150ms ease;
2280 }
2281
2282 .StripeElement--focus {
2283 box-shadow: 0 1px 3px 0 #cfd7df;
2284 }
2285
2286 .StripeElement--invalid {
2287 border-color: #fa755a;
2288 }
2289
2290 .StripeElement--webkit-autofill {
2291 background-color: #fefde5 !important;
2292 }
2293 </style>';
2294
2295 //print '<br>';
2296
2297 print '<!-- Show Stripe form payment-form STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION = ' . getDolGlobalString('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION').' STRIPE_USE_NEW_CHECKOUT = ' . getDolGlobalString('STRIPE_USE_NEW_CHECKOUT').' -->'."\n";
2298 print '<form action="'.$_SERVER['REQUEST_URI'].'" method="POST" id="payment-form">'."\n";
2299
2300 print '<input type="hidden" name="token" value="'.newToken().'">'."\n";
2301 print '<input type="hidden" name="dopayment_stripe" value="1">'."\n";
2302 print '<input type="hidden" name="action" value="charge">'."\n";
2303 print '<input type="hidden" name="tag" value="'.$TAG.'">'."\n";
2304 print '<input type="hidden" name="s" value="'.$source.'">'."\n";
2305 print '<input type="hidden" name="ref" value="'.$REF.'">'."\n";
2306 print '<input type="hidden" name="fulltag" value="'.$FULLTAG.'">'."\n";
2307 print '<input type="hidden" name="suffix" value="'.$suffix.'">'."\n";
2308 print '<input type="hidden" name="securekey" value="'.$SECUREKEY.'">'."\n";
2309 print '<input type="hidden" name="e" value="'.$entity.'" />';
2310 print '<input type="hidden" name="amount" value="'.$amount.'">'."\n";
2311 print '<input type="hidden" name="currency" value="'.$currency.'">'."\n";
2312 print '<input type="hidden" name="forcesandbox" value="'.GETPOSTINT('forcesandbox').'" />';
2313 print '<input type="hidden" name="email" value="'.GETPOST('email', 'alpha').'" />';
2314 print '<input type="hidden" name="thirdparty_id" value="'.GETPOSTINT('thirdparty_id').'" />';
2315 print '<input type="hidden" name="lang" value="'.$getpostlang.'">';
2316
2317 if (getDolGlobalString('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION') || getDolGlobalString('STRIPE_USE_NEW_CHECKOUT')) { // Use a SCA ready method
2318 require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php';
2319
2320 $service = 'StripeLive';
2321 $servicestatus = 1;
2322 if (!getDolGlobalString('STRIPE_LIVE') || GETPOST('forcesandbox', 'alpha')) {
2323 $service = 'StripeTest';
2324 $servicestatus = 0;
2325 }
2326
2327 $stripe = new Stripe($db);
2328 $stripeacc = $stripe->getStripeAccount($service);
2329 $stripecu = null;
2330 if (is_object($object) && is_object($object->thirdparty)) {
2331 $stripecu = $stripe->customerStripe($object->thirdparty, $stripeacc, $servicestatus, 1);
2332 }
2333
2334 if (getDolGlobalString('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION')) {
2335 // By default noidempotency is set to 1, to avoid the error "Keys for idempotant requests...". It means we can pay several times the same tag/ref.
2336 // If STRIPE_USE_IDEMPOTENCY_BY_DEFAULT is set or param noidempotency=0 is added, then with add an idempotent key, so we must use a different tag/ref for each payment (if not we will get an error).
2337 $noidempotency_key = (GETPOSTISSET('noidempotency') ? GETPOSTINT('noidempotency') : (getDolGlobalInt('STRIPE_USE_IDEMPOTENCY_BY_DEFAULT') ? 0 : 1));
2338
2339 $paymentintent = $stripe->getPaymentIntent($amount, $currency, ($tag ? $tag : $fulltag), 'Stripe payment: '.$fulltag.(is_object($object) ? ' ref='.$object->ref : ''), $object, $stripecu, $stripeacc, $servicestatus, 0, 'automatic', false, null, 0, $noidempotency_key);
2340 // The paymentintnent has status 'requires_payment_method' (even if paymentintent was already paid)
2341 //var_dump($paymentintent);
2342 if ($stripe->error) {
2343 setEventMessages($stripe->error, null, 'errors');
2344 }
2345 }
2346 }
2347
2348 // Note:
2349 // $conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION = 1 = use intent object (default value, suggest card payment mode only)
2350 // $conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION = 2 = use payment object (suggest both card payment mode but also sepa, ...)
2351
2352 print '
2353 <table id="dolpaymenttable" summary="Payment form" class="center centpercent">
2354 <tbody><tr><td class="textpublicpayment">';
2355
2356 if (getDolGlobalString('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION')) {
2357 print '<div id="payment-request-button"><!-- A Stripe Element will be inserted here. --></div>';
2358 }
2359
2360 print '<div class="form-row '.(getDolGlobalInt('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION') == 2 ? 'center' : 'left').'">';
2361 if (getDolGlobalInt('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION') == 1) {
2362 print '<label for="card-element">'.$langs->trans("CreditOrDebitCard").'</label>';
2363 print '<br><input id="cardholder-name" class="marginbottomonly" name="cardholder-name" value="" type="text" placeholder="'.$langs->trans("CardOwner").'" autocomplete="off" autofocus required>';
2364 }
2365
2366 if (getDolGlobalInt('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION') == 1) {
2367 print '<div id="card-element">
2368 <!-- a Stripe Element will be inserted here. -->
2369 </div>';
2370 }
2371 if (getDolGlobalInt('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION') == 2) {
2372 print '<div id="payment-element">
2373 <!-- a Stripe Element will be inserted here. -->
2374 </div>';
2375 }
2376
2377 print '<!-- Used to display form errors -->
2378 <div id="card-errors" role="alert"></div>
2379 </div>';
2380
2381 print '<br>';
2382 print '<button class="button buttonpayment" style="text-align: center; padding-left: 0; padding-right: 0;" id="buttontopay" data-secret="'.(is_object($paymentintent) ? $paymentintent->client_secret : '').'">'.$langs->trans("ValidatePayment").'</button>';
2383 print '<img id="hourglasstopay" class="hidden" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/working.gif">';
2384
2385 print '</td></tr></tbody>';
2386 print '</table>';
2387 //}
2388
2389 if (getDolGlobalString('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION')) {
2390 if (empty($paymentintent)) {
2391 print '<center>'.$langs->trans("Error").'</center>';
2392 } else {
2393 print '<input type="hidden" name="paymentintent_id" value="'.$paymentintent->id.'">';
2394 //$_SESSION["paymentintent_id"] = $paymentintent->id;
2395 }
2396 }
2397
2398 print '</form>'."\n";
2399
2400
2401 // JS Code for Stripe
2402 if (empty($stripearrayofkeys['publishable_key'])) {
2403 $langs->load("errors");
2404 print info_admin($langs->trans("ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv("Stripe")), 0, 0, 'error');
2405 } else {
2406 print '<!-- JS Code for Stripe components -->';
2407 print '<script src="https://js.stripe.com/v3/"></script>'."\n";
2408 print '<!-- urllogofull = '.$urllogofull.' -->'."\n";
2409
2410 // Code to ask the credit card. This use the default "API version". No way to force API version when using JS code.
2411 print '<script type="text/javascript">'."\n";
2412
2413 if (getDolGlobalString('STRIPE_USE_NEW_CHECKOUT')) {
2414 $amountstripe = $amount;
2415
2416 // Correct the amount according to unit of currency
2417 // See https://support.stripe.com/questions/which-zero-decimal-currencies-does-stripe-support
2418 $arrayzerounitcurrency = array('BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'VND', 'VUV', 'XAF', 'XOF', 'XPF');
2419 if (!in_array($currency, $arrayzerounitcurrency)) {
2420 $amountstripe = $amountstripe * 100;
2421 }
2422
2423 $ipaddress = getUserRemoteIP();
2424 $metadata = array('dol_version' => DOL_VERSION, 'dol_entity' => $conf->entity, 'ipaddress' => $ipaddress);
2425 if (is_object($object)) {
2426 $metadata['dol_type'] = $object->element;
2427 $metadata['dol_id'] = $object->id;
2428
2429 $ref = $object->ref;
2430 }
2431
2432 try {
2433 $arrayforpaymentintent = array(
2434 'description' => 'Stripe payment: '.$FULLTAG.($ref ? ' ref='.$ref : ''),
2435 "metadata" => $metadata
2436 );
2437 if ($TAG) {
2438 $arrayforpaymentintent["statement_descriptor"] = dol_trunc($TAG, 10, 'right', 'UTF-8', 1); // 22 chars that appears on bank receipt (company + description)
2439 }
2440
2441 $arrayforcheckout = array(
2442 'payment_method_types' => array('card'),
2443 'line_items' => array(array(
2444 'price_data' => array(
2445 'currency' => $currency,
2446 'unit_amount' => $amountstripe,
2447 'product_data' => array(
2448 'name' => $langs->transnoentitiesnoconv("Payment").' '.$TAG, // Label of product line
2449 'description' => 'Stripe payment: '.$FULLTAG.($ref ? ' ref='.$ref : ''),
2450 //'images' => array($urllogofull),
2451 ),
2452 ),
2453 'quantity' => 1,
2454 )),
2455 'mode' => 'payment',
2456 'client_reference_id' => $FULLTAG,
2457 'success_url' => $urlok,
2458 'cancel_url' => $urlko,
2459 'payment_intent_data' => $arrayforpaymentintent
2460 );
2461 if ($stripecu) {
2462 $arrayforcheckout['customer'] = $stripecu;
2463 } elseif (GETPOST('email', 'alpha') && isValidEmail(GETPOST('email', 'alpha'))) {
2464 $arrayforcheckout['customer_email'] = GETPOST('email', 'alpha');
2465 }
2466 $sessionstripe = \Stripe\Checkout\Session::create($arrayforcheckout);
2467
2468 $remoteip = getUserRemoteIP();
2469
2470 // Save some data for the paymentok
2471 $_SESSION["currencyCodeType"] = $currency;
2472 $_SESSION["paymentType"] = '';
2473 $_SESSION["FinalPaymentAmt"] = $amount;
2474 $_SESSION['ipaddress'] = ($remoteip ? $remoteip : 'unknown'); // Payer ip
2475 $_SESSION['payerID'] = is_object($stripecu) ? $stripecu->id : '';
2476 $_SESSION['TRANSACTIONID'] = $sessionstripe->id;
2477 } catch (Exception $e) {
2478 print $e->getMessage();
2479 } ?>
2480 // Code for payment with option STRIPE_USE_NEW_CHECKOUT set
2481
2482 // Create a Stripe client.
2483 <?php
2484 if (empty($stripeacc)) {
2485 ?>
2486 var stripe = Stripe('<?php echo $stripearrayofkeys['publishable_key']; // Defined into config.php?>');
2487 <?php
2488 } else {
2489 ?>
2490 var stripe = Stripe('<?php echo $stripearrayofkeys['publishable_key']; // Defined into config.php?>', { stripeAccount: '<?php echo $stripeacc; ?>' });
2491 <?php
2492 } ?>
2493
2494 // Create an instance of Elements
2495 var elements = stripe.elements();
2496
2497 // Custom styling can be passed to options when creating an Element.
2498 // (Note that this demo uses a wider set of styles than the guide below.)
2499 var style = {
2500 base: {
2501 color: '#32325d',
2502 lineHeight: '24px',
2503 fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
2504 fontSmoothing: 'antialiased',
2505 fontSize: '16px',
2506 '::placeholder': {
2507 color: '#aab7c4'
2508 }
2509 },
2510 invalid: {
2511 color: '#fa755a',
2512 iconColor: '#fa755a'
2513 }
2514 }
2515
2516 var cardElement = elements.create('card', {style: style});
2517
2518 // Comment this to avoid the redirect
2519 stripe.redirectToCheckout({
2520 // Make the id field from the Checkout Session creation API response
2521 // available to this file, so you can provide it as parameter here
2522 // instead of the {{CHECKOUT_SESSION_ID}} placeholder.
2523 sessionId: '<?php print $sessionstripe->id; ?>'
2524 }).then(function (result) {
2525 // If `redirectToCheckout` fails due to a browser or network
2526 // error, display the localized error message to your customer
2527 // using `result.error.message`.
2528 });
2529
2530
2531 <?php
2532 } elseif (getDolGlobalString('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION')) {
2533 ?>
2534 // Code for payment with option STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION set to 1 or 2
2535
2536 // Create a Stripe client.
2537 <?php
2538 if (empty($stripeacc)) {
2539 ?>
2540 var stripe = Stripe('<?php echo $stripearrayofkeys['publishable_key']; // Defined into config.php?>');
2541 <?php
2542 } else {
2543 ?>
2544 var stripe = Stripe('<?php echo $stripearrayofkeys['publishable_key']; // Defined into config.php?>', { stripeAccount: '<?php echo $stripeacc; ?>' });
2545 <?php
2546 } ?>
2547
2548 <?php
2549 if (getDolGlobalInt('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION') == 2) {
2550 ?>
2551 var cardButton = document.getElementById('buttontopay');
2552 var clientSecret = cardButton.dataset.secret;
2553 var options = { clientSecret: clientSecret };
2554
2555 // Create an instance of Elements
2556 var elements = stripe.elements(options);
2557 <?php
2558 } else {
2559 ?>
2560 // Create an instance of Elements
2561 var elements = stripe.elements();
2562 <?php
2563 } ?>
2564
2565 // Custom styling can be passed to options when creating an Element.
2566 // (Note that this demo uses a wider set of styles than the guide below.)
2567 var style = {
2568 base: {
2569 color: '#32325d',
2570 lineHeight: '24px',
2571 fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
2572 fontSmoothing: 'antialiased',
2573 fontSize: '16px',
2574 '::placeholder': {
2575 color: '#aab7c4'
2576 }
2577 },
2578 invalid: {
2579 color: '#fa755a',
2580 iconColor: '#fa755a'
2581 }
2582 }
2583
2584 <?php
2585 if (getDolGlobalInt('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION') == 2) {
2586 ?>
2587 var paymentElement = elements.create("payment");
2588
2589 // Add an instance of the card Element into the `card-element` <div>
2590 paymentElement.mount("#payment-element");
2591
2592 // Handle form submission
2593 var cardButton = document.getElementById('buttontopay');
2594
2595 cardButton.addEventListener('click', function(event) {
2596 console.log("We click on buttontopay");
2597 event.preventDefault();
2598
2599 /* Disable button to pay and show hourglass cursor */
2600 jQuery('#hourglasstopay').show();
2601 jQuery('#buttontopay').hide();
2602
2603 stripe.confirmPayment({
2604 elements,confirmParams: {
2605 return_url: '<?php echo $urlok; ?>',
2606 payment_method_data: {
2607 billing_details: {
2608 name: 'test'
2609 <?php if (GETPOST('email', 'alpha') || (is_object($object) && is_object($object->thirdparty) && !empty($object->thirdparty->email))) {
2610 ?>, email: '<?php echo dol_escape_js(GETPOST('email', 'alpha') ? GETPOST('email', 'alpha') : $object->thirdparty->email); ?>'<?php
2611 } ?>
2612 <?php if (is_object($object) && is_object($object->thirdparty) && !empty($object->thirdparty->phone)) {
2613 ?>, phone: '<?php echo dol_escape_js($object->thirdparty->phone); ?>'<?php
2614 } ?>
2615 <?php if (is_object($object) && is_object($object->thirdparty)) {
2616 ?>, address: {
2617 city: '<?php echo dol_escape_js($object->thirdparty->town); ?>',
2618 <?php if ($object->thirdparty->country_code) {
2619 ?>country: '<?php echo dol_escape_js($object->thirdparty->country_code); ?>',<?php
2620 } ?>
2621 line1: '<?php echo dol_escape_js(preg_replace('/\s\s+/', ' ', $object->thirdparty->address)); ?>',
2622 postal_code: '<?php echo dol_escape_js($object->thirdparty->zip); ?>'
2623 }
2624 <?php
2625 } ?>
2626 }
2627 },
2628 save_payment_method:<?php if ($stripecu) {
2629 print 'true';
2630 } else {
2631 print 'false';
2632 } ?> /* true when a customer was provided when creating payment intent. true ask to save the card */
2633 },
2634 }
2635 ).then(function(result) {
2636 console.log(result);
2637 if (result.error) {
2638 console.log("Error on result of handleCardPayment");
2639 jQuery('#buttontopay').show();
2640 jQuery('#hourglasstopay').hide();
2641 // Inform the user if there was an error
2642 var errorElement = document.getElementById('card-errors');
2643 console.log(result);
2644 errorElement.textContent = result.error.message;
2645 } else {
2646 // The payment has succeeded. Display a success message.
2647 console.log("No error on result of handleCardPayment, so we submit the form");
2648 // Submit the form
2649 jQuery('#buttontopay').hide();
2650 jQuery('#hourglasstopay').show();
2651 // Send form (action=charge that will do nothing)
2652 jQuery('#payment-form').submit();
2653 }
2654 });
2655
2656 });
2657 <?php
2658 } else {
2659 ?>
2660 var cardElement = elements.create('card', {style: style});
2661
2662 // Add an instance of the card Element into the `card-element` <div>
2663 cardElement.mount('#card-element');
2664
2665 // Handle real-time validation errors from the card Element.
2666 cardElement.addEventListener('change', function(event) {
2667 var displayError = document.getElementById('card-errors');
2668 if (event.error) {
2669 console.log("Show event error (like 'Incorrect card number', ...)");
2670 displayError.textContent = event.error.message;
2671 } else {
2672 console.log("Reset error message");
2673 displayError.textContent = '';
2674 }
2675 });
2676
2677 // Handle form submission
2678 var cardholderName = document.getElementById('cardholder-name');
2679 var cardButton = document.getElementById('buttontopay');
2680 var clientSecret = cardButton.dataset.secret;
2681
2682 cardButton.addEventListener('click', function(event) {
2683 console.log("We click on buttontopay");
2684 event.preventDefault();
2685
2686 if (cardholderName.value == '')
2687 {
2688 console.log("Field Card holder is empty");
2689 var displayError = document.getElementById('card-errors');
2690 displayError.textContent = '<?php print dol_escape_js($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("CardOwner"))); ?>';
2691 }
2692 else
2693 {
2694 /* Disable button to pay and show hourglass cursor */
2695 jQuery('#hourglasstopay').show();
2696 jQuery('#buttontopay').hide();
2697
2698 stripe.handleCardPayment(
2699 clientSecret, cardElement, {
2700 payment_method_data: {
2701 billing_details: {
2702 name: cardholderName.value
2703 <?php if (GETPOST('email', 'alpha') || (is_object($object) && is_object($object->thirdparty) && !empty($object->thirdparty->email))) {
2704 ?>, email: '<?php echo dol_escape_js(GETPOST('email', 'alpha') ? GETPOST('email', 'alpha') : $object->thirdparty->email); ?>'<?php
2705 } ?>
2706 <?php if (is_object($object) && is_object($object->thirdparty) && !empty($object->thirdparty->phone)) {
2707 ?>, phone: '<?php echo dol_escape_js($object->thirdparty->phone); ?>'<?php
2708 } ?>
2709 <?php if (is_object($object) && is_object($object->thirdparty)) {
2710 ?>, address: {
2711 city: '<?php echo dol_escape_js($object->thirdparty->town); ?>',
2712 <?php if ($object->thirdparty->country_code) {
2713 ?>country: '<?php echo dol_escape_js($object->thirdparty->country_code); ?>',<?php
2714 } ?>
2715 line1: '<?php echo dol_escape_js(preg_replace('/\s\s+/', ' ', $object->thirdparty->address)); ?>',
2716 postal_code: '<?php echo dol_escape_js($object->thirdparty->zip); ?>'
2717 }
2718 <?php
2719 } ?>
2720 }
2721 },
2722 save_payment_method:<?php if ($stripecu) {
2723 print 'true';
2724 } else {
2725 print 'false';
2726 } ?> /* true when a customer was provided when creating payment intent. true ask to save the card */
2727 }
2728 ).then(function(result) {
2729 console.log(result);
2730 if (result.error) {
2731 console.log("Error on result of handleCardPayment");
2732 jQuery('#buttontopay').show();
2733 jQuery('#hourglasstopay').hide();
2734 // Inform the user if there was an error
2735 var errorElement = document.getElementById('card-errors');
2736 errorElement.textContent = result.error.message;
2737 } else {
2738 // The payment has succeeded. Display a success message.
2739 console.log("No error on result of handleCardPayment, so we submit the form");
2740 // Submit the form
2741 jQuery('#buttontopay').hide();
2742 jQuery('#hourglasstopay').show();
2743 // Send form (action=charge that will do nothing)
2744 jQuery('#payment-form').submit();
2745 }
2746 });
2747 }
2748 });
2749 <?php
2750 } ?>
2751
2752 <?php
2753 }
2754
2755 print '</script>';
2756 }
2757 }
2758
2759 // For any other payment services
2760 // This hook can be used to show the embedded form to make payments with external payment modules (ie Payzen, ...)
2761 $parameters = [
2762 'paymentmethod' => $paymentmethod,
2763 'amount' => $amount,
2764 'currency' => $currency,
2765 'tag' => GETPOST("tag", 'alpha'),
2766 'dopayment' => GETPOST('dopayment', 'alpha')
2767 ];
2768 $reshook = $hookmanager->executeHooks('doPayment', $parameters, $object, $action);
2769 if ($reshook < 0) {
2770 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
2771 } elseif ($reshook > 0) {
2772 print $hookmanager->resPrint;
2773 }
2774}
2775
2776if (!$ws) {
2777 htmlPrintOnlineFooter($mysoc, $langs, 1, $suffix, $object);
2778}
2779
2780llxFooter('', 'public');
2781
2782$db->close();
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader()
Empty header.
Definition wrapper.php:55
llxFooter()
Empty footer.
Definition wrapper.php:69
$object ref
Definition info.php:79
Class to manage members of a foundation.
Class to manage members type.
Class to manage customers orders.
Class for ConferenceOrBoothAttendee.
Class to manage contracts.
Class to manage lines of contracts.
Class to manage invoices.
Class to manage generation of HTML components Only common components must be here.
Class to manage hooks.
Class to manage payments of donations.
Class to manage products or services.
Class to manage third parties objects (customers, suppliers, prospects...)
Stripe class @TODO No reason to extends CommonObject.
htmlPrintOnlineFooter($fromcompany, $langs, $addformmessage=0, $suffix='', $object=null)
Show footer of company in HTML pages.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
dol_now($mode='auto')
Return date for now.
img_mime($file, $titlealt='', $morecss='')
Show MIME img of a file.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_getIdFromCode($db, $key, $tablename, $fieldkey='code', $fieldid='id', $entityfilter=0, $filters='')
Return an id or code from a code or id.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_string_unaccent($str)
Clean a string from all accent characters to be used as ref, login or by dol_sanitizeFileName.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
dol_print_error_email($prefixcode, $errormessage='', $errormessages=array(), $morecss='error', $email='')
Show a public email and error code to contact if technical error.
dol_htmloutput_mesg($mesgstring='', $mesgarray=array(), $style='ok', $keepembedded=0)
Print formatted messages to output (Used to show messages on html output).
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
isValidEmail($address, $acceptsupervisorkey=0, $acceptuserkey=0)
Return true if email syntax is ok.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
getUserRemoteIP()
Return the IP of remote user.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='')
Show information in HTML for admin users or standard users.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
ui state ui widget content ui state ui widget header ui state a ui button
0 = Do not include form tag and submit button -1 = Do not include form tag but include submit button
if(!defined( 'CSRFCHECK_WITH_TOKEN'))
print_paybox_redirect($PRICE, $CURRENCY, $EMAIL, $urlok, $urlko, $TAG)
Create a redirect form to paybox form.
print_paypal_redirect($paymentAmount, $currencyCodeType, $paymentType, $returnURL, $cancelURL, $tag)
Send redirect to paypal to browser.
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:140
dol_verifyHash($chain, $hash, $type='0')
Compute a hash and compare it to the given one For backward compatibility reasons,...