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