PageRenderTime 38ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/modules/paypal/ipn.php

https://gitlab.com/ptisky/API_prestashop
PHP | 250 lines | 187 code | 35 blank | 28 comment | 24 complexity | a0b2682773111c560eaf90b64a7fdeb1 MD5 | raw file
  1. <?php
  2. /**
  3. * 2007-2015 PrestaShop
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Academic Free License (AFL 3.0)
  8. * that is bundled with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://opensource.org/licenses/afl-3.0.php
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@prestashop.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
  18. * versions in the future. If you wish to customize PrestaShop for your
  19. * needs please refer to http://www.prestashop.com for more information.
  20. *
  21. * @author PrestaShop SA <contact@prestashop.com>
  22. * @copyright 2007-2015 PrestaShop SA
  23. * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
  24. * International Registered Trademark & Property of PrestaShop SA
  25. */
  26. include_once(dirname(__FILE__).'/../../config/config.inc.php');
  27. include_once(_PS_MODULE_DIR_.'paypal/paypal.php');
  28. /*
  29. * Instant payment notification class.
  30. * (wait for PayPal payment confirmation, then validate order)
  31. */
  32. class PayPalIPN extends PayPal
  33. {
  34. public function getIPNTransactionDetails($result)
  35. {
  36. if (is_array($result) || (strcmp(trim($result), "VERIFIED") === false))
  37. {
  38. $transaction_id = pSQL($result['txn_id']);
  39. return array(
  40. 'id_transaction' => $transaction_id,
  41. 'transaction_id' => $transaction_id,
  42. 'id_invoice' => $result['invoice'],
  43. 'currency' => pSQL($result['mc_currency']),
  44. 'total_paid' => (float)$result['mc_gross'],
  45. 'shipping' => (float)$result['mc_shipping'],
  46. 'payment_date' => pSQL($result['payment_date']),
  47. 'payment_status' => pSQL($result['payment_status']),
  48. );
  49. }
  50. else
  51. {
  52. $transaction_id = pSQL(Tools::getValue('txn_id'));
  53. return array(
  54. 'id_transaction' => $transaction_id,
  55. 'transaction_id' => $transaction_id,
  56. 'id_invoice' => pSQL(Tools::getValue('invoice')),
  57. 'currency' => pSQL(Tools::getValue('mc_currency')),
  58. 'total_paid' => (float)Tools::getValue('mc_gross'),
  59. 'shipping' => (float)Tools::getValue('mc_shipping'),
  60. 'payment_date' => pSQL(Tools::getValue('payment_date')),
  61. 'payment_status' => pSQL(Tools::getValue('payment_status')),
  62. );
  63. }
  64. }
  65. public function confirmOrder($custom)
  66. {
  67. $result = $this->getResult();
  68. $payment_status = Tools::getValue('payment_status');
  69. $mc_gross = Tools::getValue('mc_gross');
  70. $txn_id = Tools::getValue('txn_id');
  71. $id_order = (int)PayPalOrder::getIdOrderByTransactionId($txn_id);
  72. if ($id_order != 0)
  73. Context::getContext()->cart = new Cart((int)$id_order);
  74. elseif (isset($custom['id_cart']))
  75. Context::getContext()->cart = new Cart((int)$custom['id_cart']);
  76. $address = new Address((int)Context::getContext()->cart->id_address_invoice);
  77. Context::getContext()->country = new Country((int)$address->id_country);
  78. Context::getContext()->customer = new Customer((int)Context::getContext()->cart->id_customer);
  79. Context::getContext()->language = new Language((int)Context::getContext()->cart->id_lang);
  80. Context::getContext()->currency = new Currency((int)Context::getContext()->cart->id_currency);
  81. if (isset(Context::getContext()->cart->id_shop))
  82. Context::getContext()->shop = new Shop(Context::getContext()->cart->id_shop);
  83. if (strcmp(trim($result), "VERIFIED") === false)
  84. {
  85. $details = $this->getIPNTransactionDetails($result);
  86. if ($id_order != 0)
  87. {
  88. $history = new OrderHistory();
  89. $history->id_order = (int)$id_order;
  90. PayPalOrder::updateOrder($id_order, $details);
  91. $history->changeIdOrderState((int)Configuration::get('PS_OS_ERROR'), $history->id_order);
  92. $history->addWithemail();
  93. $history->save();
  94. }
  95. }
  96. elseif (strcmp(trim($result), "VERIFIED") === 0)
  97. {
  98. $details = $this->getIPNTransactionDetails($result);
  99. if (version_compare(_PS_VERSION_, '1.5', '<'))
  100. $shop = null;
  101. else
  102. {
  103. $shop_id = Context::getContext()->shop->id;
  104. $shop = new Shop($shop_id);
  105. }
  106. if ($id_order != 0)
  107. {
  108. $order = new Order((int)$id_order);
  109. $values = $this->checkPayment($payment_status, $mc_gross, false);
  110. if ((int)$order->current_state == (int)$values['payment_type'])
  111. return;
  112. $history = new OrderHistory();
  113. $history->id_order = (int)$id_order;
  114. PayPalOrder::updateOrder($id_order, $details);
  115. $history->changeIdOrderState($values['payment_type'], $history->id_order);
  116. $history->addWithemail();
  117. $history->save();
  118. }
  119. else
  120. {
  121. $values = $this->checkPayment($payment_status, $mc_gross, true);
  122. $customer = new Customer((int)Context::getContext()->cart->id_customer);
  123. $this->validateOrder(Context::getContext()->cart->id, $values['payment_type'], $values['total_price'], $this->displayName, $values['message'], $details, Context::getContext()->cart->id_currency, false, $customer->secure_key, $shop);
  124. }
  125. }
  126. }
  127. public function checkPayment($payment_status, $mc_gross_not_rounded, $new_order)
  128. {
  129. $currency_decimals = is_array(Context::getContext()->currency) ? (int)Context::getContext()->currency['decimals'] : (int)Context::getContext()->currency->decimals;
  130. $this->decimals = $currency_decimals * _PS_PRICE_DISPLAY_PRECISION_;
  131. $mc_gross = Tools::ps_round($mc_gross_not_rounded, $this->decimals);
  132. $cart_details = Context::getContext()->cart->getSummaryDetails(null, true);
  133. $cart_hash = sha1(serialize(Context::getContext()->cart->nbProducts()));
  134. $custom = Tools::jsonDecode(Tools::getValue('custom'), true);
  135. $shipping = $cart_details['total_shipping_tax_exc'];
  136. $subtotal = $cart_details['total_price_without_tax'] - $cart_details['total_shipping_tax_exc'];
  137. $tax = $cart_details['total_tax'];
  138. $total_price = Tools::ps_round($shipping + $subtotal + $tax, $this->decimals);
  139. if (($new_order == true) && ($this->comp($mc_gross, $total_price, 2) !== 0))
  140. {
  141. $payment_type = (int)Configuration::get('PS_OS_ERROR');
  142. $message = $this->l('Price paid on paypal is not the same that on PrestaShop.').'<br />';
  143. }
  144. elseif (($new_order == true) && ($custom['hash'] != $cart_hash))
  145. {
  146. $payment_type = (int)Configuration::get('PS_OS_ERROR');
  147. $message = $this->l('Cart changed, please retry.').'<br />';
  148. }
  149. else
  150. {
  151. return $this->getDetails($payment_status) + array(
  152. 'payment_status' => $payment_status,
  153. 'total_price' => $total_price
  154. );
  155. }
  156. return array(
  157. 'message' => $message,
  158. 'payment_type' => $payment_type,
  159. 'payment_status' => $payment_status,
  160. 'total_price' => $total_price
  161. );
  162. }
  163. public function getDetails($payment_status)
  164. {
  165. if ((bool)Configuration::get('PAYPAL_CAPTURE'))
  166. {
  167. $payment_type = (int)Configuration::get('PS_OS_WS_PAYMENT');
  168. $message = $this->l('Pending payment capture.').'<br />';
  169. }
  170. else
  171. {
  172. if (strcmp($payment_status, 'Completed') === 0)
  173. {
  174. $payment_type = (int)Configuration::get('PS_OS_PAYMENT');
  175. $message = $this->l('Payment accepted.').'<br />';
  176. }
  177. elseif (strcmp($payment_status, 'Pending') === 0)
  178. {
  179. $payment_type = (int)Configuration::get('PS_OS_PAYPAL');
  180. $message = $this->l('Pending payment confirmation.').'<br />';
  181. }
  182. else
  183. {
  184. $payment_type = (int)Configuration::get('PS_OS_ERROR');
  185. $message = $this->l('Cart changed, please retry.').'<br />';
  186. }
  187. }
  188. return array(
  189. 'message' => $message,
  190. 'payment_type' => (int)$payment_type
  191. );
  192. }
  193. public function getResult()
  194. {
  195. if ((int)Configuration::get('PAYPAL_SANDBOX') == 1)
  196. $action_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr?cmd=_notify-validate';
  197. else
  198. $action_url = 'https://www.paypal.com/cgi-bin/webscr?cmd=_notify-validate';
  199. $request = '';
  200. foreach ($_POST as $key => $value)
  201. {
  202. $value = urlencode(Tools::stripslashes($value));
  203. $request .= "&$key=$value";
  204. }
  205. $handle = fopen(dirname(__FILE__).'/log.txt', 'w+');
  206. fwrite($handle, $action_url.$request);
  207. return Tools::file_get_contents($action_url.$request);
  208. }
  209. }
  210. if (Tools::getIsset('custom'))
  211. {
  212. $ipn = new PayPalIPN();
  213. $custom = Tools::jsonDecode(Tools::getValue('custom'), true);
  214. $ipn->confirmOrder($custom);
  215. }