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