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