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