PageRenderTime 65ms CodeModel.GetById 28ms RepoModel.GetById 1ms app.codeStats 0ms

/plugins/paymethod/paypal/PayPalPlugin.inc.php

https://github.com/Jouper/jouper
PHP | 307 lines | 206 code | 30 blank | 71 comment | 22 complexity | 4623bbeab2639d5b632f09d1da65cbc7 MD5 | raw file
Possible License(s): GPL-2.0
  1. <?php
  2. /**
  3. * @file PayPalPlugin.inc.php
  4. *
  5. * Copyright (c) 2006-2007 Gunther Eysenbach, Juan Pablo Alperin, MJ Suhonos
  6. * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
  7. *
  8. * @class PayPalPlugin
  9. * @ingroup plugins_paymethod_paypal
  10. *
  11. * @brief PayPal Paymethod plugin class
  12. *
  13. */
  14. import('classes.plugins.PaymethodPlugin');
  15. class PayPalPlugin extends PaymethodPlugin {
  16. /**
  17. * Get the Plugin's internal name
  18. * @return String
  19. */
  20. function getName() {
  21. return 'Paypal';
  22. }
  23. /**
  24. * Get the Plugin's display name
  25. * @return String
  26. */
  27. function getDisplayName() {
  28. return Locale::translate('plugins.paymethod.paypal.displayName');
  29. }
  30. /**
  31. * Get a description of the plugin
  32. * @return String
  33. */
  34. function getDescription() {
  35. return Locale::translate('plugins.paymethod.paypal.description');
  36. }
  37. /**
  38. * Register plugin
  39. * @return bool
  40. */
  41. function register($category, $path) {
  42. if (parent::register($category, $path)) {
  43. if (!Config::getVar('general', 'installed') || defined('RUNNING_UPGRADE')) return null;
  44. $this->addLocaleData();
  45. $this->import('PayPalDAO');
  46. $payPalDao =& new PayPalDAO();
  47. DAORegistry::registerDAO('PayPalDAO', $payPalDao);
  48. return true;
  49. }
  50. return false;
  51. }
  52. /**
  53. * Get an array of the fields in the settings form
  54. * @return array
  55. */
  56. function getSettingsFormFieldNames() {
  57. return array('paypalurl', 'selleraccount');
  58. }
  59. /**
  60. * return if required Curl is installed
  61. * @return bool
  62. */
  63. function isCurlInstalled() {
  64. return (function_exists('curl_init'));
  65. }
  66. /**
  67. * Check if plugin is configured and ready for use
  68. * @return bool
  69. */
  70. function isConfigured() {
  71. $journal =& Request::getJournal();
  72. if (!$journal) return false;
  73. // Make sure CURL support is included.
  74. if (!$this->isCurlInstalled()) return false;
  75. // Make sure that all settings form fields have been filled in
  76. foreach ($this->getSettingsFormFieldNames() as $settingName) {
  77. $setting = $this->getSetting($journal->getJournalId(), $settingName);
  78. if (empty($setting)) return false;
  79. }
  80. return true;
  81. }
  82. /**
  83. * Display the settings form
  84. * @param $params
  85. * @param $smarty Smarty
  86. */
  87. function displayPaymentSettingsForm(&$params, &$smarty) {
  88. $smarty->assign('isCurlInstalled', $this->isCurlInstalled());
  89. return parent::displayPaymentSettingsForm($params, $smarty);
  90. }
  91. /**
  92. * Display the payment form
  93. * @param $queuedPaymentId int
  94. * @param $queuedPayment QueuedPayment
  95. */
  96. function displayPaymentForm($queuedPaymentId, &$queuedPayment) {
  97. if (!$this->isConfigured()) return false;
  98. $journal =& Request::getJournal();
  99. $user =& Request::getUser();
  100. $params = array(
  101. 'business' => $this->getSetting($journal->getJournalId(), 'selleraccount'),
  102. 'item_name' => $queuedPayment->getName(),
  103. 'item_description' => $queuedPayment->getDescription(), // not a paypal parameter (PayPal uses item_name)
  104. 'amount' => $queuedPayment->getAmount(),
  105. 'quantity' => 1,
  106. 'no_note' => 1,
  107. 'no_shipping' => 1,
  108. 'currency_code' => $queuedPayment->getCurrencyCode(),
  109. 'lc' => String::substr(Locale::getLocale(), 3),
  110. 'custom' => $queuedPaymentId,
  111. 'notify_url' => Request::url(null, 'payment', 'plugin', array($this->getName(), 'ipn')),
  112. 'return' => $queuedPayment->getRequestUrl(),
  113. 'cancel_return' => Request::url(null, 'payment', 'plugin', array($this->getName(), 'cancel')),
  114. 'first_name' => ($user)?$user->getFirstName():'',
  115. 'last_name' => ($user)?$user->getLastname():'',
  116. 'item_number' => $queuedPayment->getAssocId(),
  117. 'cmd' => '_xclick'
  118. );
  119. $templateMgr =& TemplateManager::getManager();
  120. $templateMgr->assign('params', $params);
  121. $templateMgr->assign('paypalFormUrl', $this->getSetting($journal->getJournalId(), 'paypalurl'));
  122. $templateMgr->display($this->getTemplatePath() . 'paymentForm.tpl');
  123. }
  124. /**
  125. * Handle incoming requests/notifications
  126. */
  127. function handle($args) {
  128. $templateMgr =& TemplateManager::getManager();
  129. $journal =& Request::getJournal();
  130. if (!$journal) return parent::handle($args);
  131. // Just in case we need to contact someone
  132. import('mail.MailTemplate');
  133. $contactName = $journal->getSetting('contactName');
  134. $contactEmail = $journal->getSetting('contactEmail');
  135. $mail = &new MailTemplate('PAYPAL_INVESTIGATE_PAYMENT');
  136. $mail->setFrom($contactEmail, $contactName);
  137. $mail->addRecipient($contactEmail, $contactName);
  138. $paymentStatus = Request::getUserVar('payment_status');
  139. switch (array_shift($args)) {
  140. case 'ipn':
  141. // Build a confirmation transaction.
  142. $req = 'cmd=_notify-validate';
  143. foreach ($_POST as $key => $value) $req .= '&' . urlencode($key) . '=' . urlencode($value);
  144. // Create POST response
  145. $ch = curl_init();
  146. curl_setopt($ch, CURLOPT_URL, $this->getSetting($journal->getJournalId(), 'paypalurl'));
  147. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  148. curl_setopt($ch, CURLOPT_POST, 1);
  149. curl_setopt($ch, CURLOPT_HTTPHEADER, Array('Content-Type: application/x-www-form-urlencoded', 'Content-Length: ' . strlen($req)));
  150. curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
  151. $ret = curl_exec ($ch);
  152. curl_close ($ch);
  153. // Check the confirmation response and handle as necessary.
  154. if (strcmp($ret, 'VERIFIED') == 0) switch ($paymentStatus) {
  155. case 'Completed':
  156. $payPalDao =& DAORegistry::getDAO('PayPalDAO');
  157. $transactionId = Request::getUserVar('txn_id');
  158. if ($payPalDao->transactionExists($transactionId)) {
  159. // A duplicate transaction was received; notify someone.
  160. $mail->assignParams(array(
  161. 'journalName' => $journal->getJournalTitle(),
  162. 'postInfo' => print_r($_POST, true),
  163. 'additionalInfo' => "Duplicate transaction ID: $transactionId",
  164. 'serverVars' => print_r($_SERVER, true)
  165. ));
  166. $mail->send();
  167. exit();
  168. } else {
  169. // New transaction succeeded. Record it.
  170. $payPalDao->insertTransaction(
  171. $transactionId,
  172. Request::getUserVar('txn_type'),
  173. Request::getUserVar('payer_email'),
  174. Request::getUserVar('receiver_email'),
  175. Request::getUserVar('item_number'),
  176. Request::getUserVar('payment_date'),
  177. Request::getUserVar('payer_id'),
  178. Request::getUserVar('receiver_id')
  179. );
  180. $queuedPaymentId = Request::getUserVar('custom');
  181. import('payment.ojs.OJSPaymentManager');
  182. $ojsPaymentManager =& OJSPaymentManager::getManager();
  183. // Verify the cost and user details as per PayPal spec.
  184. $queuedPayment =& $ojsPaymentManager->getQueuedPayment($queuedPaymentId);
  185. if (!$queuedPayment) {
  186. // The queued payment entry is missing. Complain.
  187. $mail->assignParams(array(
  188. 'journalName' => $journal->getJournalTitle(),
  189. 'postInfo' => print_r($_POST, true),
  190. 'additionalInfo' => "Missing queued payment ID: $queuedPaymentId",
  191. 'serverVars' => print_r($_SERVER, true)
  192. ));
  193. $mail->send();
  194. exit();
  195. }
  196. //NB: if/when paypal subscriptions are enabled, these checks will have to be adjusted
  197. // because subscription prices may change over time
  198. if (
  199. (($queuedAmount = $queuedPayment->getAmount()) != ($grantedAmount = Request::getUserVar('mc_gross')) && $queuedAmount > 0) ||
  200. ($queuedCurrency = $queuedPayment->getCurrencyCode()) != ($grantedCurrency = Request::getUserVar('mc_currency')) ||
  201. ($grantedEmail = Request::getUserVar('receiver_email')) != ($queuedEmail = $this->getSetting($journal->getJournalId(), 'selleraccount'))
  202. ) {
  203. // The integrity checks for the transaction failed. Complain.
  204. $mail->assignParams(array(
  205. 'journalName' => $journal->getJournalTitle(),
  206. 'postInfo' => print_r($_POST, true),
  207. 'additionalInfo' =>
  208. "Granted amount: $grantedAmount\n" .
  209. "Queued amount: $queuedAmount\n" .
  210. "Granted currency: $grantedCurrency\n" .
  211. "Queued currency: $queuedCurrency\n" .
  212. "Granted to PayPal account: $grantedEmail\n" .
  213. "Configured PayPal account: $queuedEmail",
  214. 'serverVars' => print_r($_SERVER, true)
  215. ));
  216. $mail->send();
  217. exit();
  218. }
  219. // Fulfill the queued payment.
  220. if ($ojsPaymentManager->fulfillQueuedPayment($queuedPayment, $this->getName())) exit();
  221. // If we're still here, it means the payment couldn't be fulfilled.
  222. $mail->assignParams(array(
  223. 'journalName' => $journal->getJournalTitle(),
  224. 'postInfo' => print_r($_POST, true),
  225. 'additionalInfo' => "Queued payment ID $queuedPaymentId could not be fulfilled.",
  226. 'serverVars' => print_r($_SERVER, true)
  227. ));
  228. $mail->send();
  229. }
  230. exit();
  231. case 'Pending':
  232. // Ignore.
  233. exit();
  234. default:
  235. // An unhandled payment status was received; notify someone.
  236. $mail->assignParams(array(
  237. 'journalName' => $journal->getJournalTitle(),
  238. 'postInfo' => print_r($_POST, true),
  239. 'additionalInfo' => "Payment status: $paymentStatus",
  240. 'serverVars' => print_r($_SERVER, true)
  241. ));
  242. $mail->send();
  243. exit();
  244. } else {
  245. // An unknown confirmation response was received; notify someone.
  246. $mail->assignParams(array(
  247. 'journalName' => $journal->getJournalTitle(),
  248. 'postInfo' => print_r($_POST, true),
  249. 'additionalInfo' => "Confirmation return: $ret",
  250. 'serverVars' => print_r($_SERVER, true)
  251. ));
  252. $mail->send();
  253. exit();
  254. }
  255. break;
  256. case 'cancel':
  257. $templateMgr->assign(array(
  258. 'currentUrl' => Request::url(null, null, 'index'),
  259. 'pageTitle' => 'plugins.paymethod.paypal.purchase.cancelled.title',
  260. 'message' => 'plugins.paymethod.paypal.purchase.cancelled',
  261. 'backLink' => Request::getUserVar('ojsReturnUrl'),
  262. 'backLinkLabel' => 'common.continue'
  263. ));
  264. $templateMgr->display('common/message.tpl');
  265. exit();
  266. break;
  267. }
  268. parent::handle($args); // Don't know what to do with it
  269. }
  270. function getInstallSchemaFile() {
  271. return ($this->getPluginPath() . DIRECTORY_SEPARATOR . 'schema.xml');
  272. }
  273. function getInstallDataFile() {
  274. return ($this->getPluginPath() . DIRECTORY_SEPARATOR . 'data.xml');
  275. }
  276. }
  277. ?>