newpayment.php 46 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225
  1. <?php
  2. /* Copyright (C) 2017 Alexandre Spangaro <aspangaro@zendsi.com>
  3. * Copyright (C) 2017 Saasprov <saasprov@gmail.com>
  4. * Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. /**
  20. * \file htdocs/public/stripe/newpayment.php
  21. * \ingroup Stripe
  22. * \brief Page to do payment with Stripe
  23. */
  24. define("NOLOGIN",1); // This means this output page does not require to be logged.
  25. define("NOCSRFCHECK",1); // We accept to go on this page from external web site.
  26. // For MultiCompany module.
  27. // Do not use GETPOST here, function is not defined and define must be done before including main.inc.php
  28. // TODO This should be useless. Because entity must be retreive from object ref and not from url.
  29. $entity=(! empty($_GET['entity']) ? (int) $_GET['entity'] : (! empty($_POST['entity']) ? (int) $_POST['entity'] : 1));
  30. if (is_numeric($entity)) define("DOLENTITY", $entity);
  31. require '../../main.inc.php';
  32. require_once DOL_DOCUMENT_ROOT.'/stripe/config.php';
  33. /* included into config.php
  34. require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
  35. require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
  36. require_once DOL_DOCUMENT_ROOT.'/stripe/lib/stripe.lib.php';
  37. require_once DOL_DOCUMENT_ROOT.'/includes/stripe/init.php';
  38. */
  39. // Security check
  40. if (empty($conf->stripe->enabled)) accessforbidden('',0,0,1);
  41. $langs->load("main");
  42. $langs->load("companies");
  43. $langs->load("other");
  44. $langs->load("paybox"); // File with generic data
  45. $langs->load("paypal");
  46. $langs->load("stripe");
  47. $action=GETPOST('action','alpha');
  48. // Input are:
  49. // type ('invoice','order','contractline'),
  50. // id (object id),
  51. // amount (required if id is empty),
  52. // tag (a free text, required if type is empty)
  53. // currency (iso code)
  54. $suffix=GETPOST("suffix",'alpha');
  55. $amount=price2num(GETPOST("amount"));
  56. if (! GETPOST("currency",'alpha')) $currency=$conf->currency;
  57. else $currency=GETPOST("currency",'alpha');
  58. if (! $action)
  59. {
  60. if (! GETPOST("amount") && ! GETPOST("source"))
  61. {
  62. dol_print_error('',$langs->trans('ErrorBadParameters')." - amount or source");
  63. exit;
  64. }
  65. if (is_numeric($amount) && ! GETPOST("tag") && ! GETPOST("source"))
  66. {
  67. dol_print_error('',$langs->trans('ErrorBadParameters')." - tag or source");
  68. exit;
  69. }
  70. if (GETPOST("source") && ! GETPOST("ref"))
  71. {
  72. dol_print_error('',$langs->trans('ErrorBadParameters')." - ref");
  73. exit;
  74. }
  75. }
  76. // Define $urlwithroot
  77. //$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root));
  78. //$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
  79. $urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
  80. $urlok=$urlwithroot.'/public/stripe/paymentok.php?';
  81. $urlko=$urlwithroot.'/public/stripe/paymentko.php?';
  82. // Complete urls for post treatment
  83. $SOURCE=GETPOST("source",'alpha');
  84. $ref=$REF=GETPOST('ref','alpha');
  85. $TAG=GETPOST("tag",'alpha');
  86. $FULLTAG=GETPOST("fulltag",'alpha'); // fulltag is tag with more informations
  87. $SECUREKEY=GETPOST("securekey"); // Secure key
  88. if (! preg_match('/'.preg_quote('PM=stripe','/').'/', $FULLTAG)) $FULLTAG.=($FULLTAG?'.':'').'PM=stripe';
  89. if (! empty($SOURCE))
  90. {
  91. $urlok.='source='.urlencode($SOURCE).'&';
  92. $urlko.='source='.urlencode($SOURCE).'&';
  93. }
  94. if (! empty($REF))
  95. {
  96. $urlok.='ref='.urlencode($REF).'&';
  97. $urlko.='ref='.urlencode($REF).'&';
  98. }
  99. if (! empty($TAG))
  100. {
  101. $urlok.='tag='.urlencode($TAG).'&';
  102. $urlko.='tag='.urlencode($TAG).'&';
  103. }
  104. if (! empty($FULLTAG))
  105. {
  106. $urlok.='fulltag='.urlencode($FULLTAG).'&';
  107. $urlko.='fulltag='.urlencode($FULLTAG).'&';
  108. }
  109. if (! empty($SECUREKEY))
  110. {
  111. $urlok.='securekey='.urlencode($SECUREKEY).'&';
  112. $urlko.='securekey='.urlencode($SECUREKEY).'&';
  113. }
  114. if (! empty($entity))
  115. {
  116. $urlok.='entity='.urlencode($entity).'&';
  117. $urlko.='entity='.urlencode($entity).'&';
  118. }
  119. $urlok=preg_replace('/&$/','',$urlok); // Remove last &
  120. $urlko=preg_replace('/&$/','',$urlko); // Remove last &
  121. // Check parameters
  122. /*
  123. $STRIPE_API_OK="";
  124. if ($urlok) $STRIPE_API_OK=$urlok;
  125. $STRIPE_API_KO="";
  126. if ($urlko) $STRIPE_API_KO=$urlko;
  127. if (empty($STRIPE_API_USER))
  128. {
  129. dol_print_error('',"Paypal setup param STRIPE_API_USER not defined");
  130. return -1;
  131. }
  132. if (empty($STRIPE_API_PASSWORD))
  133. {
  134. dol_print_error('',"Paypal setup param STRIPE_API_PASSWORD not defined");
  135. return -1;
  136. }
  137. if (empty($STRIPE_API_SIGNATURE))
  138. {
  139. dol_print_error('',"Paypal setup param STRIPE_API_SIGNATURE not defined");
  140. return -1;
  141. }
  142. */
  143. // Check security token
  144. $valid=true;
  145. if (! empty($conf->global->STRIPE_SECURITY_TOKEN))
  146. {
  147. if (! empty($conf->global->STRIPE_SECURITY_TOKEN_UNIQUE))
  148. {
  149. if ($SOURCE && $REF) $token = dol_hash($conf->global->STRIPE_SECURITY_TOKEN . $SOURCE . $REF, 2); // Use the source in the hash to avoid duplicates if the references are identical
  150. else $token = dol_hash($conf->global->STRIPE_SECURITY_TOKEN, 2);
  151. }
  152. else
  153. {
  154. $token = $conf->global->STRIPE_SECURITY_TOKEN;
  155. }
  156. if ($SECUREKEY != $token) $valid=false;
  157. if (! $valid)
  158. {
  159. print '<div class="error">Bad value for key.</div>';
  160. //print 'SECUREKEY='.$SECUREKEY.' token='.$token.' valid='.$valid;
  161. exit;
  162. }
  163. }
  164. // Common variables
  165. $creditor=$mysoc->name;
  166. $paramcreditor='STRIPE_CREDITOR_'.$suffix;
  167. if (! empty($conf->global->$paramcreditor)) $creditor=$conf->global->$paramcreditor;
  168. else if (! empty($conf->global->STRIPE_CREDITOR)) $creditor=$conf->global->STRIPE_CREDITOR;
  169. /*
  170. * Actions
  171. */
  172. if ($action == 'dopayment') // We click on button Create payment
  173. {
  174. if (GETPOST('newamount')) $amount = GETPOST('newamount');
  175. else
  176. {
  177. setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Amount")), null, 'errors');
  178. $action = '';
  179. }
  180. }
  181. if ($action == 'charge')
  182. {
  183. // Correct the amount according to unit of currency
  184. // See https://support.stripe.com/questions/which-zero-decimal-currencies-does-stripe-support
  185. $arrayzerounitcurrency=array('BIF', 'CLP', 'DJF', 'GNF', 'JPY', 'KMF', 'KRW', 'MGA', 'PYG', 'RWF', 'VND', 'VUV', 'XAF', 'XOF', 'XPF');
  186. if (! in_array($currency, $arrayzerounitcurrency)) $amount=$amount * 100;
  187. dol_syslog("POST keys : ".join(',', array_keys($_POST)), LOG_DEBUG, 0, '_stripe');
  188. dol_syslog("POST values: ".join(',', $_POST), LOG_DEBUG, 0, '_stripe');
  189. $stripeToken = GETPOST("stripeToken",'alpha');
  190. $email = GETPOST("stripeEmail",'alpha');
  191. dol_syslog("stripeToken = ".$stripeToken, LOG_DEBUG, 0, '_stripe');
  192. dol_syslog("stripeEmail = ".$stripeEmail, LOG_DEBUG, 0, '_stripe');
  193. $error = 0;
  194. try {
  195. dol_syslog("Create customer", LOG_DEBUG, 0, '_stripe');
  196. $customer = \Stripe\Customer::create(array(
  197. 'email' => $email,
  198. 'description' => ($email?'Customer for '.$email:null),
  199. 'metadata' => array('ipaddress'=>$_SERVER['REMOTE_ADDR']),
  200. '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 ?)
  201. ));
  202. // TODO Add 'business_vat_id' ?
  203. dol_syslog("Create charge", LOG_DEBUG, 0, '_stripe');
  204. $charge = \Stripe\Charge::create(array(
  205. 'customer' => $customer->id,
  206. 'amount' => price2num($amount, 'MU'),
  207. 'currency' => $currency,
  208. 'description' => 'Stripe payment: '.$FULLTAG,
  209. 'metadata' => array("FULLTAG" => $FULLTAG, 'Recipient' => $mysoc->name),
  210. 'statement_descriptor' => dol_trunc(dol_trunc(dol_string_unaccent($mysoc->name), 6, 'right', 'UTF-8', 1).' '.$FULLTAG, 22, 'right', 'UTF-8', 1) // 22 chars that appears on bank receipt
  211. ));
  212. } catch(\Stripe\Error\Card $e) {
  213. // Since it's a decline, \Stripe\Error\Card will be caught
  214. $body = $e->getJsonBody();
  215. $err = $body['error'];
  216. print('Status is:' . $e->getHttpStatus() . "\n");
  217. print('Type is:' . $err['type'] . "\n");
  218. print('Code is:' . $err['code'] . "\n");
  219. // param is '' in this case
  220. print('Param is:' . $err['param'] . "\n");
  221. print('Message is:' . $err['message'] . "\n");
  222. $error++;
  223. setEventMessages($e->getMessage(), null, 'errors');
  224. dol_syslog($e->getMessage(), LOG_WARNING, 0, '_stripe');
  225. $action='';
  226. } catch (\Stripe\Error\RateLimit $e) {
  227. // Too many requests made to the API too quickly
  228. $error++;
  229. dol_syslog($e->getMessage(), LOG_WARNING, 0, '_stripe');
  230. setEventMessages($e->getMessage(), null, 'errors');
  231. $action='';
  232. } catch (\Stripe\Error\InvalidRequest $e) {
  233. // Invalid parameters were supplied to Stripe's API
  234. $error++;
  235. dol_syslog($e->getMessage(), LOG_WARNING, 0, '_stripe');
  236. setEventMessages($e->getMessage(), null, 'errors');
  237. $action='';
  238. } catch (\Stripe\Error\Authentication $e) {
  239. // Authentication with Stripe's API failed
  240. // (maybe you changed API keys recently)
  241. $error++;
  242. dol_syslog($e->getMessage(), LOG_WARNING, 0, '_stripe');
  243. setEventMessages($e->getMessage(), null, 'errors');
  244. $action='';
  245. } catch (\Stripe\Error\ApiConnection $e) {
  246. // Network communication with Stripe failed
  247. $error++;
  248. dol_syslog($e->getMessage(), LOG_WARNING, 0, '_stripe');
  249. setEventMessages($e->getMessage(), null, 'errors');
  250. $action='';
  251. } catch (\Stripe\Error\Base $e) {
  252. // Display a very generic error to the user, and maybe send
  253. // yourself an email
  254. $error++;
  255. dol_syslog($e->getMessage(), LOG_WARNING, 0, '_stripe');
  256. setEventMessages($e->getMessage(), null, 'errors');
  257. $action='';
  258. } catch (Exception $e) {
  259. // Something else happened, completely unrelated to Stripe
  260. $error++;
  261. dol_syslog($e->getMessage(), LOG_WARNING, 0, '_stripe');
  262. setEventMessages($e->getMessage(), null, 'errors');
  263. $action='';
  264. }
  265. $_SESSION["onlinetoken"] = $stripeToken;
  266. $_SESSION["FinalPaymentAmt"] = $amount;
  267. $_SESSION["currencyCodeType"] = $currency;
  268. $_SESSION["paymentType"] = '';
  269. $_SESSION['ipaddress'] = $_SERVER['REMOTE_ADDR']; // Payer ip
  270. $_SESSION['payerID'] = is_object($customer)?$customer->id:'';
  271. $_SESSION['TRANSACTIONID'] = is_object($charge)?$charge->id:'';
  272. dol_syslog("Action charge stripe result=".$error." ip=".$_SESSION['ipaddress'], LOG_DEBUG, 0, '_stripe');
  273. dol_syslog("onlinetoken=".$_SESSION["onlinetoken"]." FinalPaymentAmt=".$_SESSION["FinalPaymentAmt"]." currencyCodeType=".$_SESSION["currencyCodeType"]." payerID=".$_SESSION['payerID']." TRANSACTIONID=".$_SESSION['TRANSACTIONID'], LOG_DEBUG, 0, '_stripe');
  274. dol_syslog("FULLTAG=".$FULLTAG, LOG_DEBUG, 0, '_stripe');
  275. dol_syslog("Now call the redirect to paymentok or paymentko", LOG_DEBUG, 0, '_stripe');
  276. if ($error)
  277. {
  278. header("Location: ".$urlko);
  279. exit;
  280. }
  281. else
  282. {
  283. header("Location: ".$urlok);
  284. exit;
  285. }
  286. }
  287. /*
  288. * View
  289. */
  290. $head='';
  291. if (! empty($conf->global->STRIPE_CSS_URL)) $head='<link rel="stylesheet" type="text/css" href="'.$conf->global->STRIPE_CSS_URL.'?lang='.$langs->defaultlang.'">'."\n";
  292. $conf->dol_hide_topmenu=1;
  293. $conf->dol_hide_leftmenu=1;
  294. llxHeader($head, $langs->trans("PaymentForm"), '', '', 0, 0, '', '', '', 'onlinepaymentbody');
  295. if (empty($conf->global->STRIPE_LIVE))
  296. {
  297. dol_htmloutput_mesg($langs->trans('YouAreCurrentlyInSandboxMode'),'','warning');
  298. }
  299. print '<span id="dolpaymentspan"></span>'."\n";
  300. print '<div class="center">'."\n";
  301. print '<form id="dolpaymentform" class="center" name="paymentform" action="'.$_SERVER["PHP_SELF"].'" method="POST">'."\n";
  302. print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'."\n";
  303. print '<input type="hidden" name="action" value="dopayment">'."\n";
  304. print '<input type="hidden" name="tag" value="'.GETPOST("tag",'alpha').'">'."\n";
  305. print '<input type="hidden" name="suffix" value="'.GETPOST("suffix",'alpha').'">'."\n";
  306. print '<input type="hidden" name="securekey" value="'.$SECUREKEY.'">'."\n";
  307. print '<input type="hidden" name="entity" value="'.$entity.'" />';
  308. print "\n";
  309. print '<!-- Form to send a Stripe payment -->'."\n";
  310. print '<!-- STRIPE_API_SANDBOX = '.$conf->global->STRIPE_API_SANDBOX.' -->'."\n";
  311. print '<!-- creditor = '.$creditor.' -->'."\n";
  312. print '<!-- urlok = '.$urlok.' -->'."\n";
  313. print '<!-- urlko = '.$urlko.' -->'."\n";
  314. print "\n";
  315. print '<table id="dolpaymenttable" summary="Payment form" class="center">'."\n";
  316. // Show logo (search order: logo defined by PAYBOX_LOGO_suffix, then PAYBOX_LOGO, then small company logo, large company logo, theme logo, common logo)
  317. $width=0;
  318. // Define logo and logosmall
  319. $logosmall=$mysoc->logo_small;
  320. $logo=$mysoc->logo;
  321. $paramlogo='STRIPE_LOGO_'.$suffix;
  322. if (! empty($conf->global->$paramlogo)) $logosmall=$conf->global->$paramlogo;
  323. else if (! empty($conf->global->STRIPE_LOGO)) $logosmall=$conf->global->STRIPE_LOGO;
  324. //print '<!-- Show logo (logosmall='.$logosmall.' logo='.$logo.') -->'."\n";
  325. // Define urllogo
  326. $urllogo='';
  327. if (! empty($logosmall) && is_readable($conf->mycompany->dir_output.'/logos/thumbs/'.$logosmall))
  328. {
  329. $urllogo=DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode('thumbs/'.$logosmall);
  330. }
  331. elseif (! empty($logo) && is_readable($conf->mycompany->dir_output.'/logos/'.$logo))
  332. {
  333. $urllogo=DOL_URL_ROOT.'/viewimage.php?modulepart=mycompany&amp;file='.urlencode($logo);
  334. $width=96;
  335. }
  336. // Output html code for logo
  337. if ($urllogo)
  338. {
  339. print '<tr>';
  340. print '<td align="center"><img id="dolpaymentlogo" title="'.$title.'" src="'.$urllogo.'"';
  341. if ($width) print ' width="'.$width.'"';
  342. print '></td>';
  343. print '</tr>'."\n";
  344. }
  345. // Output introduction text
  346. $text='';
  347. if (! empty($conf->global->STRIPE_NEWFORM_TEXT))
  348. {
  349. $langs->load("members");
  350. if (preg_match('/^\((.*)\)$/',$conf->global->STRIPE_NEWFORM_TEXT,$reg)) $text.=$langs->trans($reg[1])."<br>\n";
  351. else $text.=$conf->global->STRIPE_NEWFORM_TEXT."<br>\n";
  352. $text='<tr><td align="center"><br>'.$text.'<br></td></tr>'."\n";
  353. }
  354. if (empty($text))
  355. {
  356. $text.='<tr><td class="textpublicpayment"><br><strong>'.$langs->trans("WelcomeOnPaymentPage").'</strong><br></td></tr>'."\n";
  357. $text.='<tr><td class="textpublicpayment"><br>'.$langs->trans("ThisScreenAllowsYouToPay",$creditor).'<br><br></td></tr>'."\n";
  358. }
  359. print $text;
  360. // Output payment summary form
  361. print '<tr><td align="center">';
  362. print '<table with="100%" id="tablepublicpayment">';
  363. print '<tr class="liste_total"><td align="left" colspan="2">'.$langs->trans("ThisIsInformationOnPayment").' :</td></tr>'."\n";
  364. $found=false;
  365. $error=0;
  366. $var=false;
  367. // Free payment
  368. if (! GETPOST("source"))
  369. {
  370. $found=true;
  371. $tag=GETPOST("tag");
  372. $fulltag=$tag;
  373. // Creditor
  374. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor");
  375. print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>';
  376. print '<input type="hidden" name="creditor" value="'.$creditor.'">';
  377. print '</td></tr>'."\n";
  378. // Amount
  379. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Amount");
  380. if (empty($amount)) print ' ('.$langs->trans("ToComplete").')';
  381. print '</td><td class="CTableRow'.($var?'1':'2').'">';
  382. if (empty($amount) || ! is_numeric($amount))
  383. {
  384. print '<input type="hidden" name="amount" value="'.GETPOST("amount",'int').'">';
  385. print '<input class="flat" size=8 type="text" name="newamount" value="'.GETPOST("newamount","int").'">';
  386. }
  387. else {
  388. print '<b>'.price($amount).'</b>';
  389. print '<input type="hidden" name="amount" value="'.$amount.'">';
  390. print '<input type="hidden" name="newamount" value="'.$amount.'">';
  391. }
  392. // Currency
  393. print ' <b>'.$langs->trans("Currency".$currency).'</b>';
  394. print '<input type="hidden" name="currency" value="'.$currency.'">';
  395. print '</td></tr>'."\n";
  396. // Tag
  397. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentCode");
  398. print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$fulltag.'</b>';
  399. print '<input type="hidden" name="tag" value="'.$tag.'">';
  400. print '<input type="hidden" name="fulltag" value="'.$fulltag.'">';
  401. print '</td></tr>'."\n";
  402. // We do not add fields shipToName, shipToStreet, shipToCity, shipToState, shipToCountryCode, shipToZip, shipToStreet2, phoneNum
  403. // as they don't exists (buyer is unknown, tag is free).
  404. }
  405. // Payment on customer order
  406. if (GETPOST("source") == 'order')
  407. {
  408. $found=true;
  409. $langs->load("orders");
  410. require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
  411. $order=new Commande($db);
  412. $result=$order->fetch('',$ref);
  413. if ($result < 0)
  414. {
  415. $mesg=$order->error;
  416. $error++;
  417. }
  418. else
  419. {
  420. $result=$order->fetch_thirdparty($order->socid);
  421. }
  422. if ($action != 'dopayment') // Do not change amount if we just click on first dopayment
  423. {
  424. $amount=$order->total_ttc;
  425. if (GETPOST("amount",'int')) $amount=GETPOST("amount",'int');
  426. $amount=price2num($amount);
  427. }
  428. $fulltag='ORD='.$order->ref.'.CUS='.$order->thirdparty->id;
  429. //$fulltag.='.NAM='.strtr($order->thirdparty->name,"-"," ");
  430. if (! empty($TAG)) { $tag=$TAG; $fulltag.='.TAG='.$TAG; }
  431. $fulltag=dol_string_unaccent($fulltag);
  432. // Creditor
  433. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor");
  434. print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>';
  435. print '<input type="hidden" name="creditor" value="'.$creditor.'">';
  436. print '</td></tr>'."\n";
  437. // Debitor
  438. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("ThirdParty");
  439. print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$order->thirdparty->name.'</b>';
  440. // Object
  441. $text='<b>'.$langs->trans("PaymentOrderRef",$order->ref).'</b>';
  442. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Designation");
  443. print '</td><td class="CTableRow'.($var?'1':'2').'">'.$text;
  444. print '<input type="hidden" name="source" value="'.GETPOST("source",'alpha').'">';
  445. print '<input type="hidden" name="ref" value="'.$order->ref.'">';
  446. print '</td></tr>'."\n";
  447. // Amount
  448. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Amount");
  449. if (empty($amount)) print ' ('.$langs->trans("ToComplete").')';
  450. print '</td><td class="CTableRow'.($var?'1':'2').'">';
  451. if (empty($amount) || ! is_numeric($amount))
  452. {
  453. print '<input type="hidden" name="amount" value="'.GETPOST("amount",'int').'">';
  454. print '<input class="flat" size=8 type="text" name="newamount" value="'.GETPOST("newamount","int").'">';
  455. }
  456. else {
  457. print '<b>'.price($amount).'</b>';
  458. print '<input type="hidden" name="amount" value="'.$amount.'">';
  459. print '<input type="hidden" name="newamount" value="'.$amount.'">';
  460. }
  461. // Currency
  462. print ' <b>'.$langs->trans("Currency".$currency).'</b>';
  463. print '<input type="hidden" name="currency" value="'.$currency.'">';
  464. print '</td></tr>'."\n";
  465. // Tag
  466. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentCode");
  467. print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$fulltag.'</b>';
  468. print '<input type="hidden" name="tag" value="'.$tag.'">';
  469. print '<input type="hidden" name="fulltag" value="'.$fulltag.'">';
  470. print '</td></tr>'."\n";
  471. // Shipping address
  472. $shipToName=$order->thirdparty->name;
  473. $shipToStreet=$order->thirdparty->address;
  474. $shipToCity=$order->thirdparty->town;
  475. $shipToState=$order->thirdparty->state_code;
  476. $shipToCountryCode=$order->thirdparty->country_code;
  477. $shipToZip=$order->thirdparty->zip;
  478. $shipToStreet2='';
  479. $phoneNum=$order->thirdparty->phone;
  480. if ($shipToName && $shipToStreet && $shipToCity && $shipToCountryCode && $shipToZip)
  481. {
  482. print '<input type="hidden" name="shipToName" value="'.$shipToName.'">'."\n";
  483. print '<input type="hidden" name="shipToStreet" value="'.$shipToStreet.'">'."\n";
  484. print '<input type="hidden" name="shipToCity" value="'.$shipToCity.'">'."\n";
  485. print '<input type="hidden" name="shipToState" value="'.$shipToState.'">'."\n";
  486. print '<input type="hidden" name="shipToCountryCode" value="'.$shipToCountryCode.'">'."\n";
  487. print '<input type="hidden" name="shipToZip" value="'.$shipToZip.'">'."\n";
  488. print '<input type="hidden" name="shipToStreet2" value="'.$shipToStreet2.'">'."\n";
  489. print '<input type="hidden" name="phoneNum" value="'.$phoneNum.'">'."\n";
  490. }
  491. else
  492. {
  493. print '<!-- Shipping address not complete, so we don t use it -->'."\n";
  494. }
  495. print '<input type="hidden" name="email" value="'.$order->thirdparty->email.'">'."\n";
  496. print '<input type="hidden" name="desc" value="'.$langs->trans("Order").' '.$order->ref.'">'."\n";
  497. }
  498. // Payment on customer invoice
  499. if (GETPOST("source") == 'invoice')
  500. {
  501. $found=true;
  502. $langs->load("bills");
  503. require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
  504. $invoice=new Facture($db);
  505. $result=$invoice->fetch('',$ref);
  506. if ($result < 0)
  507. {
  508. $mesg=$invoice->error;
  509. $error++;
  510. }
  511. else
  512. {
  513. $result=$invoice->fetch_thirdparty($invoice->socid);
  514. }
  515. if ($action != 'dopayment') // Do not change amount if we just click on first dopayment
  516. {
  517. $amount=price2num($invoice->total_ttc - $invoice->getSommePaiement());
  518. if (GETPOST("amount",'int')) $amount=GETPOST("amount",'int');
  519. $amount=price2num($amount);
  520. }
  521. $fulltag='INV='.$invoice->ref.'.CUS='.$invoice->thirdparty->id;
  522. //$fulltag.='.NAM='.strtr($invoice->thirdparty->name,"-"," ");
  523. if (! empty($TAG)) { $tag=$TAG; $fulltag.='.TAG='.$TAG; }
  524. $fulltag=dol_string_unaccent($fulltag);
  525. // Creditor
  526. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor");
  527. print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>';
  528. print '<input type="hidden" name="creditor" value="'.$creditor.'">';
  529. print '</td></tr>'."\n";
  530. // Debitor
  531. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("ThirdParty");
  532. print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$invoice->thirdparty->name.'</b>';
  533. // Object
  534. $text='<b>'.$langs->trans("PaymentInvoiceRef",$invoice->ref).'</b>';
  535. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Designation");
  536. print '</td><td class="CTableRow'.($var?'1':'2').'">'.$text;
  537. print '<input type="hidden" name="source" value="'.GETPOST("source",'alpha').'">';
  538. print '<input type="hidden" name="ref" value="'.$invoice->ref.'">';
  539. print '</td></tr>'."\n";
  540. // Amount
  541. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Amount");
  542. if (empty($amount)) print ' ('.$langs->trans("ToComplete").')';
  543. print '</td><td class="CTableRow'.($var?'1':'2').'">';
  544. if (empty($amount) || ! is_numeric($amount))
  545. {
  546. print '<input type="hidden" name="amount" value="'.GETPOST("amount",'int').'">';
  547. print '<input class="flat" size=8 type="text" name="newamount" value="'.GETPOST("newamount","int").'">';
  548. }
  549. else {
  550. print '<b>'.price($amount).'</b>';
  551. print '<input type="hidden" name="amount" value="'.$amount.'">';
  552. print '<input type="hidden" name="newamount" value="'.$amount.'">';
  553. }
  554. // Currency
  555. print ' <b>'.$langs->trans("Currency".$currency).'</b>';
  556. print '<input type="hidden" name="currency" value="'.$currency.'">';
  557. print '</td></tr>'."\n";
  558. // Tag
  559. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentCode");
  560. print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$fulltag.'</b>';
  561. print '<input type="hidden" name="tag" value="'.$tag.'">';
  562. print '<input type="hidden" name="fulltag" value="'.$fulltag.'">';
  563. print '</td></tr>'."\n";
  564. // Shipping address
  565. $shipToName=$invoice->thirdparty->name;
  566. $shipToStreet=$invoice->thirdparty->address;
  567. $shipToCity=$invoice->thirdparty->town;
  568. $shipToState=$invoice->thirdparty->state_code;
  569. $shipToCountryCode=$invoice->thirdparty->country_code;
  570. $shipToZip=$invoice->thirdparty->zip;
  571. $shipToStreet2='';
  572. $phoneNum=$invoice->thirdparty->phone;
  573. if ($shipToName && $shipToStreet && $shipToCity && $shipToCountryCode && $shipToZip)
  574. {
  575. print '<input type="hidden" name="shipToName" value="'.$shipToName.'">'."\n";
  576. print '<input type="hidden" name="shipToStreet" value="'.$shipToStreet.'">'."\n";
  577. print '<input type="hidden" name="shipToCity" value="'.$shipToCity.'">'."\n";
  578. print '<input type="hidden" name="shipToState" value="'.$shipToState.'">'."\n";
  579. print '<input type="hidden" name="shipToCountryCode" value="'.$shipToCountryCode.'">'."\n";
  580. print '<input type="hidden" name="shipToZip" value="'.$shipToZip.'">'."\n";
  581. print '<input type="hidden" name="shipToStreet2" value="'.$shipToStreet2.'">'."\n";
  582. print '<input type="hidden" name="phoneNum" value="'.$phoneNum.'">'."\n";
  583. }
  584. else
  585. {
  586. print '<!-- Shipping address not complete, so we don t use it -->'."\n";
  587. }
  588. print '<input type="hidden" name="email" value="'.$invoice->thirdparty->email.'">'."\n";
  589. print '<input type="hidden" name="desc" value="'.$langs->trans("Invoice").' '.$invoice->ref.'">'."\n";
  590. }
  591. // Payment on contract line
  592. if (GETPOST("source") == 'contractline')
  593. {
  594. $found=true;
  595. $langs->load("contracts");
  596. require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
  597. $contractline=new ContratLigne($db);
  598. $result=$contractline->fetch('',$ref);
  599. if ($result < 0)
  600. {
  601. $mesg=$contractline->error;
  602. $error++;
  603. }
  604. else
  605. {
  606. if ($contractline->fk_contrat > 0)
  607. {
  608. $contract=new Contrat($db);
  609. $result=$contract->fetch($contractline->fk_contrat);
  610. if ($result > 0)
  611. {
  612. $result=$contract->fetch_thirdparty($contract->socid);
  613. }
  614. else
  615. {
  616. $mesg=$contract->error;
  617. $error++;
  618. }
  619. }
  620. else
  621. {
  622. $mesg='ErrorRecordNotFound';
  623. $error++;
  624. }
  625. }
  626. if ($action != 'dopayment') // Do not change amount if we just click on first dopayment
  627. {
  628. $amount=$contractline->total_ttc;
  629. if ($contractline->fk_product)
  630. {
  631. $product=new Product($db);
  632. $result=$product->fetch($contractline->fk_product);
  633. // We define price for product (TODO Put this in a method in product class)
  634. if (! empty($conf->global->PRODUIT_MULTIPRICES))
  635. {
  636. $pu_ht = $product->multiprices[$contract->thirdparty->price_level];
  637. $pu_ttc = $product->multiprices_ttc[$contract->thirdparty->price_level];
  638. $price_base_type = $product->multiprices_base_type[$contract->thirdparty->price_level];
  639. }
  640. else
  641. {
  642. $pu_ht = $product->price;
  643. $pu_ttc = $product->price_ttc;
  644. $price_base_type = $product->price_base_type;
  645. }
  646. $amount=$pu_ttc;
  647. if (empty($amount))
  648. {
  649. dol_print_error('','ErrorNoPriceDefinedForThisProduct');
  650. exit;
  651. }
  652. }
  653. if (GETPOST("amount",'int')) $amount=GETPOST("amount",'int');
  654. $amount=price2num($amount);
  655. }
  656. $fulltag='COL='.$contractline->ref.'.CON='.$contract->ref.'.CUS='.$contract->thirdparty->id.'.DAT='.dol_print_date(dol_now(),'%Y%m%d%H%M');
  657. //$fulltag.='.NAM='.strtr($contract->thirdparty->name,"-"," ");
  658. if (! empty($TAG)) { $tag=$TAG; $fulltag.='.TAG='.$TAG; }
  659. $fulltag=dol_string_unaccent($fulltag);
  660. $qty=1;
  661. if (GETPOST('qty')) $qty=GETPOST('qty');
  662. // Creditor
  663. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor");
  664. print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>';
  665. print '<input type="hidden" name="creditor" value="'.$creditor.'">';
  666. print '</td></tr>'."\n";
  667. // Debitor
  668. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("ThirdParty");
  669. print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$contract->thirdparty->name.'</b>';
  670. // Object
  671. $text='<b>'.$langs->trans("PaymentRenewContractId",$contract->ref,$contractline->ref).'</b>';
  672. if ($contractline->fk_product)
  673. {
  674. $text.='<br>'.$product->ref.($product->label?' - '.$product->label:'');
  675. }
  676. if ($contractline->description) $text.='<br>'.dol_htmlentitiesbr($contractline->description);
  677. //if ($contractline->date_fin_validite) {
  678. // $text.='<br>'.$langs->trans("DateEndPlanned").': ';
  679. // $text.=dol_print_date($contractline->date_fin_validite);
  680. //}
  681. if ($contractline->date_fin_validite)
  682. {
  683. $text.='<br>'.$langs->trans("ExpiredSince").': '.dol_print_date($contractline->date_fin_validite);
  684. }
  685. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Designation");
  686. print '</td><td class="CTableRow'.($var?'1':'2').'">'.$text;
  687. print '<input type="hidden" name="source" value="'.GETPOST("source",'alpha').'">';
  688. print '<input type="hidden" name="ref" value="'.$contractline->ref.'">';
  689. print '</td></tr>'."\n";
  690. // Quantity
  691. $label=$langs->trans("Quantity");
  692. $qty=1;
  693. $duration='';
  694. if ($contractline->fk_product)
  695. {
  696. if ($product->isService() && $product->duration_value > 0)
  697. {
  698. $label=$langs->trans("Duration");
  699. // TODO Put this in a global method
  700. if ($product->duration_value > 1)
  701. {
  702. $dur=array("h"=>$langs->trans("Hours"),"d"=>$langs->trans("DurationDays"),"w"=>$langs->trans("DurationWeeks"),"m"=>$langs->trans("DurationMonths"),"y"=>$langs->trans("DurationYears"));
  703. }
  704. else
  705. {
  706. $dur=array("h"=>$langs->trans("Hour"),"d"=>$langs->trans("DurationDay"),"w"=>$langs->trans("DurationWeek"),"m"=>$langs->trans("DurationMonth"),"y"=>$langs->trans("DurationYear"));
  707. }
  708. $duration=$product->duration_value.' '.$dur[$product->duration_unit];
  709. }
  710. }
  711. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$label.'</td>';
  712. print '<td class="CTableRow'.($var?'1':'2').'"><b>'.($duration?$duration:$qty).'</b>';
  713. print '<input type="hidden" name="newqty" value="'.dol_escape_htmltag($qty).'">';
  714. print '</b></td></tr>'."\n";
  715. // Amount
  716. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Amount");
  717. if (empty($amount)) print ' ('.$langs->trans("ToComplete").')';
  718. print '</td><td class="CTableRow'.($var?'1':'2').'">';
  719. if (empty($amount) || ! is_numeric($amount))
  720. {
  721. print '<input type="hidden" name="amount" value="'.GETPOST("amount",'int').'">';
  722. print '<input class="flat" size=8 type="text" name="newamount" value="'.GETPOST("newamount","int").'">';
  723. }
  724. else {
  725. print '<b>'.price($amount).'</b>';
  726. print '<input type="hidden" name="amount" value="'.$amount.'">';
  727. print '<input type="hidden" name="newamount" value="'.$amount.'">';
  728. }
  729. // Currency
  730. print ' <b>'.$langs->trans("Currency".$currency).'</b>';
  731. print '<input type="hidden" name="currency" value="'.$currency.'">';
  732. print '</td></tr>'."\n";
  733. // Tag
  734. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentCode");
  735. print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$fulltag.'</b>';
  736. print '<input type="hidden" name="tag" value="'.$tag.'">';
  737. print '<input type="hidden" name="fulltag" value="'.$fulltag.'">';
  738. print '</td></tr>'."\n";
  739. // Shipping address
  740. $shipToName=$contract->thirdparty->name;
  741. $shipToStreet=$contract->thirdparty->address;
  742. $shipToCity=$contract->thirdparty->town;
  743. $shipToState=$contract->thirdparty->state_code;
  744. $shipToCountryCode=$contract->thirdparty->country_code;
  745. $shipToZip=$contract->thirdparty->zip;
  746. $shipToStreet2='';
  747. $phoneNum=$contract->thirdparty->phone;
  748. if ($shipToName && $shipToStreet && $shipToCity && $shipToCountryCode && $shipToZip)
  749. {
  750. print '<input type="hidden" name="shipToName" value="'.$shipToName.'">'."\n";
  751. print '<input type="hidden" name="shipToStreet" value="'.$shipToStreet.'">'."\n";
  752. print '<input type="hidden" name="shipToCity" value="'.$shipToCity.'">'."\n";
  753. print '<input type="hidden" name="shipToState" value="'.$shipToState.'">'."\n";
  754. print '<input type="hidden" name="shipToCountryCode" value="'.$shipToCountryCode.'">'."\n";
  755. print '<input type="hidden" name="shipToZip" value="'.$shipToZip.'">'."\n";
  756. print '<input type="hidden" name="shipToStreet2" value="'.$shipToStreet2.'">'."\n";
  757. print '<input type="hidden" name="phoneNum" value="'.$phoneNum.'">'."\n";
  758. }
  759. else
  760. {
  761. print '<!-- Shipping address not complete, so we don t use it -->'."\n";
  762. }
  763. print '<input type="hidden" name="email" value="'.$contract->thirdparty->email.'">'."\n";
  764. print '<input type="hidden" name="desc" value="'.$langs->trans("Contract").' '.$contract->ref.'">'."\n";
  765. }
  766. // Payment on member subscription
  767. if (GETPOST("source") == 'membersubscription')
  768. {
  769. $found=true;
  770. $langs->load("members");
  771. require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php';
  772. require_once DOL_DOCUMENT_ROOT.'/adherents/class/subscription.class.php';
  773. $member=new Adherent($db);
  774. $result=$member->fetch('',$ref);
  775. if ($result < 0)
  776. {
  777. $mesg=$member->error;
  778. $error++;
  779. }
  780. else
  781. {
  782. $subscription=new Subscription($db);
  783. }
  784. if ($action != 'dopayment') // Do not change amount if we just click on first dopayment
  785. {
  786. $amount=$subscription->total_ttc;
  787. if (GETPOST("amount",'int')) $amount=GETPOST("amount",'int');
  788. $amount=price2num($amount);
  789. }
  790. $fulltag='MEM='.$member->id.'.DAT='.dol_print_date(dol_now(),'%Y%m%d%H%M');
  791. if (! empty($TAG)) { $tag=$TAG; $fulltag.='.TAG='.$TAG; }
  792. $fulltag=dol_string_unaccent($fulltag);
  793. // Creditor
  794. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Creditor");
  795. print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$creditor.'</b>';
  796. print '<input type="hidden" name="creditor" value="'.$creditor.'">';
  797. print '</td></tr>'."\n";
  798. // Debitor
  799. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Member");
  800. print '</td><td class="CTableRow'.($var?'1':'2').'"><b>';
  801. if ($member->morphy == 'mor' && ! empty($member->societe)) print $member->societe;
  802. else print $member->getFullName($langs);
  803. print '</b>';
  804. // Object
  805. $text='<b>'.$langs->trans("PaymentSubscription").'</b>';
  806. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Designation");
  807. print '</td><td class="CTableRow'.($var?'1':'2').'">'.$text;
  808. print '<input type="hidden" name="source" value="'.GETPOST("source",'alpha').'">';
  809. print '<input type="hidden" name="ref" value="'.$member->ref.'">';
  810. print '</td></tr>'."\n";
  811. if ($member->last_subscription_date || $member->last_subscription_amount)
  812. {
  813. // Last subscription date
  814. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("LastSubscriptionDate");
  815. print '</td><td class="CTableRow'.($var?'1':'2').'">'.dol_print_date($member->last_subscription_date,'day');
  816. print '</td></tr>'."\n";
  817. // Last subscription amount
  818. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("LastSubscriptionAmount");
  819. print '</td><td class="CTableRow'.($var?'1':'2').'">'.price($member->last_subscription_amount);
  820. print '</td></tr>'."\n";
  821. if (empty($amount) && ! GETPOST('newamount')) $_GET['newamount']=$member->last_subscription_amount;
  822. }
  823. // Amount
  824. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("Amount");
  825. if (empty($amount))
  826. {
  827. print ' ('.$langs->trans("ToComplete");
  828. if (! empty($conf->global->MEMBER_EXT_URL_SUBSCRIPTION_INFO)) print ' - <a href="'.$conf->global->MEMBER_EXT_URL_SUBSCRIPTION_INFO.'" rel="external" target="_blank">'.$langs->trans("SeeHere").'</a>';
  829. print ')';
  830. }
  831. print '</td><td class="CTableRow'.($var?'1':'2').'">';
  832. if (empty($amount) || ! is_numeric($amount))
  833. {
  834. $valtoshow=GETPOST("newamount",'int');
  835. if (! empty($conf->global->MEMBER_MIN_AMOUNT) && $valtoshow) $valtoshow=max($conf->global->MEMBER_MIN_AMOUNT,$valtoshow);
  836. print '<input type="hidden" name="amount" value="'.GETPOST("amount",'int').'">';
  837. print '<input class="flat" size="8" type="text" name="newamount" value="'.$valtoshow.'">';
  838. }
  839. else {
  840. $valtoshow=$amount;
  841. if (! empty($conf->global->MEMBER_MIN_AMOUNT) && $valtoshow) $valtoshow=max($conf->global->MEMBER_MIN_AMOUNT,$valtoshow);
  842. print '<b>'.price($valtoshow).'</b>';
  843. print '<input type="hidden" name="amount" value="'.$valtoshow.'">';
  844. print '<input type="hidden" name="newamount" value="'.$valtoshow.'">';
  845. }
  846. // Currency
  847. print ' <b>'.$langs->trans("Currency".$currency).'</b>';
  848. print '<input type="hidden" name="currency" value="'.$currency.'">';
  849. print '</td></tr>'."\n";
  850. // Tag
  851. print '<tr class="CTableRow'.($var?'1':'2').'"><td class="CTableRow'.($var?'1':'2').'">'.$langs->trans("PaymentCode");
  852. print '</td><td class="CTableRow'.($var?'1':'2').'"><b>'.$fulltag.'</b>';
  853. print '<input type="hidden" name="tag" value="'.$tag.'">';
  854. print '<input type="hidden" name="fulltag" value="'.$fulltag.'">';
  855. print '</td></tr>'."\n";
  856. // Shipping address
  857. $shipToName=$member->getFullName($langs);
  858. $shipToStreet=$member->address;
  859. $shipToCity=$member->town;
  860. $shipToState=$member->state_code;
  861. $shipToCountryCode=$member->country_code;
  862. $shipToZip=$member->zip;
  863. $shipToStreet2='';
  864. $phoneNum=$member->phone;
  865. if ($shipToName && $shipToStreet && $shipToCity && $shipToCountryCode && $shipToZip)
  866. {
  867. print '<input type="hidden" name="shipToName" value="'.$shipToName.'">'."\n";
  868. print '<input type="hidden" name="shipToStreet" value="'.$shipToStreet.'">'."\n";
  869. print '<input type="hidden" name="shipToCity" value="'.$shipToCity.'">'."\n";
  870. print '<input type="hidden" name="shipToState" value="'.$shipToState.'">'."\n";
  871. print '<input type="hidden" name="shipToCountryCode" value="'.$shipToCountryCode.'">'."\n";
  872. print '<input type="hidden" name="shipToZip" value="'.$shipToZip.'">'."\n";
  873. print '<input type="hidden" name="shipToStreet2" value="'.$shipToStreet2.'">'."\n";
  874. print '<input type="hidden" name="phoneNum" value="'.$phoneNum.'">'."\n";
  875. }
  876. else
  877. {
  878. print '<!-- Shipping address not complete, so we don t use it -->'."\n";
  879. }
  880. print '<input type="hidden" name="email" value="'.$member->email.'">'."\n";
  881. print '<input type="hidden" name="desc" value="'.$langs->trans("PaymentSubscription").'">'."\n";
  882. }
  883. if (! $found && ! $mesg) $mesg=$langs->trans("ErrorBadParameters");
  884. if ($mesg) print '<tr><td align="center" colspan="2"><br><div class="warning">'.$mesg.'</div></td></tr>'."\n";
  885. print '</table>'."\n";
  886. print "\n";
  887. if ($action != 'dopayment')
  888. {
  889. if ($found && ! $error) // We are in a management option and no error
  890. {
  891. print '<br><input class="button" type="submit" name="dopayment_stripe" value="'.$langs->trans("StripeDoPayment").'">';
  892. }
  893. else
  894. {
  895. dol_print_error_email('ERRORNEWPAYMENTSTRIPE');
  896. }
  897. }
  898. print '</td></tr>'."\n";
  899. print '</table>'."\n";
  900. print '</form>'."\n";
  901. print '</div>'."\n";
  902. print '<br>';
  903. // Add more content on page for some services
  904. if (preg_match('/^dopayment/',$action))
  905. {
  906. // Simple checkout
  907. /*
  908. print '<script src="https://checkout.stripe.com/checkout.js"
  909. class="stripe-button"
  910. data-key="'.$stripe['publishable_key'].'"
  911. data-amount="'.$ttc.'"
  912. data-currency="'.$conf->currency.'"
  913. data-description="'.$ref.'">
  914. </script>';
  915. */
  916. // Personalized checkout
  917. print '<style>
  918. /**
  919. * The CSS shown here will not be introduced in the Quickstart guide, but shows
  920. * how you can use CSS to style your Element s container.
  921. */
  922. .StripeElement {
  923. background-color: white;
  924. padding: 8px 12px;
  925. border-radius: 4px;
  926. border: 1px solid transparent;
  927. box-shadow: 0 1px 3px 0 #e6ebf1;
  928. -webkit-transition: box-shadow 150ms ease;
  929. transition: box-shadow 150ms ease;
  930. }
  931. .StripeElement--focus {
  932. box-shadow: 0 1px 3px 0 #cfd7df;
  933. }
  934. .StripeElement--invalid {
  935. border-color: #fa755a;
  936. }
  937. .StripeElement--webkit-autofill {
  938. background-color: #fefde5 !important;
  939. }
  940. </style>';
  941. print '
  942. <br>
  943. <form action="'.$_SERVER['REQUEST_URI'].'" method="POST" id="payment-form">';
  944. print '<input type="hidden" name="token" value="'.$_SESSION['newtoken'].'">'."\n";
  945. print '<input type="hidden" name="dopayment_stripe" value="1">'."\n";
  946. print '<input type="hidden" name="action" value="charge">'."\n";
  947. print '<input type="hidden" name="tag" value="'.$TAG.'">'."\n";
  948. print '<input type="hidden" name="source" value="'.$SOURCE.'">'."\n";
  949. print '<input type="hidden" name="ref" value="'.$REF.'">'."\n";
  950. print '<input type="hidden" name="fulltag" value="'.$FULLTAG.'">'."\n";
  951. print '<input type="hidden" name="suffix" value="'.$suffix.'">'."\n";
  952. print '<input type="hidden" name="securekey" value="'.$SECUREKEY.'">'."\n";
  953. print '<input type="hidden" name="entity" value="'.$entity.'" />';
  954. print '<input type="hidden" name="amount" value="'.$amount.'">'."\n";
  955. print '<input type="hidden" name="currency" value="'.$currency.'">'."\n";
  956. print '
  957. <table id="dolpaymenttable" summary="Payment form" class="center">
  958. <tbody><tr><td class="textpublicpayment">
  959. <div class="form-row left">
  960. <label for="card-element">
  961. Credit or debit card
  962. </label>
  963. <div id="card-element">
  964. <!-- a Stripe Element will be inserted here. -->
  965. </div>
  966. <!-- Used to display form errors -->
  967. <div id="card-errors" role="alert"></div>
  968. </div>
  969. <br>
  970. <button class="button" id="buttontopay">'.$langs->trans("ToPay").'</button>
  971. <img id="hourglasstopay" class="hidden" src="'.DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/working.gif'.'">
  972. </td></tr></tbody></table>
  973. </form>
  974. <script src="https://js.stripe.com/v2/"></script>
  975. <script src="https://js.stripe.com/v3/"></script>
  976. <script type="text/javascript" language="javascript">';
  977. ?>
  978. // Create a Stripe client
  979. var stripe = Stripe('<?php echo $stripe['publishable_key']; ?>');
  980. // Create an instance of Elements
  981. var elements = stripe.elements();
  982. // Custom styling can be passed to options when creating an Element.
  983. // (Note that this demo uses a wider set of styles than the guide below.)
  984. var style = {
  985. base: {
  986. color: '#32325d',
  987. lineHeight: '24px',
  988. fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
  989. fontSmoothing: 'antialiased',
  990. fontSize: '16px',
  991. '::placeholder': {
  992. color: '#aab7c4'
  993. }
  994. },
  995. invalid: {
  996. color: '#fa755a',
  997. iconColor: '#fa755a'
  998. }
  999. };
  1000. // Create an instance of the card Element
  1001. var card = elements.create('card', {style: style});
  1002. // Add an instance of the card Element into the `card-element` <div>
  1003. card.mount('#card-element');
  1004. // Handle real-time validation errors from the card Element.
  1005. card.addEventListener('change', function(event) {
  1006. var displayError = document.getElementById('card-errors');
  1007. if (event.error) {
  1008. displayError.textContent = event.error.message;
  1009. } else {
  1010. displayError.textContent = '';
  1011. }
  1012. });
  1013. // Handle form submission
  1014. var form = document.getElementById('payment-form');
  1015. console.log(form);
  1016. form.addEventListener('submit', function(event) {
  1017. event.preventDefault();
  1018. stripe.createToken(card).then(function(result) {
  1019. if (result.error) {
  1020. // Inform the user if there was an error
  1021. var errorElement = document.getElementById('card-errors');
  1022. errorElement.textContent = result.error.message;
  1023. } else {
  1024. // Send the token to your server
  1025. stripeTokenHandler(result.token);
  1026. }
  1027. });
  1028. });
  1029. function stripeTokenHandler(token) {
  1030. // Insert the token ID into the form so it gets submitted to the server
  1031. var form = document.getElementById('payment-form');
  1032. var hiddenInput = document.createElement('input');
  1033. hiddenInput.setAttribute('type', 'hidden');
  1034. hiddenInput.setAttribute('name', 'stripeToken');
  1035. hiddenInput.setAttribute('value', token.id);
  1036. form.appendChild(hiddenInput);
  1037. // Submit the form
  1038. jQuery('#buttontopay').hide();
  1039. jQuery('#hourglasstopay').show();
  1040. console.log("submit");
  1041. form.submit();
  1042. }
  1043. <?php
  1044. print '</script>';
  1045. }
  1046. htmlPrintOnlinePaymentFooter($mysoc,$langs);
  1047. llxFooter('', 'public');
  1048. $db->close();