paypal.lib.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617
  1. <?php
  2. /* Copyright (C) 2008-2012 Laurent Destailleur <eldy@users.sourceforge.net>
  3. * Copyright (C) 2011-2012 Regis Houssin <regis.houssin@inodbox.com>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. /**
  19. * \file htdocs/paypal/lib/paypal.lib.php
  20. * \ingroup paypal
  21. * \brief Library for common paypal functions
  22. */
  23. require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php';
  24. /**
  25. * Define head array for tabs of paypal tools setup pages
  26. *
  27. * @return Array of head
  28. */
  29. function paypaladmin_prepare_head()
  30. {
  31. global $langs, $conf;
  32. $h = 0;
  33. $head = array();
  34. $head[$h][0] = DOL_URL_ROOT."/paypal/admin/paypal.php";
  35. $head[$h][1] = $langs->trans("PayPal");
  36. $head[$h][2] = 'paypalaccount';
  37. $h++;
  38. $object = new stdClass();
  39. // Show more tabs from modules
  40. // Entries must be declared in modules descriptor with line
  41. // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab
  42. // $this->tabs = array('entity:-tabname); to remove a tab
  43. complete_head_from_modules($conf, $langs, $object, $head, $h, 'paypaladmin');
  44. complete_head_from_modules($conf, $langs, $object, $head, $h, 'paypaladmin', 'remove');
  45. return $head;
  46. }
  47. /**
  48. * Send redirect to paypal to browser
  49. *
  50. * @param float $paymentAmount Amount
  51. * @param string $currencyCodeType Currency code
  52. * @param string $paymentType Payment type
  53. * @param string $returnURL Url to use if payment is OK
  54. * @param string $cancelURL Url to use if payment is KO
  55. * @param string $tag Full tag
  56. * @return string No return (a redirect is done) if OK, or Error message if KO
  57. */
  58. function print_paypal_redirect($paymentAmount, $currencyCodeType, $paymentType, $returnURL, $cancelURL, $tag)
  59. {
  60. //declaring of global variables
  61. global $conf, $langs;
  62. global $API_Endpoint, $API_Url, $API_version, $USE_PROXY, $PROXY_HOST, $PROXY_PORT;
  63. global $PAYPAL_API_USER, $PAYPAL_API_PASSWORD, $PAYPAL_API_SIGNATURE;
  64. global $shipToName, $shipToStreet, $shipToCity, $shipToState, $shipToCountryCode, $shipToZip, $shipToStreet2, $phoneNum;
  65. global $email, $desc;
  66. //'------------------------------------
  67. //' Calls the SetExpressCheckout API call
  68. //'
  69. //'-------------------------------------------------
  70. if (!getDolGlobalString('PAYPAL_API_INTEGRAL_OR_PAYPALONLY')) {
  71. $conf->global->PAYPAL_API_INTEGRAL_OR_PAYPALONLY = 'integral';
  72. }
  73. $solutionType = 'Sole';
  74. $landingPage = 'Billing';
  75. // For payment with Paypal only
  76. if (getDolGlobalString('PAYPAL_API_INTEGRAL_OR_PAYPALONLY') == 'paypalonly') {
  77. $solutionType = 'Mark';
  78. $landingPage = 'Login';
  79. }
  80. // For payment with Credit card or Paypal
  81. if (getDolGlobalString('PAYPAL_API_INTEGRAL_OR_PAYPALONLY') == 'integral') {
  82. $solutionType = 'Sole';
  83. $landingPage = 'Billing';
  84. }
  85. // For payment with Credit card
  86. if (getDolGlobalString('PAYPAL_API_INTEGRAL_OR_PAYPALONLY') == 'cconly') {
  87. $solutionType = 'Sole';
  88. $landingPage = 'Billing';
  89. }
  90. dol_syslog("print_paypal_redirect expresscheckout redirect with callSetExpressCheckout $paymentAmount, $currencyCodeType, $paymentType, $returnURL, $cancelURL, $tag, $solutionType, $landingPage, $shipToName, $shipToStreet, $shipToCity, $shipToState, $shipToCountryCode, $shipToZip, $shipToStreet2, $phoneNum");
  91. $resArray = callSetExpressCheckout(
  92. $paymentAmount,
  93. $currencyCodeType,
  94. $paymentType,
  95. $returnURL,
  96. $cancelURL,
  97. $tag,
  98. $solutionType,
  99. $landingPage,
  100. $shipToName,
  101. $shipToStreet,
  102. $shipToCity,
  103. $shipToState,
  104. $shipToCountryCode,
  105. $shipToZip,
  106. $shipToStreet2,
  107. $phoneNum,
  108. $email,
  109. $desc
  110. );
  111. dol_syslog("print_paypal_redirect resArray=".var_export($resArray, true), LOG_DEBUG);
  112. $ack = strtoupper($resArray["ACK"]);
  113. if ($ack == "SUCCESS" || $ack == "SUCCESSWITHWARNING") {
  114. $token = $resArray["TOKEN"];
  115. // Redirect to paypal.com here
  116. $payPalURL = $API_Url.$token;
  117. dol_syslog("Redirect to ".$payPalURL, LOG_INFO);
  118. header("Location: ".$payPalURL);
  119. exit;
  120. } else {
  121. //Display a user friendly Error on the page using any of the following error information returned by PayPal
  122. $ErrorCode = urldecode($resArray["L_ERRORCODE0"]);
  123. $ErrorShortMsg = urldecode($resArray["L_SHORTMESSAGE0"]);
  124. $ErrorLongMsg = urldecode($resArray["L_LONGMESSAGE0"]);
  125. $ErrorSeverityCode = urldecode($resArray["L_SEVERITYCODE0"]);
  126. if ($ErrorCode == 10729) {
  127. $mesg = "PayPal can't accept payments for this thirdparty. An address is defined but is not complete (missing State).<br>Ask system administrator to fix address or to setup Paypal module to accept payments even on not complete addresses (remove option PAYPAL_REQUIRE_VALID_SHIPPING_ADDRESS).<br>\n";
  128. } else {
  129. $mesg = $langs->trans('SetExpressCheckoutAPICallFailed')."<br>\n";
  130. $mesg .= $langs->trans('DetailedErrorMessage').": ".$ErrorLongMsg."<br>\n";
  131. $mesg .= $langs->trans('ShortErrorMessage').": ".$ErrorShortMsg."<br>\n";
  132. $mesg .= $langs->trans('ErrorCode').": ".$ErrorCode."<br>\n";
  133. $mesg .= $langs->trans('ErrorSeverityCode').": ".$ErrorSeverityCode."<br>\n";
  134. }
  135. return $mesg;
  136. }
  137. }
  138. /**
  139. *-------------------------------------------------------------------------------------------------------------------------------------------
  140. * Purpose: Prepares the parameters for the SetExpressCheckout API Call.
  141. * Inputs:
  142. * paymentAmount: Total value of the shopping cart
  143. * currencyCodeType: Currency code value the PayPal API
  144. * paymentType: paymentType has to be one of the following values: Sale or Order or Authorization
  145. * returnURL: the page where buyers return to after they are done with the payment review on PayPal
  146. * cancelURL: the page where buyers return to when they cancel the payment review on PayPal
  147. * shipToName: the Ship to name entered on the merchant's site
  148. * shipToStreet: the Ship to Street entered on the merchant's site
  149. * shipToCity: the Ship to City entered on the merchant's site
  150. * shipToState: the Ship to State entered on the merchant's site
  151. * shipToCountryCode: the Code for Ship to Country entered on the merchant's site
  152. * shipToZip: the Ship to ZipCode entered on the merchant's site
  153. * shipToStreet2: the Ship to Street2 entered on the merchant's site
  154. * phoneNum: the phoneNum entered on the merchant's site
  155. * email: the buyer email
  156. * desc: Product description
  157. * See https://developer.paypal.com/docs/classic/api/merchant/SetExpressCheckout_API_Operation_NVP/
  158. *
  159. * @param double $paymentAmount Payment amount
  160. * @param string $currencyCodeType Currency
  161. * @param string $paymentType Payment type
  162. * @param string $returnURL Return Url
  163. * @param string $cancelURL Cancel Url
  164. * @param string $tag Full tag
  165. * @param string $solutionType Type ('Mark' or 'Sole')
  166. * @param string $landingPage Landing page ('Login' or 'Billing')
  167. * @param string $shipToName Ship to name
  168. * @param string $shipToStreet Ship to street
  169. * @param string $shipToCity Ship to city
  170. * @param string $shipToState Ship to state
  171. * @param string $shipToCountryCode Ship to country code
  172. * @param string $shipToZip Ship to zip
  173. * @param string $shipToStreet2 Ship to street2
  174. * @param string $phoneNum Phone
  175. * @param string $email Email
  176. * @param string $desc Description
  177. * @return array Array
  178. */
  179. function callSetExpressCheckout($paymentAmount, $currencyCodeType, $paymentType, $returnURL, $cancelURL, $tag, $solutionType, $landingPage, $shipToName, $shipToStreet, $shipToCity, $shipToState, $shipToCountryCode, $shipToZip, $shipToStreet2, $phoneNum, $email = '', $desc = '')
  180. {
  181. //------------------------------------------------------------------------------------------------------------------------------------
  182. // Construct the parameter string that describes the SetExpressCheckout API call in the shortcut implementation
  183. //declaring of global variables
  184. global $conf, $langs, $mysoc;
  185. global $API_Endpoint, $API_Url, $API_version, $USE_PROXY, $PROXY_HOST, $PROXY_PORT;
  186. global $PAYPAL_API_USER, $PAYPAL_API_PASSWORD, $PAYPAL_API_SIGNATURE;
  187. $nvpstr = '';
  188. //$nvpstr = $nvpstr . "&VERSION=".$API_version; // Already added by hash_call
  189. $nvpstr = $nvpstr."&RETURNURL=".urlencode($returnURL);
  190. $nvpstr = $nvpstr."&CANCELURL=".urlencode($cancelURL);
  191. if (getDolGlobalString('PAYPAL_ALLOW_NOTES')) {
  192. $nvpstr = $nvpstr."&ALLOWNOTE=0";
  193. }
  194. if (!getDolGlobalString('PAYPAL_REQUIRE_VALID_SHIPPING_ADDRESS')) {
  195. $nvpstr = $nvpstr."&NOSHIPPING=1"; // An empty or not complete shipping address will be accepted
  196. } else {
  197. $nvpstr = $nvpstr."&NOSHIPPING=0"; // A valid shipping address is required (full required fields mandatory)
  198. }
  199. $nvpstr = $nvpstr."&SOLUTIONTYPE=".urlencode($solutionType);
  200. $nvpstr = $nvpstr."&LANDINGPAGE=".urlencode($landingPage);
  201. if (getDolGlobalString('PAYPAL_CUSTOMER_SERVICE_NUMBER')) {
  202. $nvpstr = $nvpstr."&CUSTOMERSERVICENUMBER=".urlencode($conf->global->PAYPAL_CUSTOMER_SERVICE_NUMBER); // Hotline phone number
  203. }
  204. $paypalprefix = 'PAYMENTREQUEST_0_';
  205. //$paypalprefix = '';
  206. if (!empty($paypalprefix) && $paymentType == 'Sole') {
  207. $paymentType = 'Sale';
  208. }
  209. $nvpstr = $nvpstr."&AMT=".urlencode($paymentAmount); // Total for all elements
  210. $nvpstr = $nvpstr."&".$paypalprefix."INVNUM=".urlencode($tag);
  211. $nvpstr = $nvpstr."&".$paypalprefix."AMT=".urlencode($paymentAmount); // AMT deprecated by paypal -> PAYMENTREQUEST_n_AMT
  212. $nvpstr = $nvpstr."&".$paypalprefix."ITEMAMT=".urlencode($paymentAmount); // AMT deprecated by paypal -> PAYMENTREQUEST_n_AMT
  213. $nvpstr = $nvpstr."&".$paypalprefix."PAYMENTACTION=".urlencode($paymentType); // PAYMENTACTION deprecated by paypal -> PAYMENTREQUEST_n_PAYMENTACTION
  214. $nvpstr = $nvpstr."&".$paypalprefix."CURRENCYCODE=".urlencode($currencyCodeType); // CURRENCYCODE deprecated by paypal -> PAYMENTREQUEST_n_CURRENCYCODE
  215. $nvpstr = $nvpstr."&".$paypalprefix."L_PAYMENTREQUEST_0_QTY0=1";
  216. $nvpstr = $nvpstr."&".$paypalprefix."L_PAYMENTREQUEST_0_AMT0=".urlencode($paymentAmount);
  217. $nvpstr = $nvpstr."&".$paypalprefix."L_PAYMENTREQUEST_0_NAME0=".urlencode($desc);
  218. $nvpstr = $nvpstr."&".$paypalprefix."L_PAYMENTREQUEST_0_NUMBER0=0";
  219. $nvpstr = $nvpstr."&".$paypalprefix."SHIPTONAME=".urlencode($shipToName); // SHIPTONAME deprecated by paypal -> PAYMENTREQUEST_n_SHIPTONAME
  220. $nvpstr = $nvpstr."&".$paypalprefix."SHIPTOSTREET=".urlencode($shipToStreet); //
  221. $nvpstr = $nvpstr."&".$paypalprefix."SHIPTOSTREET2=".urlencode($shipToStreet2);
  222. $nvpstr = $nvpstr."&".$paypalprefix."SHIPTOCITY=".urlencode($shipToCity);
  223. $nvpstr = $nvpstr."&".$paypalprefix."SHIPTOSTATE=".urlencode($shipToState);
  224. $nvpstr = $nvpstr."&".$paypalprefix."SHIPTOCOUNTRYCODE=".urlencode($shipToCountryCode);
  225. $nvpstr = $nvpstr."&".$paypalprefix."SHIPTOZIP=".urlencode($shipToZip);
  226. $nvpstr = $nvpstr."&".$paypalprefix."PHONENUM=".urlencode($phoneNum);
  227. if (!empty($email)) {
  228. $nvpstr = $nvpstr."&".$paypalprefix."EMAIL=".urlencode($email); // EMAIL deprecated by paypal -> PAYMENTREQUEST_n_EMAIL
  229. }
  230. if (!empty($desc)) {
  231. $nvpstr = $nvpstr."&".$paypalprefix."DESC=".urlencode($desc); // DESC deprecated by paypal -> PAYMENTREQUEST_n_DESC
  232. }
  233. if (getDolGlobalString('PAYPAL_LOGOIMG') && $mysoc->logo) {
  234. global $dolibarr_main_url_root;
  235. // Define $urlwithroot
  236. $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root));
  237. $urlwithroot = $urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
  238. //$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
  239. $urllogo = $urlwithroot."/viewimage.php?modulepart=mycompany&file=".urlencode('logos/'.$mysoc->logo);
  240. $nvpstr = $nvpstr."&LOGOIMG=".urlencode($urllogo);
  241. }
  242. if (getDolGlobalString('PAYPAL_BRANDNAME')) {
  243. $nvpstr = $nvpstr."&BRANDNAME=".urlencode($conf->global->PAYPAL_BRANDNAME); // BRANDNAME
  244. }
  245. if (getDolGlobalString('PAYPAL_NOTETOBUYER')) {
  246. $nvpstr = $nvpstr."&NOTETOBUYER=".urlencode($conf->global->PAYPAL_NOTETOBUYER); // PAYPAL_NOTETOBUYER
  247. }
  248. $_SESSION["FinalPaymentAmt"] = $paymentAmount;
  249. $_SESSION["currencyCodeType"] = $currencyCodeType;
  250. $_SESSION["PaymentType"] = $paymentType; // 'Mark', 'Sole'
  251. $_SESSION['ipaddress'] = getUserRemoteIP(); // Payer ip
  252. //'---------------------------------------------------------------------------------------------------------------
  253. //' Make the API call to PayPal
  254. //' If the API call succeded, then redirect the buyer to PayPal to begin to authorize payment.
  255. //' If an error occured, show the resulting errors
  256. //'---------------------------------------------------------------------------------------------------------------
  257. $resArray = hash_call("SetExpressCheckout", $nvpstr);
  258. $ack = strtoupper($resArray["ACK"]);
  259. if ($ack == "SUCCESS" || $ack == "SUCCESSWITHWARNING") {
  260. $token = urldecode($resArray["TOKEN"]);
  261. $_SESSION['TOKEN'] = $token;
  262. }
  263. return $resArray;
  264. }
  265. /**
  266. * Prepares the parameters for the GetExpressCheckoutDetails API Call.
  267. *
  268. * @param string $token Token
  269. * @return array The NVP Collection object of the GetExpressCheckoutDetails Call Response.
  270. */
  271. function getDetails($token)
  272. {
  273. //'--------------------------------------------------------------
  274. //' At this point, the buyer has completed authorizing the payment
  275. //' at PayPal. The function will call PayPal to obtain the details
  276. //' of the authorization, incuding any shipping information of the
  277. //' buyer. Remember, the authorization is not a completed transaction
  278. //' at this state - the buyer still needs an additional step to finalize
  279. //' the transaction
  280. //'--------------------------------------------------------------
  281. //declaring of global variables
  282. global $conf, $langs;
  283. global $API_Endpoint, $API_Url, $API_version, $USE_PROXY, $PROXY_HOST, $PROXY_PORT;
  284. global $PAYPAL_API_USER, $PAYPAL_API_PASSWORD, $PAYPAL_API_SIGNATURE;
  285. //'---------------------------------------------------------------------------
  286. //' Build a second API request to PayPal, using the token as the
  287. //' ID to get the details on the payment authorization
  288. //'---------------------------------------------------------------------------
  289. $nvpstr = "&TOKEN=".$token;
  290. //'---------------------------------------------------------------------------
  291. //' Make the API call and store the results in an array.
  292. //' If the call was a success, show the authorization details, and provide
  293. //' an action to complete the payment.
  294. //' If failed, show the error
  295. //'---------------------------------------------------------------------------
  296. $resArray = hash_call("GetExpressCheckoutDetails", $nvpstr);
  297. $ack = strtoupper($resArray["ACK"]);
  298. if ($ack == "SUCCESS" || $ack == "SUCCESSWITHWARNING") {
  299. $_SESSION['payer_id'] = $resArray['PAYERID'];
  300. }
  301. return $resArray;
  302. }
  303. /**
  304. * Validate payment
  305. *
  306. * @param string $token Token
  307. * @param string $paymentType Type
  308. * @param string $currencyCodeType Currency
  309. * @param string $payerID Payer ID
  310. * @param string $ipaddress IP Address
  311. * @param string $FinalPaymentAmt Amount
  312. * @param string $tag Full tag
  313. * @return array
  314. */
  315. function confirmPayment($token, $paymentType, $currencyCodeType, $payerID, $ipaddress, $FinalPaymentAmt, $tag)
  316. {
  317. /* Gather the information to make the final call to
  318. finalize the PayPal payment. The variable nvpstr
  319. holds the name value pairs
  320. */
  321. //declaring of global variables
  322. global $conf, $langs;
  323. global $API_Endpoint, $API_Url, $API_version, $USE_PROXY, $PROXY_HOST, $PROXY_PORT;
  324. global $PAYPAL_API_USER, $PAYPAL_API_PASSWORD, $PAYPAL_API_SIGNATURE;
  325. $nvpstr = '';
  326. $nvpstr .= '&TOKEN='.urlencode($token);
  327. $nvpstr .= '&PAYERID='.urlencode($payerID);
  328. $nvpstr .= '&PAYMENTACTION='.urlencode($paymentType);
  329. $nvpstr .= '&AMT='.urlencode($FinalPaymentAmt);
  330. $nvpstr .= '&CURRENCYCODE='.urlencode($currencyCodeType);
  331. $nvpstr .= '&IPADDRESS='.urlencode($ipaddress);
  332. $nvpstr .= '&INVNUM='.urlencode($tag);
  333. /* Make the call to PayPal to finalize payment
  334. If an error occured, show the resulting errors
  335. */
  336. $resArray = hash_call("DoExpressCheckoutPayment", $nvpstr);
  337. /* Display the API response back to the browser.
  338. If the response from PayPal was a success, display the response parameters'
  339. If the response was an error, display the errors received using APIError.php.
  340. */
  341. $ack = strtoupper($resArray["ACK"]);
  342. return $resArray;
  343. }
  344. /**
  345. * This function makes a DoDirectPayment API call
  346. *
  347. * paymentType: paymentType has to be one of the following values: Sale or Order or Authorization
  348. * paymentAmount: total value of the shopping cart
  349. * currencyCode: currency code value the PayPal API
  350. * firstName: first name as it appears on credit card
  351. * lastName: last name as it appears on credit card
  352. * street: buyer's street address line as it appears on credit card
  353. * city: buyer's city
  354. * state: buyer's state
  355. * countryCode: buyer's country code
  356. * zip: buyer's zip
  357. * creditCardType: buyer's credit card type (i.e. Visa, MasterCard ... )
  358. * creditCardNumber: buyers credit card number without any spaces, dashes or any other characters
  359. * expDate: credit card expiration date
  360. * cvv2: Card Verification Value
  361. * @return array The NVP Collection object of the DoDirectPayment Call Response.
  362. */
  363. /*
  364. function DirectPayment($paymentType, $paymentAmount, $creditCardType, $creditCardNumber, $expDate, $cvv2, $firstName, $lastName, $street, $city, $state, $zip, $countryCode, $currencyCode, $tag)
  365. {
  366. //declaring of global variables
  367. global $conf, $langs;
  368. global $API_Endpoint, $API_Url, $API_version, $USE_PROXY, $PROXY_HOST, $PROXY_PORT;
  369. global $PAYPAL_API_USER, $PAYPAL_API_PASSWORD, $PAYPAL_API_SIGNATURE;
  370. //Construct the parameter string that describes DoDirectPayment
  371. $nvpstr = '';
  372. $nvpstr = $nvpstr . "&AMT=" . urlencode($paymentAmount); // deprecated by paypal
  373. $nvpstr = $nvpstr . "&CURRENCYCODE=" . urlencode($currencyCode);
  374. $nvpstr = $nvpstr . "&PAYMENTACTION=" . urlencode($paymentType); // deprecated by paypal
  375. $nvpstr = $nvpstr . "&CREDITCARDTYPE=" . urlencode($creditCardType);
  376. $nvpstr = $nvpstr . "&ACCT=" . urlencode($creditCardNumber);
  377. $nvpstr = $nvpstr . "&EXPDATE=" . urlencode($expDate);
  378. $nvpstr = $nvpstr . "&CVV2=" . urlencode($cvv2);
  379. $nvpstr = $nvpstr . "&FIRSTNAME=" . urlencode($firstName);
  380. $nvpstr = $nvpstr . "&LASTNAME=" . urlencode($lastName);
  381. $nvpstr = $nvpstr . "&STREET=" . urlencode($street);
  382. $nvpstr = $nvpstr . "&CITY=" . urlencode($city);
  383. $nvpstr = $nvpstr . "&STATE=" . urlencode($state);
  384. $nvpstr = $nvpstr . "&COUNTRYCODE=" . urlencode($countryCode);
  385. $nvpstr = $nvpstr . "&IPADDRESS=" . getUserRemotIP();
  386. $nvpstr = $nvpstr . "&INVNUM=" . urlencode($tag);
  387. $resArray=hash_call("DoDirectPayment", $nvpstr);
  388. return $resArray;
  389. }
  390. */
  391. /**
  392. * hash_call: Function to perform the API call to PayPal using API signature
  393. *
  394. * @param string $methodName is name of API method.
  395. * @param string $nvpStr is nvp string.
  396. * @return array returns an associtive array containing the response from the server.
  397. */
  398. function hash_call($methodName, $nvpStr)
  399. {
  400. //declaring of global variables
  401. global $conf, $langs;
  402. global $API_Endpoint, $API_Url, $API_version, $USE_PROXY, $PROXY_HOST, $PROXY_PORT, $PROXY_USER, $PROXY_PASS;
  403. global $PAYPAL_API_USER, $PAYPAL_API_PASSWORD, $PAYPAL_API_SIGNATURE;
  404. // TODO problem with triggers
  405. $API_version = "98.0";
  406. if (getDolGlobalString('PAYPAL_API_SANDBOX') || GETPOST('forcesandbox', 'alpha')) { // We can force sand box with param 'forcesandbox'
  407. $API_Endpoint = "https://api-3t.sandbox.paypal.com/nvp";
  408. $API_Url = "https://www.sandbox.paypal.com/webscr?cmd=_express-checkout&token=";
  409. } else {
  410. $API_Endpoint = "https://api-3t.paypal.com/nvp";
  411. $API_Url = "https://www.paypal.com/cgi-bin/webscr?cmd=_express-checkout&token=";
  412. }
  413. // Clean parameters
  414. $PAYPAL_API_USER = "";
  415. if (getDolGlobalString('PAYPAL_API_USER')) {
  416. $PAYPAL_API_USER = $conf->global->PAYPAL_API_USER;
  417. }
  418. $PAYPAL_API_PASSWORD = "";
  419. if (getDolGlobalString('PAYPAL_API_PASSWORD')) {
  420. $PAYPAL_API_PASSWORD = $conf->global->PAYPAL_API_PASSWORD;
  421. }
  422. $PAYPAL_API_SIGNATURE = "";
  423. if (getDolGlobalString('PAYPAL_API_SIGNATURE')) {
  424. $PAYPAL_API_SIGNATURE = $conf->global->PAYPAL_API_SIGNATURE;
  425. }
  426. $PAYPAL_API_SANDBOX = "";
  427. if (getDolGlobalString('PAYPAL_API_SANDBOX')) {
  428. $PAYPAL_API_SANDBOX = $conf->global->PAYPAL_API_SANDBOX;
  429. }
  430. // TODO END problem with triggers
  431. dol_syslog("Paypal API endpoint ".$API_Endpoint);
  432. //setting the curl parameters.
  433. $ch = curl_init();
  434. /*print $API_Endpoint."-".$API_version."-".$PAYPAL_API_USER."-".$PAYPAL_API_PASSWORD."-".$PAYPAL_API_SIGNATURE."<br>";
  435. print $USE_PROXY."-".$gv_ApiErrorURL."<br>";
  436. print $nvpStr;
  437. exit;*/
  438. curl_setopt($ch, CURLOPT_URL, $API_Endpoint);
  439. curl_setopt($ch, CURLOPT_VERBOSE, 1);
  440. // TLSv1 by default or change to TLSv1.2 in module configuration
  441. curl_setopt($ch, CURLOPT_SSLVERSION, (!getDolGlobalString('PAYPAL_SSLVERSION') ? 1 : $conf->global->PAYPAL_SSLVERSION));
  442. $ssl_verifypeer = -1;
  443. // Turning on or off the ssl target certificate
  444. if ($ssl_verifypeer < 0) {
  445. global $dolibarr_main_prod;
  446. $ssl_verifypeer = ($dolibarr_main_prod ? true : false);
  447. }
  448. if (getDolGlobalString('MAIN_CURL_DISABLE_VERIFYPEER')) {
  449. $ssl_verifypeer = 0;
  450. }
  451. //turning off the server and peer verification(TrustManager Concept).
  452. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, ($ssl_verifypeer ? true : false));
  453. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, ($ssl_verifypeer ? true : false));
  454. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, !getDolGlobalString('MAIN_USE_CONNECT_TIMEOUT') ? 5 : $conf->global->MAIN_USE_CONNECT_TIMEOUT);
  455. curl_setopt($ch, CURLOPT_TIMEOUT, !getDolGlobalString('MAIN_USE_RESPONSE_TIMEOUT') ? 30 : $conf->global->MAIN_USE_RESPONSE_TIMEOUT);
  456. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  457. curl_setopt($ch, CURLOPT_POST, 1);
  458. //if USE_PROXY constant set to true in Constants.php, then only proxy will be enabled.
  459. if ($USE_PROXY) {
  460. dol_syslog("Paypal API hash_call set proxy to ".$PROXY_HOST.":".$PROXY_PORT." - ".$PROXY_USER.":".$PROXY_PASS);
  461. //curl_setopt ($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); // Curl 7.10
  462. curl_setopt($ch, CURLOPT_PROXY, $PROXY_HOST.":".$PROXY_PORT);
  463. if ($PROXY_USER) {
  464. curl_setopt($ch, CURLOPT_PROXYUSERPWD, $PROXY_USER.":".$PROXY_PASS);
  465. }
  466. }
  467. //NVPRequest for submitting to server
  468. $nvpreq = "METHOD=".urlencode($methodName)."&VERSION=".urlencode($API_version)."&PWD=".urlencode($PAYPAL_API_PASSWORD)."&USER=".urlencode($PAYPAL_API_USER)."&SIGNATURE=".urlencode($PAYPAL_API_SIGNATURE).$nvpStr;
  469. $nvpreq .= "&LOCALECODE=".strtoupper($langs->getDefaultLang(1));
  470. //$nvpreq.="&BRANDNAME=".urlencode(); // Override merchant name
  471. //$nvpreq.="&NOTIFYURL=".urlencode(); // For Instant Payment Notification url
  472. dol_syslog("Paypal API hash_call nvpreq=".$nvpreq);
  473. //setting the nvpreq as POST FIELD to curl
  474. curl_setopt($ch, CURLOPT_POSTFIELDS, $nvpreq);
  475. //getting response from server
  476. $response = curl_exec($ch);
  477. $nvpReqArray = deformatNVP($nvpreq);
  478. $_SESSION['nvpReqArray'] = $nvpReqArray;
  479. //convrting NVPResponse to an Associative Array
  480. dol_syslog("Paypal API hash_call Response nvpresp=".$response);
  481. $nvpResArray = deformatNVP($response);
  482. if (curl_errno($ch)) {
  483. // moving to display page to display curl errors
  484. $_SESSION['curl_error_no'] = curl_errno($ch);
  485. $_SESSION['curl_error_msg'] = curl_error($ch);
  486. //Execute the Error handling module to display errors.
  487. } else {
  488. //closing the curl
  489. curl_close($ch);
  490. }
  491. return $nvpResArray;
  492. }
  493. /**
  494. * This function will take NVPString and convert it to an Associative Array and it will decode the response.
  495. * It is usefull to search for a particular key and displaying arrays.
  496. *
  497. * @param string $nvpstr NVPString
  498. * @return array nvpArray = Associative Array
  499. */
  500. function deformatNVP($nvpstr)
  501. {
  502. $intial = 0;
  503. $nvpArray = array();
  504. while (strlen($nvpstr)) {
  505. //postion of Key
  506. $keypos = strpos($nvpstr, '=');
  507. //position of value
  508. $valuepos = strpos($nvpstr, '&') ? strpos($nvpstr, '&') : strlen($nvpstr);
  509. /*getting the Key and Value values and storing in a Associative Array*/
  510. $keyval = substr($nvpstr, $intial, $keypos);
  511. $valval = substr($nvpstr, $keypos + 1, $valuepos - $keypos - 1);
  512. //decoding the respose
  513. $nvpArray[urldecode($keyval)] = urldecode($valval);
  514. $nvpstr = substr($nvpstr, $valuepos + 1, strlen($nvpstr));
  515. }
  516. return $nvpArray;
  517. }
  518. /**
  519. * Get API errors
  520. *
  521. * @return array Array of errors
  522. */
  523. function getApiError()
  524. {
  525. $errors = array();
  526. $resArray = $_SESSION['reshash'];
  527. if (isset($_SESSION['curl_error_no'])) {
  528. $errors[] = $_SESSION['curl_error_no'].'-'.$_SESSION['curl_error_msg'];
  529. }
  530. foreach ($resArray as $key => $value) {
  531. $errors[] = $key.'-'.$value;
  532. }
  533. return $errors;
  534. }