* Copyright (C) 2006-2017 Laurent Destailleur * Copyright (C) 2009-2012 Regis Houssin * Copyright (C) 2018 Juanjo Menent * Copyright (C) 2018-2021 Thibault FOUCART * Copyright (C) 2021 Waƫl Almoman * Copyright (C) 2021 Dorian Vabre * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * For Paypal test: https://developer.paypal.com/ * For Paybox test: ??? * For Stripe test: Use credit card 4242424242424242 .More example on https://stripe.com/docs/testing * * Variants: * - When option STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION is on, we use the new PaymentIntent API * - When option STRIPE_USE_NEW_CHECKOUT is on, we use the new checkout API * - If no option set, we use old APIS (charge) */ /** * \file htdocs/public/payment/newpayment.php * \ingroup core * \brief File to offer a way to make a payment for a particular Dolibarr object */ if (!defined('NOLOGIN')) { define("NOLOGIN", 1); // This means this output page does not require to be logged. } if (!defined('NOCSRFCHECK')) { define("NOCSRFCHECK", 1); // We accept to go on this page from external web site. } if (!defined('NOIPCHECK')) { define('NOIPCHECK', '1'); // Do not check IP defined into conf $dolibarr_main_restrict_ip } if (!defined('NOBROWSERNOTIF')) { define('NOBROWSERNOTIF', '1'); } // For MultiCompany module. // Do not use GETPOST here, function is not defined and get of entity must be done before including main.inc.php $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)))); if (is_numeric($entity)) { define("DOLENTITY", $entity); } // Load Dolibarr environment require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/eventorganization/class/conferenceorboothattendee.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT.'/societe/class/societeaccount.class.php'; require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; // Hook to be used by external payment modules (ie Payzen, ...) $hookmanager = new HookManager($db); $hookmanager->initHooks(array('newpayment')); // Load translation files $langs->loadLangs(array("main", "other", "dict", "bills", "companies", "errors", "paybox", "paypal", "stripe")); // File with generic data // Security check // No check on module enabled. Done later according to $validpaymentmethod $action = GETPOST('action', 'aZ09'); // Input are: // type ('invoice','order','contractline'), // id (object id), // amount (required if id is empty), // tag (a free text, required if type is empty) // currency (iso code) $suffix = GETPOST("suffix", 'aZ09'); $amount = price2num(GETPOST("amount", 'alpha')); if (!GETPOST("currency", 'alpha')) { $currency = $conf->currency; } else { $currency = GETPOST("currency", 'aZ09'); } $source = GETPOST("s", 'aZ09') ?GETPOST("s", 'aZ09') : GETPOST("source", 'aZ09'); $getpostlang = GETPOST('lang', 'aZ09'); if (!$action) { if (!GETPOST("amount", 'alpha') && !$source) { print $langs->trans('ErrorBadParameters')." - amount or source"; exit; } if (is_numeric($amount) && !GETPOST("tag", 'alpha') && !$source) { print $langs->trans('ErrorBadParameters')." - tag or source"; exit; } if ($source && !GETPOST("ref", 'alpha')) { print $langs->trans('ErrorBadParameters')." - ref"; exit; } } if ($source == 'organizedeventregistration') { // Finding the Attendee $attendee = new ConferenceOrBoothAttendee($db); $invoiceid = GETPOST('ref', 'int'); $invoice = new Facture($db); $resultinvoice = $invoice->fetch($invoiceid); if ($resultinvoice <= 0) { setEventMessages(null, $invoice->errors, "errors"); } else { /* $attendeeid = 0; $invoice->fetchObjectLinked(); $linkedAttendees = $invoice->linkedObjectsIds['conferenceorboothattendee']; if (is_array($linkedAttendees)) { $linkedAttendees = array_values($linkedAttendees); $attendeeid = $linkedAttendees[0]; }*/ $sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."eventorganization_conferenceorboothattendee"; $sql .= " WHERE fk_invoice = ".((int) $invoiceid); $resql = $db->query($sql); if ($resql) { $obj = $db->fetch_object($resql); if ($obj) { $attendeeid = $obj->rowid; } } if ($attendeeid > 0) { $resultattendee = $attendee->fetch($attendeeid); if ($resultattendee <= 0) { setEventMessages(null, $attendee->errors, "errors"); } else { $attendee->fetch_projet(); $amount = price2num($invoice->total_ttc); // Finding the associated thirdparty $thirdparty = new Societe($db); $resultthirdparty = $thirdparty->fetch($invoice->socid); if ($resultthirdparty <= 0) { setEventMessages(null, $thirdparty->errors, "errors"); } $object = $thirdparty; } } } } elseif ($source == 'boothlocation') { // Getting the amount to pay, the invoice, finding the thirdparty $invoiceid = GETPOST('ref'); $invoice = new Facture($db); $resultinvoice = $invoice->fetch($invoiceid); if ($resultinvoice <= 0) { setEventMessages(null, $invoice->errors, "errors"); } else { $amount = price2num($invoice->total_ttc); // Finding the associated thirdparty $thirdparty = new Societe($db); $resultthirdparty = $thirdparty->fetch($invoice->socid); if ($resultthirdparty <= 0) { setEventMessages(null, $thirdparty->errors, "errors"); } $object = $thirdparty; } } $paymentmethod = GETPOST('paymentmethod', 'alphanohtml') ? GETPOST('paymentmethod', 'alphanohtml') : ''; // Empty in most cases. Defined when a payment mode is forced $validpaymentmethod = array(); // Detect $paymentmethod foreach ($_POST as $key => $val) { $reg = array(); if (preg_match('/^dopayment_(.*)$/', $key, $reg)) { $paymentmethod = $reg[1]; break; } } // Define $urlwithroot //$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root)); //$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file $urlwithroot = DOL_MAIN_URL_ROOT; // This is to use same domain name than current. For Paypal payment, we can use internal URL like localhost. $urlok = $urlwithroot.'/public/payment/paymentok.php?'; $urlko = $urlwithroot.'/public/payment/paymentko.php?'; // Complete urls for post treatment $ref = $REF = GETPOST('ref', 'alpha'); $TAG = GETPOST("tag", 'alpha'); $FULLTAG = GETPOST("fulltag", 'alpha'); // fulltag is tag with more informations $SECUREKEY = GETPOST("securekey"); // Secure key if ($paymentmethod && !preg_match('/'.preg_quote('PM='.$paymentmethod, '/').'/', $FULLTAG)) { $FULLTAG .= ($FULLTAG ? '.' : '').'PM='.$paymentmethod; } if (!empty($suffix)) { $urlok .= 'suffix='.urlencode($suffix).'&'; $urlko .= 'suffix='.urlencode($suffix).'&'; } if ($source) { $urlok .= 's='.urlencode($source).'&'; $urlko .= 's='.urlencode($source).'&'; } if (!empty($REF)) { $urlok .= 'ref='.urlencode($REF).'&'; $urlko .= 'ref='.urlencode($REF).'&'; } if (!empty($TAG)) { $urlok .= 'tag='.urlencode($TAG).'&'; $urlko .= 'tag='.urlencode($TAG).'&'; } if (!empty($FULLTAG)) { $urlok .= 'fulltag='.urlencode($FULLTAG).'&'; $urlko .= 'fulltag='.urlencode($FULLTAG).'&'; } if (!empty($SECUREKEY)) { $urlok .= 'securekey='.urlencode($SECUREKEY).'&'; $urlko .= 'securekey='.urlencode($SECUREKEY).'&'; } if (!empty($entity)) { $urlok .= 'e='.urlencode($entity).'&'; $urlko .= 'e='.urlencode($entity).'&'; } if (!empty($getpostlang)) { $urlok .= 'lang='.urlencode($getpostlang).'&'; $urlko .= 'lang='.urlencode($getpostlang).'&'; } $urlok = preg_replace('/&$/', '', $urlok); // Remove last & $urlko = preg_replace('/&$/', '', $urlko); // Remove last & // Make special controls if ((empty($paymentmethod) || $paymentmethod == 'paypal') && isModEnabled('paypal')) { require_once DOL_DOCUMENT_ROOT.'/paypal/lib/paypal.lib.php'; require_once DOL_DOCUMENT_ROOT.'/paypal/lib/paypalfunctions.lib.php'; // Check parameters $PAYPAL_API_OK = ""; if ($urlok) { $PAYPAL_API_OK = $urlok; } $PAYPAL_API_KO = ""; if ($urlko) { $PAYPAL_API_KO = $urlko; } if (empty($PAYPAL_API_USER)) { dol_print_error('', "Paypal setup param PAYPAL_API_USER not defined"); return -1; } if (empty($PAYPAL_API_PASSWORD)) { dol_print_error('', "Paypal setup param PAYPAL_API_PASSWORD not defined"); return -1; } if (empty($PAYPAL_API_SIGNATURE)) { dol_print_error('', "Paypal setup param PAYPAL_API_SIGNATURE not defined"); return -1; } } if ((empty($paymentmethod) || $paymentmethod == 'paybox') && isModEnabled('paybox')) { // No specific test for the moment } if ((empty($paymentmethod) || $paymentmethod == 'stripe') && isModEnabled('stripe')) { require_once DOL_DOCUMENT_ROOT.'/stripe/config.php'; // This include also /stripe/lib/stripe.lib.php, /includes/stripe/stripe-php/init.php, ... } // Initialize $validpaymentmethod // The list can be complete by the hook 'doValidatePayment' executed inside getValidOnlinePaymentMethods() $validpaymentmethod = getValidOnlinePaymentMethods($paymentmethod); // Check security token $tmpsource = $source; if ($tmpsource == 'membersubscription') { $tmpsource = 'member'; } $valid = true; if (!empty($conf->global->PAYMENT_SECURITY_TOKEN)) { $tokenisok = false; if (!empty($conf->global->PAYMENT_SECURITY_TOKEN_UNIQUE)) { if ($tmpsource && $REF) { // Use the source in the hash to avoid duplicates if the references are identical $tokenisok = dol_verifyHash($conf->global->PAYMENT_SECURITY_TOKEN.$tmpsource.$REF, $SECUREKEY, '2'); // Do a second test for retro-compatibility (token may have been hashed with membersubscription in external module) if ($tmpsource != $source) { $tokenisok = dol_verifyHash($conf->global->PAYMENT_SECURITY_TOKEN.$source.$REF, $SECUREKEY, '2'); } } else { $tokenisok = dol_verifyHash($conf->global->PAYMENT_SECURITY_TOKEN, $SECUREKEY, '2'); } } else { $tokenisok = ($conf->global->PAYMENT_SECURITY_TOKEN == $SECUREKEY); } if (! $tokenisok) { if (empty($conf->global->PAYMENT_SECURITY_ACCEPT_ANY_TOKEN)) { $valid = false; // PAYMENT_SECURITY_ACCEPT_ANY_TOKEN is for backward compatibility } else { dol_syslog("Warning: PAYMENT_SECURITY_ACCEPT_ANY_TOKEN is on", LOG_WARNING); } } if (!$valid) { print '
Bad value for key.
'; //print 'SECUREKEY='.$SECUREKEY.' valid='.$valid; exit; } } if (!empty($paymentmethod) && empty($validpaymentmethod[$paymentmethod])) { print 'Payment module for payment method '.$paymentmethod.' is not active'; exit; } if (empty($validpaymentmethod)) { print 'No active payment module (Paypal, Stripe, Paybox, ...)'; exit; } // Common variables $creditor = $mysoc->name; $paramcreditor = 'ONLINE_PAYMENT_CREDITOR'; $paramcreditorlong = 'ONLINE_PAYMENT_CREDITOR_'.$suffix; if (!empty($conf->global->$paramcreditorlong)) { $creditor = $conf->global->$paramcreditorlong; // use label long of the seller to show } elseif (!empty($conf->global->$paramcreditor)) { $creditor = $conf->global->$paramcreditor; // use label short of the seller to show } $mesg = ''; /* * Actions */ // Action dopayment is called after clicking/choosing the payment mode if ($action == 'dopayment') { dol_syslog("--- newpayment.php Execute action = ".$action." paymentmethod=".$paymentmethod.' amount='.$amount.' newamount='.GETPOST("newamount", 'alpha'), LOG_DEBUG, 0, '_payment'); if ($paymentmethod == 'paypal') { $PAYPAL_API_PRICE = price2num(GETPOST("newamount", 'alpha'), 'MT'); $PAYPAL_PAYMENT_TYPE = 'Sale'; // Vars that are used as global var later in print_paypal_redirect() $origfulltag = GETPOST("fulltag", 'alpha'); $shipToName = GETPOST("shipToName", 'alpha'); $shipToStreet = GETPOST("shipToStreet", 'alpha'); $shipToCity = GETPOST("shipToCity", 'alpha'); $shipToState = GETPOST("shipToState", 'alpha'); $shipToCountryCode = GETPOST("shipToCountryCode", 'alpha'); $shipToZip = GETPOST("shipToZip", 'alpha'); $shipToStreet2 = GETPOST("shipToStreet2", 'alpha'); $phoneNum = GETPOST("phoneNum", 'alpha'); $email = GETPOST("email", 'alpha'); $desc = GETPOST("desc", 'alpha'); $thirdparty_id = GETPOST('thirdparty_id', 'int'); // Special case for Paypal-Indonesia if ($shipToCountryCode == 'ID' && !preg_match('/\-/', $shipToState)) { $shipToState = 'ID-'.$shipToState; } if (empty($PAYPAL_API_PRICE) || !is_numeric($PAYPAL_API_PRICE)) { $mesg = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Amount")); $action = ''; // } elseif (empty($EMAIL)) { $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("YourEMail")); // } elseif (! isValidEMail($EMAIL)) { $mesg=$langs->trans("ErrorBadEMail",$EMAIL); } elseif (!$origfulltag) { $mesg = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("PaymentCode")); $action = ''; } //var_dump($_POST); if (empty($mesg)) { dol_syslog("newpayment.php call paypal api and do redirect", LOG_DEBUG); // Other $PAYPAL_API_DEVISE = "USD"; if (!empty($currency)) { $PAYPAL_API_DEVISE = $currency; } // Show var initialized by include fo paypal lib at begin of this file dol_syslog("Submit Paypal form", LOG_DEBUG); dol_syslog("PAYPAL_API_USER: $PAYPAL_API_USER", LOG_DEBUG); dol_syslog("PAYPAL_API_PASSWORD: ".preg_replace('/./', '*', $PAYPAL_API_PASSWORD), LOG_DEBUG); // No password into log files dol_syslog("PAYPAL_API_SIGNATURE: $PAYPAL_API_SIGNATURE", LOG_DEBUG); dol_syslog("PAYPAL_API_SANDBOX: $PAYPAL_API_SANDBOX", LOG_DEBUG); dol_syslog("PAYPAL_API_OK: $PAYPAL_API_OK", LOG_DEBUG); dol_syslog("PAYPAL_API_KO: $PAYPAL_API_KO", LOG_DEBUG); dol_syslog("PAYPAL_API_PRICE: $PAYPAL_API_PRICE", LOG_DEBUG); dol_syslog("PAYPAL_API_DEVISE: $PAYPAL_API_DEVISE", LOG_DEBUG); // All those fields may be empty when making a payment for a free amount for example dol_syslog("shipToName: $shipToName", LOG_DEBUG); dol_syslog("shipToStreet: $shipToStreet", LOG_DEBUG); dol_syslog("shipToCity: $shipToCity", LOG_DEBUG); dol_syslog("shipToState: $shipToState", LOG_DEBUG); dol_syslog("shipToCountryCode: $shipToCountryCode", LOG_DEBUG); dol_syslog("shipToZip: $shipToZip", LOG_DEBUG); dol_syslog("shipToStreet2: $shipToStreet2", LOG_DEBUG); dol_syslog("phoneNum: $phoneNum", LOG_DEBUG); dol_syslog("email: $email", LOG_DEBUG); dol_syslog("desc: $desc", LOG_DEBUG); 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 // A redirect is added if API call successfull $mesg = print_paypal_redirect($PAYPAL_API_PRICE, $PAYPAL_API_DEVISE, $PAYPAL_PAYMENT_TYPE, $PAYPAL_API_OK, $PAYPAL_API_KO, $FULLTAG); // If we are here, it means the Paypal redirect was not done, so we show error message $action = ''; } } if ($paymentmethod == 'paybox') { $PRICE = price2num(GETPOST("newamount"), 'MT'); $email = $conf->global->ONLINE_PAYMENT_SENDEMAIL; $thirdparty_id = GETPOST('thirdparty_id', 'int'); $origfulltag = GETPOST("fulltag", 'alpha'); // Securekey into back url useless for back url and we need an url lower than 150. $urlok = preg_replace('/securekey=[^&]+&?/', '', $urlok); $urlko = preg_replace('/securekey=[^&]+&?/', '', $urlko); if (empty($PRICE) || !is_numeric($PRICE)) { $mesg = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Amount")); } elseif (empty($email)) { $mesg = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("ONLINE_PAYMENT_SENDEMAIL")); } elseif (!isValidEMail($email)) { $mesg = $langs->trans("ErrorBadEMail", $email); } elseif (!$origfulltag) { $mesg = $langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("PaymentCode")); } elseif (dol_strlen($urlok) > 150) { $mesg = 'Error urlok too long '.$urlok.' (Paybox requires 150, found '.strlen($urlok).')'; } elseif (dol_strlen($urlko) > 150) { $mesg = 'Error urlko too long '.$urlko.' (Paybox requires 150, found '.strlen($urlok).')'; } if (empty($mesg)) { dol_syslog("newpayment.php call paybox api and do redirect", LOG_DEBUG); include_once DOL_DOCUMENT_ROOT.'/paybox/lib/paybox.lib.php'; print_paybox_redirect($PRICE, $conf->currency, $email, $urlok, $urlko, $FULLTAG); session_destroy(); exit; } } if ($paymentmethod == 'stripe') { if (GETPOST('newamount', 'alpha')) { $amount = price2num(GETPOST('newamount', 'alpha'), 'MT'); } else { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Amount")), null, 'errors'); $action = ''; } } } // Called when choosing Stripe mode. // When using the old Charge API architecture, this code is called after clicking the 'dopayment' with the Charge API architecture. // 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. if ($action == 'charge' && isModEnabled('stripe')) { $amountstripe = $amount; // Correct the amount according to unit of currency // See https://support.stripe.com/questions/which-zero-decimal-currencies-does-stripe-support $arrayzerounitcurrency = array('BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'VND', 'VUV', 'XAF', 'XOF', 'XPF'); if (!in_array($currency, $arrayzerounitcurrency)) { $amountstripe = $amountstripe * 100; } dol_syslog("--- newpayment.php Execute action = ".$action." STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION=".getDolGlobalInt('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION'), LOG_DEBUG, 0, '_payment'); dol_syslog("GET=".var_export($_GET, true), LOG_DEBUG, 0, '_payment'); dol_syslog("POST=".var_export($_POST, true), LOG_DEBUG, 0, '_payment'); $stripeToken = GETPOST("stripeToken", 'alpha'); $email = GETPOST("email", 'alpha'); $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 $dol_type = (GETPOST('s', 'alpha') ? GETPOST('s', 'alpha') : GETPOST('source', 'alpha')); $dol_id = GETPOST('dol_id', 'int'); $vatnumber = GETPOST('vatnumber', 'alpha'); $savesource = GETPOSTISSET('savesource') ? GETPOST('savesource', 'int') : 1; dol_syslog("POST stripeToken = ".$stripeToken, LOG_DEBUG, 0, '_payment'); dol_syslog("POST email = ".$email, LOG_DEBUG, 0, '_payment'); dol_syslog("POST thirdparty_id = ".$thirdparty_id, LOG_DEBUG, 0, '_payment'); dol_syslog("POST vatnumber = ".$vatnumber, LOG_DEBUG, 0, '_payment'); $error = 0; $errormessage = ''; // When using the old Charge API architecture if (!getDolGlobalInt('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION')) { try { $metadata = array( 'dol_version' => DOL_VERSION, 'dol_entity' => $conf->entity, 'dol_company' => $mysoc->name, // Usefull when using multicompany 'dol_tax_num' => $vatnumber, 'ipaddress'=> getUserRemoteIP() ); if (!empty($thirdparty_id)) { $metadata["dol_thirdparty_id"] = $thirdparty_id; } if ($thirdparty_id > 0) { dol_syslog("Search existing Stripe customer profile for thirdparty_id=".$thirdparty_id, LOG_DEBUG, 0, '_payment'); $service = 'StripeTest'; $servicestatus = 0; if (!empty($conf->global->STRIPE_LIVE) && !GETPOST('forcesandbox', 'int')) { $service = 'StripeLive'; $servicestatus = 1; } $thirdparty = new Societe($db); $thirdparty->fetch($thirdparty_id); // Create Stripe customer include_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php'; $stripe = new Stripe($db); $stripeacc = $stripe->getStripeAccount($service); $customer = $stripe->customerStripe($thirdparty, $stripeacc, $servicestatus, 1); if (empty($customer)) { $error++; dol_syslog('Failed to get/create stripe customer for thirdparty id = '.$thirdparty_id.' and servicestatus = '.$servicestatus.': '.$stripe->error, LOG_ERR, 0, '_payment'); setEventMessages('Failed to get/create stripe customer for thirdparty id = '.$thirdparty_id.' and servicestatus = '.$servicestatus.': '.$stripe->error, null, 'errors'); $action = ''; } // Create Stripe card from Token if (!$error) { if ($savesource) { $card = $customer->sources->create(array("source" => $stripeToken, "metadata" => $metadata)); } else { $card = $stripeToken; } if (empty($card)) { $error++; dol_syslog('Failed to create card record', LOG_WARNING, 0, '_payment'); setEventMessages('Failed to create card record', null, 'errors'); $action = ''; } else { if (!empty($FULLTAG)) { $metadata["FULLTAG"] = $FULLTAG; } if (!empty($dol_id)) { $metadata["dol_id"] = $dol_id; } if (!empty($dol_type)) { $metadata["dol_type"] = $dol_type; } dol_syslog("Create charge on card ".$card->id, LOG_DEBUG, 0, '_payment'); $charge = \Stripe\Charge::create(array( 'amount' => price2num($amountstripe, 'MU'), 'currency' => $currency, 'capture' => true, // Charge immediatly 'description' => 'Stripe payment: '.$FULLTAG.' ref='.$ref, 'metadata' => $metadata, 'customer' => $customer->id, 'source' => $card, 'statement_descriptor_suffix' => dol_trunc($FULLTAG, 10, 'right', 'UTF-8', 1), // 22 chars that appears on bank receipt (company + description) ), array("idempotency_key" => "$FULLTAG", "stripe_account" => "$stripeacc")); // Return $charge = array('id'=>'ch_XXXX', 'status'=>'succeeded|pending|failed', 'failure_code'=>, 'failure_message'=>...) if (empty($charge)) { $error++; dol_syslog('Failed to charge card', LOG_WARNING, 0, '_payment'); setEventMessages('Failed to charge card', null, 'errors'); $action = ''; } } } } else { $vatcleaned = $vatnumber ? $vatnumber : null; /*$taxinfo = array('type'=>'vat'); if ($vatcleaned) { $taxinfo["tax_id"] = $vatcleaned; } // We force data to "null" if not defined as expected by Stripe if (empty($vatcleaned)) $taxinfo=null; */ dol_syslog("Create anonymous customer card profile", LOG_DEBUG, 0, '_payment'); $customer = \Stripe\Customer::create(array( 'email' => $email, 'description' => ($email ? 'Anonymous customer for '.$email : 'Anonymous customer'), 'metadata' => $metadata, '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 ?) )); // Return $customer = array('id'=>'cus_XXXX', ...) // Create the VAT record in Stripe /* We don't know country of customer, so we can't create tax 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 { if (!empty($vatcleaned)) { $isineec=isInEEC($object); if ($object->country_code && $isineec) { //$taxids = $customer->allTaxIds($customer->id); $customer->createTaxId($customer->id, array('type'=>'eu_vat', 'value'=>$vatcleaned)); } } }*/ if (!empty($FULLTAG)) { $metadata["FULLTAG"] = $FULLTAG; } if (!empty($dol_id)) { $metadata["dol_id"] = $dol_id; } if (!empty($dol_type)) { $metadata["dol_type"] = $dol_type; } // The customer was just created with a source, so we can make a charge // with no card defined, the source just used for customer creation will be used. dol_syslog("Create charge", LOG_DEBUG, 0, '_payment'); $charge = \Stripe\Charge::create(array( 'customer' => $customer->id, 'amount' => price2num($amountstripe, 'MU'), 'currency' => $currency, 'capture' => true, // Charge immediatly 'description' => 'Stripe payment: '.$FULLTAG.' ref='.$ref, 'metadata' => $metadata, 'statement_descriptor' => dol_trunc($FULLTAG, 10, 'right', 'UTF-8', 1), // 22 chars that appears on bank receipt (company + description) ), array("idempotency_key" => "$FULLTAG", "stripe_account" => "$stripeacc")); // Return $charge = array('id'=>'ch_XXXX', 'status'=>'succeeded|pending|failed', 'failure_code'=>, 'failure_message'=>...) if (empty($charge)) { $error++; dol_syslog('Failed to charge card', LOG_WARNING, 0, '_payment'); setEventMessages('Failed to charge card', null, 'errors'); $action = ''; } } } catch (\Stripe\Error\Card $e) { // Since it's a decline, \Stripe\Error\Card will be caught $body = $e->getJsonBody(); $err = $body['error']; print('Status is:'.$e->getHttpStatus()."\n"); print('Type is:'.$err['type']."\n"); print('Code is:'.$err['code']."\n"); // param is '' in this case print('Param is:'.$err['param']."\n"); print('Message is:'.$err['message']."\n"); $error++; $errormessage = "ErrorCard ".$e->getMessage()." err=".var_export($err, true); dol_syslog($errormessage, LOG_WARNING, 0, '_payment'); setEventMessages($e->getMessage(), null, 'errors'); $action = ''; } catch (\Stripe\Error\RateLimit $e) { // Too many requests made to the API too quickly $error++; $errormessage = "ErrorRateLimit ".$e->getMessage(); dol_syslog($errormessage, LOG_WARNING, 0, '_payment'); setEventMessages($e->getMessage(), null, 'errors'); $action = ''; } catch (\Stripe\Error\InvalidRequest $e) { // Invalid parameters were supplied to Stripe's API $error++; $errormessage = "ErrorInvalidRequest ".$e->getMessage(); dol_syslog($errormessage, LOG_WARNING, 0, '_payment'); setEventMessages($e->getMessage(), null, 'errors'); $action = ''; } catch (\Stripe\Error\Authentication $e) { // Authentication with Stripe's API failed // (maybe you changed API keys recently) $error++; $errormessage = "ErrorAuthentication ".$e->getMessage(); dol_syslog($errormessage, LOG_WARNING, 0, '_payment'); setEventMessages($e->getMessage(), null, 'errors'); $action = ''; } catch (\Stripe\Error\ApiConnection $e) { // Network communication with Stripe failed $error++; $errormessage = "ErrorApiConnection ".$e->getMessage(); dol_syslog($errormessage, LOG_WARNING, 0, '_payment'); setEventMessages($e->getMessage(), null, 'errors'); $action = ''; } catch (\Stripe\Error\Base $e) { // Display a very generic error to the user, and maybe send // yourself an email $error++; $errormessage = "ErrorBase ".$e->getMessage(); dol_syslog($errormessage, LOG_WARNING, 0, '_payment'); setEventMessages($e->getMessage(), null, 'errors'); $action = ''; } catch (Exception $e) { // Something else happened, completely unrelated to Stripe $error++; $errormessage = "ErrorException ".$e->getMessage(); dol_syslog($errormessage, LOG_WARNING, 0, '_payment'); setEventMessages($e->getMessage(), null, 'errors'); $action = ''; } } // When using the PaymentIntent API architecture (mode set on by default into conf.class.php) if (getDolGlobalInt('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION')) { $service = 'StripeTest'; $servicestatus = 0; if (!empty($conf->global->STRIPE_LIVE) && !GETPOST('forcesandbox', 'int')) { $service = 'StripeLive'; $servicestatus = 1; } include_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php'; $stripe = new Stripe($db); $stripeacc = $stripe->getStripeAccount($service); // We go here if $conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION is set. // In such a case, payment is always ok when we call the "charge" action. $paymentintent_id = GETPOST("paymentintent_id", "alpha"); // Force to use the correct API key global $stripearrayofkeysbyenv; \Stripe\Stripe::setApiKey($stripearrayofkeysbyenv[$servicestatus]['secret_key']); try { if (empty($stripeacc)) { // If the Stripe connect account not set, we use common API usage $paymentintent = \Stripe\PaymentIntent::retrieve($paymentintent_id); } else { $paymentintent = \Stripe\PaymentIntent::retrieve($paymentintent_id, array("stripe_account" => $stripeacc)); } } catch (Exception $e) { $error++; $errormessage = "CantRetrievePaymentIntent ".$e->getMessage(); dol_syslog($errormessage, LOG_WARNING, 0, '_payment'); setEventMessages($e->getMessage(), null, 'errors'); $action = ''; } if ($paymentintent->status != 'succeeded') { $error++; $errormessage = "StatusOfRetrievedIntent is not succeeded: ".$paymentintent->status; dol_syslog($errormessage, LOG_WARNING, 0, '_payment'); setEventMessages($paymentintent->status, null, 'errors'); $action = ''; } else { // TODO We can also record the payment mode into llx_societe_rib with stripe $paymentintent->payment_method // 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. //dol_syslog("Create payment_method for ".$paymentintent->payment_method, LOG_DEBUG, 0, '_payment'); // Get here amount and currency used for payment and force value into $amount and $currency so the real amount is saved into session instead // of the amount and currency retreived from the POST. if (!empty($paymentintent->currency) && !empty($paymentintent->amount)) { $currency = strtoupper($paymentintent->currency); $amount = $paymentintent->amount; // Correct the amount according to unit of currency // See https://support.stripe.com/questions/which-zero-decimal-currencies-does-stripe-support $arrayzerounitcurrency = array('BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'VND', 'VUV', 'XAF', 'XOF', 'XPF'); if (!in_array($currency, $arrayzerounitcurrency)) { $amount = $amount / 100; } } } } $remoteip = getUserRemoteIP(); $_SESSION["onlinetoken"] = $stripeToken; $_SESSION["FinalPaymentAmt"] = $amount; // amount really paid (coming from Stripe). Will be used for check in paymentok.php. $_SESSION["currencyCodeType"] = $currency; // currency really used for payment (coming from Stripe). Will be used for check in paymentok.php. $_SESSION["paymentType"] = ''; $_SESSION['ipaddress'] = ($remoteip ? $remoteip : 'unknown'); // Payer ip $_SESSION['payerID'] = is_object($customer) ? $customer->id : ''; $_SESSION['TRANSACTIONID'] = (is_object($charge) ? $charge->id : (is_object($paymentintent) ? $paymentintent->id : '')); $_SESSION['errormessage'] = $errormessage; dol_syslog("Action charge stripe STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION=".getDolGlobalInt('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION')." ip=".$remoteip, LOG_DEBUG, 0, '_payment'); dol_syslog("onlinetoken=".$_SESSION["onlinetoken"]." FinalPaymentAmt=".$_SESSION["FinalPaymentAmt"]." currencyCodeType=".$_SESSION["currencyCodeType"]." payerID=".$_SESSION['payerID']." TRANSACTIONID=".$_SESSION['TRANSACTIONID'], LOG_DEBUG, 0, '_payment'); dol_syslog("FULLTAG=".$FULLTAG, LOG_DEBUG, 0, '_payment'); dol_syslog("error=".$error." errormessage=".$errormessage, LOG_DEBUG, 0, '_payment'); dol_syslog("_SERVER[SERVER_NAME] = ".(empty($_SERVER["SERVER_NAME"]) ? '' : dol_escape_htmltag($_SERVER["SERVER_NAME"])), LOG_DEBUG, 0, '_payment'); dol_syslog("_SERVER[SERVER_ADDR] = ".(empty($_SERVER["SERVER_ADDR"]) ? '' : dol_escape_htmltag($_SERVER["SERVER_ADDR"])), LOG_DEBUG, 0, '_payment'); dol_syslog("Now call the redirect to paymentok or paymentko, URL = ".($error ? $urlko : $urlok), LOG_DEBUG, 0, '_payment'); if ($error) { header("Location: ".$urlko); exit; } else { header("Location: ".$urlok); exit; } } // This hook is used to push to $validpaymentmethod by external payment modules (ie Payzen, ...) $parameters = array( 'paymentmethod' => $paymentmethod, 'validpaymentmethod' => &$validpaymentmethod ); $reshook = $hookmanager->executeHooks('doPayment', $parameters, $object, $action); if ($reshook < 0) { setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); } elseif ($reshook > 0) { print $hookmanager->resPrint; } /* * View */ $form = new Form($db); $head = ''; if (!empty($conf->global->ONLINE_PAYMENT_CSS_URL)) { $head = ''."\n"; } $conf->dol_hide_topmenu = 1; $conf->dol_hide_leftmenu = 1; $replacemainarea = (empty($conf->dol_hide_leftmenu) ? '
' : '').'
'; llxHeader($head, $langs->trans("PaymentForm"), '', '', 0, 0, '', '', '', 'onlinepaymentbody', $replacemainarea); dol_syslog("--- newpayment.php action = ".$action, LOG_DEBUG, 0, '_payment'); dol_syslog("newpayment.php show page source=".$source." paymentmethod=".$paymentmethod.' amount='.$amount.' newamount='.GETPOST("newamount", 'alpha')." ref=".$ref, LOG_DEBUG, 0, '_payment'); dol_syslog("_SERVER[SERVER_NAME] = ".(empty($_SERVER["SERVER_NAME"]) ? '' : dol_escape_htmltag($_SERVER["SERVER_NAME"])), LOG_DEBUG, 0, '_payment'); dol_syslog("_SERVER[SERVER_ADDR] = ".(empty($_SERVER["SERVER_ADDR"]) ? '' : dol_escape_htmltag($_SERVER["SERVER_ADDR"])), LOG_DEBUG, 0, '_payment'); // Check link validity if ($source && in_array($ref, array('member_ref', 'contractline_ref', 'invoice_ref', 'order_ref', 'donation_ref', ''))) { $langs->load("errors"); dol_print_error_email('BADREFINPAYMENTFORM', $langs->trans("ErrorBadLinkSourceSetButBadValueForRef", $source, $ref)); // End of page llxFooter(); $db->close(); exit; } // Show sandbox warning if ((empty($paymentmethod) || $paymentmethod == 'paypal') && isModEnabled('paypal') && (!empty($conf->global->PAYPAL_API_SANDBOX) || GETPOST('forcesandbox', 'int'))) { // We can force sand box with param 'forcesandbox' dol_htmloutput_mesg($langs->trans('YouAreCurrentlyInSandboxMode', 'Paypal'), '', 'warning'); } if ((empty($paymentmethod) || $paymentmethod == 'stripe') && isModEnabled('stripe') && (empty($conf->global->STRIPE_LIVE) || GETPOST('forcesandbox', 'int'))) { dol_htmloutput_mesg($langs->trans('YouAreCurrentlyInSandboxMode', 'Stripe'), '', 'warning'); } print ''."\n"; print '
'."\n"; print '
'."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''; print ''; print ''; print "\n"; // Show logo (search order: logo defined by PAYMENT_LOGO_suffix, then PAYMENT_LOGO, then small company logo, large company logo, theme logo, common logo) // Define logo and logosmall $logosmall = $mysoc->logo_small; $logo = $mysoc->logo; $paramlogo = 'ONLINE_PAYMENT_LOGO_'.$suffix; if (!empty($conf->global->$paramlogo)) { $logosmall = $conf->global->$paramlogo; } elseif (!empty($conf->global->ONLINE_PAYMENT_LOGO)) { $logosmall = $conf->global->ONLINE_PAYMENT_LOGO; } //print ''."\n"; // Define urllogo $urllogo = ''; $urllogofull = ''; if (!empty($logosmall) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$logosmall)) { $urllogo = DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.'&file='.urlencode('logos/thumbs/'.$logosmall); $urllogofull = $dolibarr_main_url_root.'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.'&file='.urlencode('logos/thumbs/'.$logosmall); } elseif (!empty($logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$logo)) { $urllogo = DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.'&file='.urlencode('logos/'.$logo); $urllogofull = $dolibarr_main_url_root.'/viewimage.php?modulepart=mycompany&entity='.$conf->entity.'&file='.urlencode('logos/'.$logo); } // Output html code for logo if ($urllogo) { print '
'; print '
'; print ''; print '
'; if (empty($conf->global->MAIN_HIDE_POWERED_BY)) { print ''; } print '
'; } if (!empty($conf->global->MAIN_IMAGE_PUBLIC_PAYMENT)) { print '
'; print ''; print '
'; } print ''."\n"; print ''."\n"; // Additionnal information for each payment system if (isModEnabled('paypal')) { print ''."\n"; print ''."\n"; } if (isModEnabled('paybox')) { print ''."\n"; } if (isModEnabled('stripe')) { print ''."\n"; } print ''."\n"; print ''."\n"; print "\n"; // Section with payment informationsummary print ''."\n"; // Output introduction text $text = ''; if (!empty($conf->global->PAYMENT_NEWFORM_TEXT)) { $langs->load("members"); if (preg_match('/^\((.*)\)$/', $conf->global->PAYMENT_NEWFORM_TEXT, $reg)) { $text .= $langs->trans($reg[1])."
\n"; } else { $text .= $conf->global->PAYMENT_NEWFORM_TEXT."
\n"; } $text = ''."\n"; } if (empty($text)) { $text .= ''."\n"; $text .= ''."\n"; } print $text; // Output payment summary form print ''."\n"; print '

'.$text.'

'.$langs->trans("WelcomeOnPaymentPage").'
'.$langs->trans("ThisScreenAllowsYouToPay", $creditor).'

'; print ''; print ''."\n"; $found = false; $error = 0; $object = null; // Free payment if (!$source) { $found = true; $tag = GETPOST("tag", 'alpha'); if (GETPOST('fulltag', 'alpha')) { $fulltag = GETPOST('fulltag', 'alpha'); } else { $fulltag = "TAG=".$tag; } // Creditor print ''."\n"; // Amount print ''."\n"; // Tag print ''."\n"; // We do not add fields shipToName, shipToStreet, shipToCity, shipToState, shipToCountryCode, shipToZip, shipToStreet2, phoneNum // as they don't exists (buyer is unknown, tag is free). } // Payment on a Sale Order if ($source == 'order') { $found = true; $langs->load("orders"); require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php'; $order = new Commande($db); $result = $order->fetch('', $ref); if ($result <= 0) { $mesg = $order->error; $error++; } else { $result = $order->fetch_thirdparty($order->socid); } $object = $order; if ($action != 'dopayment') { // Do not change amount if we just click on first dopayment $amount = $order->total_ttc; if (GETPOST("amount", 'alpha')) { $amount = GETPOST("amount", 'alpha'); } $amount = price2num($amount); } $tag = ''; if (GETPOST('fulltag', 'alpha')) { $fulltag = GETPOST('fulltag', 'alpha'); } else { $fulltag = 'ORD='.$order->id.'.CUS='.$order->thirdparty->id; if (!empty($TAG)) { $tag = $TAG; $fulltag .= '.TAG='.$TAG; } } $fulltag = dol_string_unaccent($fulltag); // Creditor print ''."\n"; // Debitor print ''."\n"; // Object $text = ''.$langs->trans("PaymentOrderRef", $order->ref).''; if (GETPOST('desc', 'alpha')) { $text = ''.$langs->trans(GETPOST('desc', 'alpha')).''; } print ''."\n"; // Amount print ''."\n"; // Tag print ''."\n"; // Shipping address $shipToName = $order->thirdparty->name; $shipToStreet = $order->thirdparty->address; $shipToCity = $order->thirdparty->town; $shipToState = $order->thirdparty->state_code; $shipToCountryCode = $order->thirdparty->country_code; $shipToZip = $order->thirdparty->zip; $shipToStreet2 = ''; $phoneNum = $order->thirdparty->phone; if ($shipToName && $shipToStreet && $shipToCity && $shipToCountryCode && $shipToZip) { print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; } else { print ''."\n"; } if (is_object($order->thirdparty)) { print ''."\n"; } print ''."\n"; print ''."\n"; $labeldesc = $langs->trans("Order").' '.$order->ref; if (GETPOST('desc', 'alpha')) { $labeldesc = GETPOST('desc', 'alpha'); } print ''."\n"; } // Payment on a Customer Invoice if ($source == 'invoice') { $found = true; $langs->load("bills"); require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; $invoice = new Facture($db); $result = $invoice->fetch('', $ref); if ($result <= 0) { $mesg = $invoice->error; $error++; } else { $result = $invoice->fetch_thirdparty($invoice->socid); } $object = $invoice; if ($action != 'dopayment') { // Do not change amount if we just click on first dopayment $amount = price2num($invoice->total_ttc - ($invoice->getSommePaiement() + $invoice->getSumCreditNotesUsed() + $invoice->getSumDepositsUsed())); if (GETPOST("amount", 'alpha')) { $amount = GETPOST("amount", 'alpha'); } $amount = price2num($amount); } if (GETPOST('fulltag', 'alpha')) { $fulltag = GETPOST('fulltag', 'alpha'); } else { $fulltag = 'INV='.$invoice->id.'.CUS='.$invoice->thirdparty->id; if (!empty($TAG)) { $tag = $TAG; $fulltag .= '.TAG='.$TAG; } } $fulltag = dol_string_unaccent($fulltag); // Creditor print ''."\n"; // Debitor print ''."\n"; // Object $text = ''.$langs->trans("PaymentInvoiceRef", $invoice->ref).''; if (GETPOST('desc', 'alpha')) { $text = ''.$langs->trans(GETPOST('desc', 'alpha')).''; } print ''."\n"; // Amount print ''."\n"; // Tag print ''."\n"; // Shipping address $shipToName = $invoice->thirdparty->name; $shipToStreet = $invoice->thirdparty->address; $shipToCity = $invoice->thirdparty->town; $shipToState = $invoice->thirdparty->state_code; $shipToCountryCode = $invoice->thirdparty->country_code; $shipToZip = $invoice->thirdparty->zip; $shipToStreet2 = ''; $phoneNum = $invoice->thirdparty->phone; if ($shipToName && $shipToStreet && $shipToCity && $shipToCountryCode && $shipToZip) { print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; } else { print ''."\n"; } if (is_object($invoice->thirdparty)) { print ''."\n"; } print ''."\n"; print ''."\n"; $labeldesc = $langs->trans("Invoice").' '.$invoice->ref; if (GETPOST('desc', 'alpha')) { $labeldesc = GETPOST('desc', 'alpha'); } print ''."\n"; } // Payment on a Contract line if ($source == 'contractline') { $found = true; $langs->load("contracts"); require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php'; $contract = new Contrat($db); $contractline = new ContratLigne($db); $result = $contractline->fetch('', $ref); if ($result <= 0) { $mesg = $contractline->error; $error++; } else { if ($contractline->fk_contrat > 0) { $result = $contract->fetch($contractline->fk_contrat); if ($result > 0) { $result = $contract->fetch_thirdparty($contract->socid); } else { $mesg = $contract->error; $error++; } } else { $mesg = 'ErrorRecordNotFound'; $error++; } } $object = $contractline; if ($action != 'dopayment') { // Do not change amount if we just click on first dopayment $amount = $contractline->total_ttc; if ($contractline->fk_product && !empty($conf->global->PAYMENT_USE_NEW_PRICE_FOR_CONTRACTLINES)) { $product = new Product($db); $result = $product->fetch($contractline->fk_product); // We define price for product (TODO Put this in a method in product class) if (!empty($conf->global->PRODUIT_MULTIPRICES)) { $pu_ht = $product->multiprices[$contract->thirdparty->price_level]; $pu_ttc = $product->multiprices_ttc[$contract->thirdparty->price_level]; $price_base_type = $product->multiprices_base_type[$contract->thirdparty->price_level]; } else { $pu_ht = $product->price; $pu_ttc = $product->price_ttc; $price_base_type = $product->price_base_type; } $amount = $pu_ttc; if (empty($amount)) { dol_print_error('', 'ErrorNoPriceDefinedForThisProduct'); exit; } } if (GETPOST("amount", 'alpha')) { $amount = GETPOST("amount", 'alpha'); } $amount = price2num($amount); } if (GETPOST('fulltag', 'alpha')) { $fulltag = GETPOST('fulltag', 'alpha'); } else { $fulltag = 'COL='.$contractline->id.'.CON='.$contract->id.'.CUS='.$contract->thirdparty->id.'.DAT='.dol_print_date(dol_now(), '%Y%m%d%H%M%S'); if (!empty($TAG)) { $tag = $TAG; $fulltag .= '.TAG='.$TAG; } } $fulltag = dol_string_unaccent($fulltag); $qty = 1; if (GETPOST('qty')) { $qty = price2num(GETPOST('qty', 'alpha'), 'MS'); } // Creditor print ''."\n"; // Debitor print ''."\n"; // Object $text = ''.$langs->trans("PaymentRenewContractId", $contract->ref, $contractline->ref).''; if ($contractline->fk_product > 0) { $contractline->fetch_product(); $text .= '
'.$contractline->product->ref.($contractline->product->label ? ' - '.$contractline->product->label : ''); } if ($contractline->description) { $text .= '
'.dol_htmlentitiesbr($contractline->description); } if ($contractline->date_end) { $text .= '
'.$langs->trans("ExpiredSince").': '.dol_print_date($contractline->date_end); } if (GETPOST('desc', 'alpha')) { $text = ''.$langs->trans(GETPOST('desc', 'alpha')).''; } print ''."\n"; // Quantity $label = $langs->trans("Quantity"); $qty = 1; $duration = ''; if ($contractline->fk_product) { if ($contractline->product->isService() && $contractline->product->duration_value > 0) { $label = $langs->trans("Duration"); // TODO Put this in a global method if ($contractline->product->duration_value > 1) { $dur = array("h"=>$langs->trans("Hours"), "d"=>$langs->trans("DurationDays"), "w"=>$langs->trans("DurationWeeks"), "m"=>$langs->trans("DurationMonths"), "y"=>$langs->trans("DurationYears")); } else { $dur = array("h"=>$langs->trans("Hour"), "d"=>$langs->trans("DurationDay"), "w"=>$langs->trans("DurationWeek"), "m"=>$langs->trans("DurationMonth"), "y"=>$langs->trans("DurationYear")); } $duration = $contractline->product->duration_value.' '.$dur[$contractline->product->duration_unit]; } } print ''; print ''."\n"; // Amount print ''."\n"; // Tag print ''."\n"; // Shipping address $shipToName = $contract->thirdparty->name; $shipToStreet = $contract->thirdparty->address; $shipToCity = $contract->thirdparty->town; $shipToState = $contract->thirdparty->state_code; $shipToCountryCode = $contract->thirdparty->country_code; $shipToZip = $contract->thirdparty->zip; $shipToStreet2 = ''; $phoneNum = $contract->thirdparty->phone; if ($shipToName && $shipToStreet && $shipToCity && $shipToCountryCode && $shipToZip) { print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; } else { print ''."\n"; } if (is_object($contract->thirdparty)) { print ''."\n"; } print ''."\n"; print ''."\n"; $labeldesc = $langs->trans("Contract").' '.$contract->ref; if (GETPOST('desc', 'alpha')) { $labeldesc = GETPOST('desc', 'alpha'); } print ''."\n"; } // Payment on a Member subscription if ($source == 'member' || $source == 'membersubscription') { $newsource = 'member'; $tag=""; $found = true; $langs->load("members"); require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php'; require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php'; $member = new Adherent($db); $adht = new AdherentType($db); $result = $member->fetch('', $ref); if ($result <= 0) { $mesg = $member->error; $error++; } else { $member->fetch_thirdparty(); $subscription = new Subscription($db); $adht->fetch($member->typeid); } $object = $member; if ($action != 'dopayment') { // Do not change amount if we just click on first dopayment $amount = $subscription->total_ttc; if (GETPOST("amount", 'alpha')) { $amount = GETPOST("amount", 'alpha'); } // If amount still not defined, we take amount of the type of member if (empty($amount)) { $amount = $adht->amount; } $amount = max(0, price2num($amount, 'MT')); } if (GETPOST('fulltag', 'alpha')) { $fulltag = GETPOST('fulltag', 'alpha'); } else { $fulltag = 'MEM='.$member->id.'.DAT='.dol_print_date(dol_now(), '%Y%m%d%H%M%S'); if (!empty($TAG)) { $tag = $TAG; $fulltag .= '.TAG='.$TAG; } } $fulltag = dol_string_unaccent($fulltag); // Creditor print ''."\n"; // Debitor print ''."\n"; // Object $text = ''.$langs->trans("PaymentSubscription").''; if (GETPOST('desc', 'alpha')) { $text = ''.$langs->trans(GETPOST('desc', 'alpha')).''; } print ''."\n"; if ($object->datefin > 0) { print ''."\n"; } if ($member->last_subscription_date || $member->last_subscription_amount) { // Last subscription date print ''."\n"; // Last subscription amount print ''."\n"; if (empty($amount) && !GETPOST('newamount', 'alpha')) { $_GET['newamount'] = $member->last_subscription_amount; $_GET['amount'] = $member->last_subscription_amount; } if (!empty($member->last_subscription_amount) && !GETPOSTISSET('newamount') && is_numeric($amount)) { $amount = max($member->last_subscription_amount, $amount); } } if ($member->type) { $oldtypeid = $member->typeid; $newtypeid = (int) (GETPOSTISSET("typeid") ? GETPOST("typeid", 'int') : $member->typeid); if (!empty($conf->global->MEMBER_ALLOW_CHANGE_OF_TYPE)) { require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent_type.class.php'; $adht = new AdherentType($db); // Amount by member type $amountbytype = $adht->amountByType(1); // Last member type print '\n"; // Set the new member type $member->typeid = $newtypeid; $member->type = dol_getIdFromCode($db, $newtypeid, 'adherent_type', 'rowid', 'libelle'); // list member type if (!$action) { // Set amount for the subscription $amount = (!empty($amountbytype[$member->typeid])) ? $amountbytype[$member->typeid] : $member->last_subscription_amount; print '\n"; } elseif ($action == 'dopayment') { print '\n"; } } else { print '\n"; } } // Amount print ''."\n"; // Tag print ''."\n"; // Shipping address $shipToName = $member->getFullName($langs); $shipToStreet = $member->address; $shipToCity = $member->town; $shipToState = $member->state_code; $shipToCountryCode = $member->country_code; $shipToZip = $member->zip; $shipToStreet2 = ''; $phoneNum = $member->phone; if ($shipToName && $shipToStreet && $shipToCity && $shipToCountryCode && $shipToZip) { print ''; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; } else { print ''."\n"; } if (is_object($member->thirdparty)) { print ''."\n"; } print ''."\n"; $labeldesc = $langs->trans("PaymentSubscription"); if (GETPOST('desc', 'alpha')) { $labeldesc = GETPOST('desc', 'alpha'); } print ''."\n"; } // Payment on donation if ($source == 'donation') { $found = true; $langs->load("don"); require_once DOL_DOCUMENT_ROOT.'/don/class/don.class.php'; $don = new Don($db); $result = $don->fetch($ref); if ($result <= 0) { $mesg = $don->error; $error++; } else { $don->fetch_thirdparty(); } $object = $don; if ($action != 'dopayment') { // Do not change amount if we just click on first dopayment if (GETPOST("amount", 'alpha')) { $amount = GETPOST("amount", 'alpha'); } else { $amount = $don->getRemainToPay(); } $amount = price2num($amount); } if (GETPOST('fulltag', 'alpha')) { $fulltag = GETPOST('fulltag', 'alpha'); } else { $fulltag = 'DON='.$don->ref.'.DAT='.dol_print_date(dol_now(), '%Y%m%d%H%M%S'); if (!empty($TAG)) { $tag = $TAG; $fulltag .= '.TAG='.$TAG; } } $fulltag = dol_string_unaccent($fulltag); // Creditor print ''."\n"; // Debitor print ''."\n"; // Object $text = ''.$langs->trans("PaymentDonation").''; if (GETPOST('desc', 'alpha')) { $text = ''.$langs->trans(GETPOST('desc', 'alpha')).''; } print ''."\n"; // Amount print ''."\n"; // Tag print ''."\n"; // Shipping address $shipToName = $don->getFullName($langs); $shipToStreet = $don->address; $shipToCity = $don->town; $shipToState = $don->state_code; $shipToCountryCode = $don->country_code; $shipToZip = $don->zip; $shipToStreet2 = ''; $phoneNum = $don->phone; if ($shipToName && $shipToStreet && $shipToCity && $shipToCountryCode && $shipToZip) { print ''; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; } else { print ''."\n"; } if (is_object($don->thirdparty)) { print ''."\n"; } print ''."\n"; $labeldesc = $langs->trans("PaymentSubscription"); if (GETPOST('desc', 'alpha')) { $labeldesc = GETPOST('desc', 'alpha'); } print ''."\n"; } if ($source == 'organizedeventregistration') { $found = true; $langs->loadLangs(array("members", "eventorganization")); if (GETPOST('fulltag', 'alpha')) { $fulltag = GETPOST('fulltag', 'alpha'); } else { $fulltag = 'ATT='.$attendee->id.'.DAT='.dol_print_date(dol_now(), '%Y%m%d%H%M%S'); if (!empty($TAG)) { $tag = $TAG; $fulltag .= '.TAG='.$TAG; } } $fulltag = dol_string_unaccent($fulltag); // Creditor print ''."\n"; // Debitor print ''."\n"; if (! is_object($attendee->project)) { $text = 'ErrorProjectNotFound'; } else { $text = $langs->trans("PaymentEvent").' - '.$attendee->project->title; } // Object print ''."\n"; // Amount print ''."\n"; // Tag print ''."\n"; // Shipping address $shipToName = $thirdparty->getFullName($langs); $shipToStreet = $thirdparty->address; $shipToCity = $thirdparty->town; $shipToState = $thirdparty->state_code; $shipToCountryCode = $thirdparty->country_code; $shipToZip = $thirdparty->zip; $shipToStreet2 = ''; $phoneNum = $thirdparty->phone; if ($shipToName && $shipToStreet && $shipToCity && $shipToCountryCode && $shipToZip) { print ''; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; } else { print ''."\n"; } print ''."\n"; print ''."\n"; $labeldesc = $langs->trans("PaymentSubscription"); if (GETPOST('desc', 'alpha')) { $labeldesc = GETPOST('desc', 'alpha'); } print ''."\n"; } if ($source == 'boothlocation') { $found = true; $langs->load("members"); if (GETPOST('fulltag', 'alpha')) { $fulltag = GETPOST('fulltag', 'alpha'); } else { $fulltag = 'BOO='.GETPOST("booth").'.DAT='.dol_print_date(dol_now(), '%Y%m%d%H%M%S'); if (!empty($TAG)) { $tag = $TAG; $fulltag .= '.TAG='.$TAG; } } $fulltag = dol_string_unaccent($fulltag); // Creditor print ''."\n"; // Debitor print ''."\n"; // Object $text = ''.$langs->trans("PaymentBoothLocation").''; print ''."\n"; // Amount print ''."\n"; // Tag print ''."\n"; // Shipping address $shipToName = $thirdparty->getFullName($langs); $shipToStreet = $thirdparty->address; $shipToCity = $thirdparty->town; $shipToState = $thirdparty->state_code; $shipToCountryCode = $thirdparty->country_code; $shipToZip = $thirdparty->zip; $shipToStreet2 = ''; $phoneNum = $thirdparty->phone; if ($shipToName && $shipToStreet && $shipToCity && $shipToCountryCode && $shipToZip) { print ''; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; } else { print ''."\n"; } print ''."\n"; print ''."\n"; $labeldesc = $langs->trans("PaymentSubscription"); if (GETPOST('desc', 'alpha')) { $labeldesc = GETPOST('desc', 'alpha'); } print ''."\n"; } if (!$found && !$mesg) { $mesg = $langs->trans("ErrorBadParameters"); } if ($mesg) { print ''."\n"; } print '
'.$langs->trans("ThisIsInformationOnPayment").' :
'.$langs->trans("Creditor"); print ''; print img_picto('', 'company', 'class="pictofixedwidth"'); print ''.$creditor.''; print ''; print '
'.$langs->trans("Amount"); if (empty($amount)) { print ' ('.$langs->trans("ToComplete").')'; } print ''; if (empty($amount) || !is_numeric($amount)) { print ''; print ''; // Currency print ' '.$langs->trans("Currency".$currency).''; } else { print ''.price($amount, 1, $langs, 1, -1, -1, $currency).''; // Price with currency print ''; print ''; } print ''; print '
'.$langs->trans("PaymentCode"); print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("Creditor"); print ''; print img_picto('', 'company', 'class="pictofixedwidth"'); print ''.$creditor.''; print ''; print '
'.$langs->trans("ThirdParty"); print ''; print img_picto('', 'company', 'class="pictofixedwidth"'); print ''.$order->thirdparty->name.''; print '
'.$langs->trans("Designation"); print ''.$text; print ''; print ''; print ''; $directdownloadlink = $order->getLastMainDocLink('commande'); if ($directdownloadlink) { print '
'; print img_mime($order->last_main_doc, ''); print $langs->trans("DownloadDocument").''; } print '
'.$langs->trans("Amount"); if (empty($amount)) { print ' ('.$langs->trans("ToComplete").')'; } print ''; if (empty($amount) || !is_numeric($amount)) { print ''; print ''; // Currency print ' '.$langs->trans("Currency".$currency).''; } else { print ''.price($amount, 1, $langs, 1, -1, -1, $currency).''; // Price with currency print ''; print ''; } print ''; print '
'.$langs->trans("PaymentCode"); print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("Creditor"); print ''; print img_picto('', 'company', 'class="pictofixedwidth"'); print ''.$creditor.''; print ''; print '
'.$langs->trans("ThirdParty"); print ''; print img_picto('', 'company', 'class="pictofixedwidth"'); print ''.$invoice->thirdparty->name.''; print '
'.$langs->trans("Designation"); print ''.$text; print ''; print ''; print ''; $directdownloadlink = $invoice->getLastMainDocLink('facture'); if ($directdownloadlink) { print '
'; print img_mime($invoice->last_main_doc, ''); print $langs->trans("DownloadDocument").''; } print '
'.$langs->trans("PaymentAmount"); if (empty($amount) && empty($object->paye)) { print ' ('.$langs->trans("ToComplete").')'; } print ''; if ($object->type == $object::TYPE_CREDIT_NOTE) { print ''.$langs->trans("CreditNote").''; } elseif (empty($object->paye)) { if (empty($amount) || !is_numeric($amount)) { print ''; print ''; print ' '.$langs->trans("Currency".$currency).''; } else { print ''.price($amount, 1, $langs, 1, -1, -1, $currency).''; // Price with currency print ''; print ''; } } else { print ''.price($object->total_ttc, 1, $langs, 1, -1, -1, $currency).''; // Price with currency } print ''; print '
'.$langs->trans("PaymentCode"); print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("Creditor"); print ''.$creditor.''; print ''; print '
'.$langs->trans("ThirdParty"); print ''.$contract->thirdparty->name.''; print '
'.$langs->trans("Designation"); print ''.$text; print ''; print ''; print ''; $directdownloadlink = $contract->getLastMainDocLink('contract'); if ($directdownloadlink) { print '
'; print img_mime($contract->last_main_doc, ''); print $langs->trans("DownloadDocument").''; } print '
'.$label.''.($duration ? $duration : $qty).''; print ''; print '
'.$langs->trans("Amount"); if (empty($amount)) { print ' ('.$langs->trans("ToComplete").')'; } print ''; if (empty($amount) || !is_numeric($amount)) { print ''; print ''; // Currency print ' '.$langs->trans("Currency".$currency).''; } else { print ''.price($amount, 1, $langs, 1, -1, -1, $currency).''; // Price with currency print ''; print ''; } print ''; print '
'.$langs->trans("PaymentCode"); print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("Creditor"); print ''.$creditor.''; print ''; print '
'.$langs->trans("Member"); print ''; print ''; if ($member->morphy == 'mor' && !empty($member->company)) { print img_picto('', 'company', 'class="pictofixedwidth"'); print $member->company; } else { print img_picto('', 'member', 'class="pictofixedwidth"'); print $member->getFullName($langs); } print ''; print '
'.$langs->trans("Designation"); print ''.$text; print ''; print ''; print '
'.$langs->trans("DateEndSubscription"); print ''.dol_print_date($member->datefin, 'day'); print '
'.$langs->trans("LastSubscriptionDate"); print ''.dol_print_date($member->last_subscription_date, 'day'); print '
'.$langs->trans("LastSubscriptionAmount"); print ''.price($member->last_subscription_amount); print '
'.$langs->trans("LastMemberType"); print ''.dol_escape_htmltag($member->type); print "
'.$langs->trans("NewSubscription"); print ''; 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); print "
'.$langs->trans("NewMemberType"); print ''.dol_escape_htmltag($member->type); print ''; print "
'.$langs->trans("MemberType"); print ''.dol_escape_htmltag($member->type); print "
'.$langs->trans("Amount"); // This place no longer allows amount edition if (!empty($conf->global->MEMBER_EXT_URL_SUBSCRIPTION_INFO)) { print ' - '.$langs->trans("SeeHere").''; } print ''; if (!empty($conf->global->MEMBER_MIN_AMOUNT) && $amount) { $amount = max(0, $conf->global->MEMBER_MIN_AMOUNT, $amount); } $caneditamount = $adht->caneditamount; $minimumamount = empty($conf->global->MEMBER_MIN_AMOUNT)? $adht->amount : max($conf->global->MEMBER_MIN_AMOUNT, $adht->amount, $amount); if ($caneditamount && $action != 'dopayment') { if (GETPOSTISSET('newamount')) { print ''; } else { print ''; } } else { print ''.price($amount, 1, $langs, 1, -1, -1, $currency).''; // Price with currency if ($minimumamount > $amount) { print '   '. $langs->trans("AmountIsLowerToMinimumNotice", price($minimumamount, 1, $langs, 1, -1, -1, $currency)).''; } print ''; } print ''; print ''; print '
'.$langs->trans("PaymentCode"); print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("Creditor"); print ''.$creditor.''; print ''; print '
'.$langs->trans("ThirdParty"); print ''; if ($don->morphy == 'mor' && !empty($don->societe)) { print $don->societe; } else { print $don->getFullName($langs); } print ''; print '
'.$langs->trans("Designation"); print ''.$text; print ''; print ''; print '
'.$langs->trans("Amount"); if (empty($amount)) { if (empty($conf->global->DONATION_NEWFORM_AMOUNT)) { print ' ('.$langs->trans("ToComplete"); } if (!empty($conf->global->DONATION_EXT_URL_SUBSCRIPTION_INFO)) { print ' - '.$langs->trans("SeeHere").''; } if (empty($conf->global->DONATION_NEWFORM_AMOUNT)) { print ')'; } } print ''; $valtoshow = ''; if (empty($amount) || !is_numeric($amount)) { $valtoshow = price2num(GETPOST("newamount", 'alpha'), 'MT'); // force default subscription amount to value defined into constant... if (empty($valtoshow)) { if (!empty($conf->global->DONATION_NEWFORM_EDITAMOUNT)) { if (!empty($conf->global->DONATION_NEWFORM_AMOUNT)) { $valtoshow = $conf->global->DONATION_NEWFORM_AMOUNT; } } else { if (!empty($conf->global->DONATION_NEWFORM_AMOUNT)) { $amount = $conf->global->DONATION_NEWFORM_AMOUNT; } } } } if (empty($amount) || !is_numeric($amount)) { //$valtoshow=price2num(GETPOST("newamount",'alpha'),'MT'); if (!empty($conf->global->DONATION_MIN_AMOUNT) && $valtoshow) { $valtoshow = max($conf->global->DONATION_MIN_AMOUNT, $valtoshow); } print ''; print ''; // Currency print ' '.$langs->trans("Currency".$currency).''; } else { $valtoshow = $amount; if (!empty($conf->global->DONATION_MIN_AMOUNT) && $valtoshow) { $valtoshow = max($conf->global->DONATION_MIN_AMOUNT, $valtoshow); $amount = $valtoshow; } print ''.price($valtoshow, 1, $langs, 1, -1, -1, $currency).''; // Price with currency print ''; print ''; } print ''; print '
'.$langs->trans("PaymentCode"); print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("Creditor"); print ''.$creditor.''; print ''; print '
'.$langs->trans("Attendee"); print ''; print $attendee->email; print ($thirdparty->name ? ' ('.$thirdparty->name.')' : ''); print ''; print '
'.$langs->trans("Designation"); print ''.$text.''; print ''; print ''; print '
'.$langs->trans("Amount"); print ''; $valtoshow = $amount; print ''.price($valtoshow, 1, $langs, 1, -1, -1, $currency).''; // Price with currency print ''; print ''; print ''; print '
'.$langs->trans("PaymentCode"); print ''.$fulltag.''; print ''; print ''; print '
'.$langs->trans("Creditor"); print ''.$creditor.''; print ''; print '
'.$langs->trans("Attendee"); print ''; print $thirdparty->name; print ''; print '
'.$langs->trans("Designation"); print ''.$text; print ''; print ''; print '
'.$langs->trans("Amount"); print ''; $valtoshow = $amount; print ''.price($valtoshow, 1, $langs, 1, -1, -1, $currency).''; // Price with currency print ''; print ''; print ''; print '
'.$langs->trans("PaymentCode"); print ''.$fulltag.''; print ''; print ''; print '

'.dol_escape_htmltag($mesg, 1, 1, 'br').'
'."\n"; print "\n"; // Show all payment mode buttons (Stripe, Paypal, ...) if ($action != 'dopayment') { if ($found && !$error) { // We are in a management option and no error // Check status of the object (Invoice) to verify if it is paid by external payment modules (ie Payzen, ...) $parameters = [ 'source' => $source, 'object' => $object ]; $reshook = $hookmanager->executeHooks('doCheckStatus', $parameters, $object, $action); if ($reshook < 0) { setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); } elseif ($reshook > 0) { print $hookmanager->resPrint; } if ($source == 'order' && $object->billed) { print '

'.$langs->trans("OrderBilled").''; } elseif ($source == 'invoice' && $object->paye) { print '

'.$langs->trans("InvoicePaid").''; } elseif ($source == 'donation' && $object->paid) { print '

'.$langs->trans("DonationPaid").''; } else { // Membership can be paid and we still allow to make renewal if (($source == 'member' || $source == 'membersubscription') && $object->datefin > dol_now()) { $langs->load("members"); print '
'.$langs->trans("MembershipPaid", dol_print_date($object->datefin, 'day')).'
'; print '
'.$langs->trans("PaymentWillBeRecordedForNextPeriod").'
'; } // Buttons for all payments registration methods // This hook is used to add Button to newpayment.php for external payment modules (ie Payzen, ...) $parameters = [ 'paymentmethod' => $paymentmethod ]; $reshook = $hookmanager->executeHooks('doAddButton', $parameters, $object, $action); if ($reshook < 0) { setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); } elseif ($reshook > 0) { print $hookmanager->resPrint; } if ((empty($paymentmethod) || $paymentmethod == 'paybox') && isModEnabled('paybox')) { print '
'; print '
'; print ''.$langs->trans("CreditOrDebitCard").''; print '
'; print ' '; } if ((empty($paymentmethod) || $paymentmethod == 'stripe') && isModEnabled('stripe')) { print '
'; print ''; print '
'; print ''.$langs->trans("CreditOrDebitCard").''; print '
'; print ' '; } if ((empty($paymentmethod) || $paymentmethod == 'paypal') && isModEnabled('paypal')) { if (empty($conf->global->PAYPAL_API_INTEGRAL_OR_PAYPALONLY)) { $conf->global->PAYPAL_API_INTEGRAL_OR_PAYPALONLY = 'integral'; } print '
'; if ($conf->global->PAYPAL_API_INTEGRAL_OR_PAYPALONLY != 'integral') { print '
 
'; } print ' '; if ($conf->global->PAYPAL_API_INTEGRAL_OR_PAYPALONLY == 'integral') { print '
'; print ''.$langs->trans("CreditOrDebitCard").' - '; print ''.$langs->trans("PayPalBalance").''; } if ($conf->global->PAYPAL_API_INTEGRAL_OR_PAYPALONLY == 'paypalonly') { //print '
'; //print ''.$langs->trans("PayPalBalance").'">'; } print '
'; print ' '; } } } else { dol_print_error_email('ERRORNEWPAYMENT'); } } else { // Print } print '
'."\n"; print '
'."\n"; print '
'."\n"; print '
'; // Add more content on page for some services if (preg_match('/^dopayment/', $action)) { // If we choosed/click on the payment mode // Save some data for the paymentok $remoteip = getUserRemoteIP(); $_SESSION["currencyCodeType"] = $currency; $_SESSION["FinalPaymentAmt"] = $amount; $_SESSION['ipaddress'] = ($remoteip ? $remoteip : 'unknown'); // Payer ip $_SESSION["paymentType"] = ''; // For Stripe if (GETPOST('dopayment_stripe', 'alpha')) { // Personalized checkout print ''; //print '
'; print ''."\n"; print '
'."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''."\n"; print ''; print ''."\n"; print ''."\n"; print ''; print ''; print ''; print ''; if (!empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION) || !empty($conf->global->STRIPE_USE_NEW_CHECKOUT)) { // Use a SCA ready method require_once DOL_DOCUMENT_ROOT.'/stripe/class/stripe.class.php'; $service = 'StripeLive'; $servicestatus = 1; if (empty($conf->global->STRIPE_LIVE) || GETPOST('forcesandbox', 'alpha')) { $service = 'StripeTest'; $servicestatus = 0; } $stripe = new Stripe($db); $stripeacc = $stripe->getStripeAccount($service); $stripecu = null; if (is_object($object) && is_object($object->thirdparty)) { $stripecu = $stripe->customerStripe($object->thirdparty, $stripeacc, $servicestatus, 1); } if (!empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) { $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. $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); // The paymentintnent has status 'requires_payment_method' (even if paymentintent was already paid) //var_dump($paymentintent); if ($stripe->error) { setEventMessages($stripe->error, null, 'errors'); } } } // Note: // $conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION = 1 = use intent object (default value, suggest card payment mode only) // $conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION = 2 = use payment object (suggest both card payment mode but also sepa, ...) print ' '; print '
'; if (!empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) { print '
'; } print '
'; if (getDolGlobalInt('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION') == 1) { print ''; print '
'; } if (getDolGlobalInt('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION') == 1) { print '
'; } if (getDolGlobalInt('STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION') == 2) { print '
'; } print '
'; print '
'; print ''; print ''; print '
'; //} if (!empty($conf->global->STRIPE_USE_INTENT_WITH_AUTOMATIC_CONFIRMATION)) { if (empty($paymentintent)) { print '
'.$langs->trans("Error").'
'; } else { print ''; //$_SESSION["paymentintent_id"] = $paymentintent->id; } } print '
'."\n"; // JS Code for Stripe if (empty($stripearrayofkeys['publishable_key'])) { $langs->load("errors"); print info_admin($langs->trans("ErrorModuleSetupNotComplete", $langs->transnoentitiesnoconv("Stripe")), 0, 0, 'error'); } else { print ''; print ''."\n"; print ''."\n"; // Code to ask the credit card. This use the default "API version". No way to force API version when using JS code. print ''; } } // For any other payment services // This hook can be used to show the embedded form to make payments with external payment modules (ie Payzen, ...) $parameters = [ 'paymentmethod' => $paymentmethod, 'amount' => $amount, 'currency' => $currency, 'tag' => GETPOST("tag", 'alpha'), 'dopayment' => GETPOST('dopayment', 'alpha') ]; $reshook = $hookmanager->executeHooks('doPayment', $parameters, $object, $action); if ($reshook < 0) { setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); } elseif ($reshook > 0) { print $hookmanager->resPrint; } } htmlPrintOnlineFooter($mysoc, $langs, 1, $suffix, $object); llxFooter('', 'public'); $db->close();