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