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