newpayment.php 108 KB

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