PayPal_Rest_API_Utility

The PayPal for WooCommerce PayPal Rest API Utility class.

Defined (1)

The class is defined in the following location(s).

/angelleye-includes/paypal-rest-api-utility.php  
  1. class PayPal_Rest_API_Utility { 
  2.  
  3. public $card; 
  4. public $FundingInstrument; 
  5. public $Payer; 
  6. public $order_item; 
  7. public $item; 
  8. public $item_list; 
  9. public $details; 
  10. public $payment_data; 
  11. public $amount; 
  12. public $transaction; 
  13. public $payment; 
  14. public $payment_method; 
  15. public $gateway; 
  16. public $CreditCardToken; 
  17.  
  18. public function __construct($gateway) { 
  19. $this->add_paypal_rest_api_lib(); 
  20. $this->create_transaction_method_obj(); 
  21. $this->payment_method = (isset($_POST['payment_method'])) ? $_POST['payment_method'] : 'paypal_credit_card_rest'; 
  22. if ($this->payment_method == 'paypal_credit_card_rest') { 
  23. $this->gateway = $gateway; 
  24. $this->testmode = 'yes' === $this->gateway->get_option('testmode', 'no'); 
  25. $this->softdescriptor = $this->gateway->get_option('softdescriptor', ''); 
  26. $this->mode = $this->testmode == true ? 'SANDBOX' : 'LIVE'; 
  27. $this->debug = 'yes' === $this->gateway->get_option('debug', 'no'); 
  28. if ($this->testmode) { 
  29. $this->rest_client_id = $this->gateway->get_option('rest_client_id_sandbox', false); 
  30. $this->rest_secret_id = $this->gateway->get_option('rest_secret_id_sandbox', false); 
  31. } else { 
  32. $this->rest_client_id = $this->gateway->get_option('rest_client_id', false); 
  33. $this->rest_secret_id = $this->gateway->get_option('rest_secret_id', false); 
  34.  
  35. /** 
  36. * @since 1.2 
  37. * @global type $woocommerce 
  38. * @param type $order 
  39. * @param type $card_data 
  40. * @return type 
  41. */ 
  42. public function create_payment($order, $card_data) { 
  43. global $woocommerce; 
  44. $old_wc = version_compare(WC_VERSION, '3.0', '<'); 
  45. $order_id = version_compare( WC_VERSION, '3.0', '<' ) ? $order->id : $order->get_id(); 
  46. try { 
  47. $this->set_trnsaction_obj_value($order, $card_data); 
  48. try { 
  49. $this->add_log(print_r($this->payment, true)); 
  50. $this->payment->create($this->getAuth()); 
  51. } catch (PayPal\Exception\PayPalConnectionException $ex) { 
  52. $this->add_log($ex->getMessage()); 
  53. if (!empty($order->subscription_renewal)) { 
  54. return true; 
  55. wc_add_notice(__("Error processing checkout. Please try again. ", 'woo-paypal-plus'), 'error'); 
  56. return array( 
  57. 'result' => 'fail',  
  58. 'redirect' => '' 
  59. ); 
  60. } catch (Exception $ex) { 
  61. $this->send_failed_order_email($order_id); 
  62. $this->add_log($ex->getMessage()); 
  63. if (!empty($order->subscription_renewal)) { 
  64. return true; 
  65. wc_add_notice(__("Error processing checkout. Please try again. ", 'woo-paypal-plus'), 'error'); 
  66. return array( 
  67. 'result' => 'fail',  
  68. 'redirect' => '' 
  69. ); 
  70.  
  71. if ($this->payment->state == "approved") { 
  72. $transactions = $this->payment->getTransactions(); 
  73. $relatedResources = $transactions[0]->getRelatedResources(); 
  74. $sale = $relatedResources[0]->getSale(); 
  75. $saleId = $sale->getId(); 
  76. do_action('before_save_payment_token', $order_id); 
  77. $order->add_order_note(__('PayPal Credit Card (REST) payment completed', 'paypal-for-woocommerce')); 
  78. if ((!empty($_POST['wc-paypal_credit_card_rest-payment-token']) && $_POST['wc-paypal_credit_card_rest-payment-token'] == 'new') || $this->is_subscription($order_id)) { 
  79. if ((!empty($_POST['wc-paypal_credit_card_rest-new-payment-method']) && $_POST['wc-paypal_credit_card_rest-new-payment-method'] == true) || $this->is_subscription($order_id)) { 
  80. try { 
  81. $this->card->create($this->getAuth()); 
  82. $customer_id = $order->get_user_id(); 
  83. $creditcard_id = $this->card->getId(); 
  84. $this->save_payment_token($order, $creditcard_id); 
  85. $token = new WC_Payment_Token_CC(); 
  86. $token->set_user_id( $customer_id ); 
  87. $token->set_token( $creditcard_id ); 
  88. $token->set_gateway_id( $this->payment_method ); 
  89. $token->set_card_type( $this->card->type ); 
  90. $token->set_last4( substr( $this->card->number, -4 ) ); 
  91. $token->set_expiry_month( $this->card->expire_month ); 
  92. $token->set_expiry_year( $this->card->expire_year ); 
  93. $save_result = $token->save(); 
  94. if ($save_result) { 
  95. $order->add_payment_token($token); 
  96. } catch (Exception $ex) { 
  97.  
  98. $order->payment_complete($saleId); 
  99. $is_sandbox = $this->mode == 'SANDBOX' ? true : false; 
  100. if ($old_wc) { 
  101. update_post_meta($order->id, 'is_sandbox', $is_sandbox); 
  102. } else { 
  103. update_post_meta( $order->get_id(), 'is_sandbox', $is_sandbox ); 
  104. if (!empty($order->subscription_renewal)) { 
  105. return true; 
  106. WC()->cart->empty_cart(); 
  107. $return_url = $order->get_checkout_order_received_url(); 
  108. if (is_ajax()) { 
  109. wp_send_json(array( 
  110. 'result' => 'success',  
  111. 'redirect' => apply_filters('woocommerce_checkout_no_payment_needed_redirect', $return_url, $order) 
  112. )); 
  113. } else { 
  114. wp_safe_redirect( 
  115. apply_filters('woocommerce_checkout_no_payment_needed_redirect', $return_url, $order) 
  116. ); 
  117. exit; 
  118. } else { 
  119. $this->send_failed_order_email($order_id); 
  120. if (!empty($order->subscription_renewal)) { 
  121. return true; 
  122. wc_add_notice(__('Error Payment state:' . $this->payment->state, 'paypal-for-woocommerce'), 'error'); 
  123. $this->add_log(__('Error Payment state:' . $this->payment->state, 'paypal-for-woocommerce')); 
  124. return array( 
  125. 'result' => 'fail',  
  126. 'redirect' => '' 
  127. ); 
  128. } catch (PayPal\Exception\PayPalConnectionException $ex) { 
  129. $this->send_failed_order_email($order_id); 
  130. $this->add_log($ex->getData()); 
  131. if (!empty($order->subscription_renewal)) { 
  132. return true; 
  133. wc_add_notice(__("Error processing checkout. Please try again. ", 'paypal-for-woocommerce'), 'error'); 
  134. $this->add_log($ex->getData()); 
  135. return array( 
  136. 'result' => 'fail',  
  137. 'redirect' => '' 
  138. ); 
  139. exit; 
  140. } catch (Exception $ex) { 
  141. $this->send_failed_order_email($order_id); 
  142. $this->add_log($ex->getMessage()); 
  143. if (!empty($order->subscription_renewal)) { 
  144. return true; 
  145. wc_add_notice(__("Error processing checkout. Please try again. ", 'paypal-for-woocommerce'), 'error'); 
  146. $this->add_log($ex->getMessage()); 
  147. return array( 
  148. 'result' => 'fail',  
  149. 'redirect' => '' 
  150. ); 
  151.  
  152. /** 
  153. * @since 1.2 
  154. * @param type $order 
  155. * @param type $card_data 
  156. */ 
  157. public function set_trnsaction_obj_value($order, $card_data) { 
  158. $order_id = version_compare(WC_VERSION, '3.0', '<') ? $order->id : $order->get_id(); 
  159. if (!empty($_POST['wc-paypal_credit_card_rest-payment-token']) && $_POST['wc-paypal_credit_card_rest-payment-token'] != 'new') { 
  160. $token_id = wc_clean($_POST['wc-paypal_credit_card_rest-payment-token']); 
  161. $token = WC_Payment_Tokens::get($token_id); 
  162. $this->CreditCardToken = new CreditCardToken(); 
  163. $this->CreditCardToken->setCreditCardId($token->get_token()); 
  164. $this->fundingInstrument = new FundingInstrument(); 
  165. $this->fundingInstrument->setCreditCardToken($this->CreditCardToken); 
  166. $this->save_payment_token($order, $token->get_token()); 
  167. } else if (!empty($order->subscription_renewal)) { 
  168. $payment_tokens = get_post_meta($order_id, '_payment_tokens_id', true); 
  169. $this->CreditCardToken = new CreditCardToken(); 
  170. $this->CreditCardToken->setCreditCardId($payment_tokens); 
  171. $this->fundingInstrument = new FundingInstrument(); 
  172. $this->fundingInstrument->setCreditCardToken($this->CreditCardToken); 
  173. } else { 
  174. $this->set_card_details($order, $card_data); 
  175. $this->fundingInstrument = new FundingInstrument(); 
  176. $this->fundingInstrument->setCreditCard($this->card); 
  177.  
  178. $this->payer = new Payer(); 
  179. $this->payer->setPaymentMethod("credit_card"); 
  180. $this->payer->setFundingInstruments(array($this->fundingInstrument)); 
  181. if ($order->get_total() > 0) { 
  182. $this->set_item($order); 
  183. $this->set_item_list(); 
  184. $this->set_detail_values(); 
  185. $this->set_amount_values($order); 
  186. $this->set_transaction($order); 
  187. $this->set_payment(); 
  188.  
  189. /** 
  190. * @since 1.2 
  191. * @param type $order 
  192. */ 
  193. public function set_item($order) { 
  194. $this->payment_data = AngellEYE_Gateway_Paypal::calculate($order, $this->send_items); 
  195. foreach ($this->payment_data['order_items'] as $item) { 
  196. $this->item = new Item(); 
  197. $this->item->setName($item['name']); 
  198. $this->item->setCurrency(version_compare(WC_VERSION, '3.0', '<') ? $order->get_order_currency() : $order->get_currency()); 
  199. $this->item->setQuantity($item['qty']); 
  200. $this->item->setPrice($item['amt']); 
  201. array_push($this->order_item, $this->item); 
  202.  
  203. /** 
  204. * @since 1.2 
  205. */ 
  206. public function set_item_list() { 
  207. $this->item_list = new ItemList(); 
  208. $this->item_list->setItems($this->order_item); 
  209.  
  210. /** 
  211. * @since 1.2 
  212. */ 
  213. public function set_detail_values() { 
  214. $this->details = new Details(); 
  215. if (isset($this->payment_data['shippingamt'])) { 
  216. $this->details->setShipping($this->payment_data['shippingamt']); 
  217. if (isset($this->payment_data['taxamt'])) { 
  218. $this->details->setTax($this->payment_data['taxamt']); 
  219. if ($this->payment_data['itemamt']) { 
  220. $this->details->setSubtotal($this->payment_data['itemamt']); 
  221.  
  222. /** 
  223. * @since 1.2 
  224. * @param type $order 
  225. */ 
  226. public function set_amount_values($order) { 
  227. $this->amount = new Amount(); 
  228. $this->amount->setCurrency(version_compare(WC_VERSION, '3.0', '<') ? $order->get_order_currency() : $order->get_currency()); 
  229. $this->amount->setTotal($this->number_format($order->get_total(), $order)); 
  230. $this->amount->setDetails($this->details); 
  231.  
  232. /** 
  233. * @since 1.2 
  234. */ 
  235. public function set_transaction($order) { 
  236. $this->transaction = new Transaction(); 
  237. $this->transaction->setAmount($this->amount); 
  238. $this->transaction->setItemList($this->item_list); 
  239. $this->transaction->setDescription("Payment description"); 
  240. $this->transaction->setInvoiceNumber(uniqid()); 
  241. $this->transaction->setCustom(json_encode(array('order_id' => version_compare(WC_VERSION, '3.0', '<') ? $order->id : $order->get_id(), 'order_key' => version_compare(WC_VERSION, '3.0', '<') ? $order->order_key : $order->get_order_key()))); 
  242. if (!empty($this->softdescriptor)) { 
  243. $this->transaction->setSoftDescriptor($this->softdescriptor); 
  244.  
  245. /** 
  246. * @since 1.2 
  247. */ 
  248. public function set_payment() { 
  249. $this->payment = new Payment(); 
  250. $this->payment->setIntent("sale"); 
  251. $this->payment->setPayer($this->payer); 
  252. $this->payment->setTransactions(array($this->transaction)); 
  253.  
  254. /** 
  255. * @since 1.2 
  256. * @return ApiContext 
  257. */ 
  258. public function getAuth() { 
  259. $this->mode = $this->testmode == true ? 'SANDBOX' : 'LIVE'; 
  260. $auth = new ApiContext(new OAuthTokenCredential($this->rest_client_id, $this->rest_secret_id)); 
  261. $auth->setConfig(array('mode' => $this->mode, 'http.headers.PayPal-Partner-Attribution-Id' => 'AngellEYE_SP_WooCommerce', 'log.LogEnabled' => true, 'log.LogLevel' => 'DEBUG', 'log.FileName' => wc_get_log_file_path('paypal_credit_card_rest'))); 
  262. return $auth; 
  263.  
  264. /** 
  265. * @since 1.2 
  266. * @param type $order 
  267. * @param type $card_data 
  268. */ 
  269. public function set_card_details($order, $card_data) { 
  270. $this->set_card_type($card_data); 
  271. $this->set_card_number($card_data); 
  272. $this->set_card_expire_month($card_data); 
  273. $this->set_card_expire_year($card_data); 
  274. $this->set_card_cvv($card_data); 
  275. $this->set_card_first_name($order); 
  276. $this->set_card_set_last_name($order); 
  277.  
  278. /** 
  279. * @since 1.2 
  280. * @param type $card_data 
  281. */ 
  282. public function set_card_type($card_data) { 
  283. $first_four = substr($card_data->number, 0, 4); 
  284. $card_type = AngellEYE_Utility::card_type_from_account_number($first_four); 
  285. $this->card->setType($card_type); 
  286.  
  287. /** 
  288. * @since 1.2 
  289. * @param type $card_data 
  290. */ 
  291. public function set_card_number($card_data) { 
  292. $this->card->setNumber($card_data->number); 
  293.  
  294. /** 
  295. * @since 1.2 
  296. * @param type $card_data 
  297. */ 
  298. public function set_card_expire_month($card_data) { 
  299. $this->card->setExpireMonth($card_data->exp_month); 
  300.  
  301. /** 
  302. * @since 1.2 
  303. * @param type $card_data 
  304. */ 
  305. public function set_card_expire_year($card_data) { 
  306. $this->card->setExpireYear($card_data->exp_year); 
  307.  
  308. /** 
  309. * @since 1.2 
  310. * @param type $card_data 
  311. */ 
  312. public function set_card_cvv($card_data) { 
  313. $this->card->setCvv2($card_data->cvc); 
  314.  
  315. /** 
  316. * @since 1.2 
  317. * @param type $order 
  318. */ 
  319. public function set_card_first_name($order) { 
  320. $this->card->setFirstName(version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_first_name : $order->get_billing_first_name()); 
  321.  
  322. /** 
  323. * @since 1.2 
  324. * @param type $order 
  325. */ 
  326. public function set_card_set_last_name($order) { 
  327. $this->card->setLastName(version_compare( WC_VERSION, '3.0', '<' ) ? $order->billing_last_name : $order->get_billing_last_name()); 
  328.  
  329. /** 
  330. * @since 1.2 
  331. */ 
  332. public function create_transaction_method_obj() { 
  333.  
  334. $this->card = new CreditCard(); 
  335. $this->order_item = array(); 
  336. $this->send_items = true; 
  337.  
  338. /** 
  339. * @since 1.2 
  340. * @return type 
  341. */ 
  342. public function add_paypal_rest_api_lib() { 
  343. if (!class_exists('WC_Payment_Gateway')) { 
  344. return; 
  345. if (!class_exists('Angelleye_PayPal')) { 
  346. //require_once( PAYPAL_FOR_WOOCOMMERCE_PLUGIN_DIR . '/classes/lib/autoload.php' ); 
  347. require_once( PAYPAL_FOR_WOOCOMMERCE_PLUGIN_DIR . '/classes/lib/autoload.php' ); 
  348.  
  349. /** 
  350. * @since 1.2 
  351. * @param type $message 
  352. */ 
  353. public function add_log($message) { 
  354. if ($this->debug == 'yes' && $this->mode == 'LIVE') { 
  355. if (empty($this->log)) { 
  356. $this->log = new WC_Logger(); 
  357. $this->log->add('paypal_credit_card_rest', $message); 
  358.  
  359. /** 
  360. * @since 1.2 
  361. * @return type 
  362. */ 
  363. public function get_posted_card() { 
  364. $card_number = isset($_POST['paypal_credit_card_rest-card-number']) ? wc_clean($_POST['paypal_credit_card_rest-card-number']) : ''; 
  365. $card_cvc = isset($_POST['paypal_credit_card_rest-card-cvc']) ? wc_clean($_POST['paypal_credit_card_rest-card-cvc']) : ''; 
  366. $card_expiry = isset($_POST['paypal_credit_card_rest-card-expiry']) ? wc_clean($_POST['paypal_credit_card_rest-card-expiry']) : ''; 
  367. $card_number = str_replace(array(' ', '-'), '', $card_number); 
  368. $card_expiry = array_map('trim', explode('/', $card_expiry)); 
  369. $card_exp_month = str_pad($card_expiry[0], 2, "0", STR_PAD_LEFT); 
  370. $card_exp_year = isset($card_expiry[1]) ? $card_expiry[1] : ''; 
  371. if (strlen($card_exp_year) == 2) { 
  372. $card_exp_year += 2000; 
  373. return (object) array( 
  374. 'number' => $card_number,  
  375. 'type' => '',  
  376. 'cvc' => $card_cvc,  
  377. 'exp_month' => $card_exp_month,  
  378. 'exp_year' => $card_exp_year,  
  379. ); 
  380.  
  381. /** 
  382. * @since 1.2 
  383. */ 
  384. public function add_dependencies_admin_notices() { 
  385. $missing_extensions = $this->get_missing_dependencies(); 
  386. if (count($missing_extensions) > 0) { 
  387. $message = sprintf( 
  388. _n( 
  389. '%s requires the %s PHP extension to function. Contact your host or server administrator to configure and install the missing extension.', '%s requires the following PHP extensions to function: %s. Contact your host or server administrator to configure and install the missing extensions.', count($missing_extensions), 'paypal-for-woocommerce' 
  390. ), "PayPal Credit Card (REST)", '<strong>' . implode(', ', $missing_extensions) . '</strong>' 
  391. ); 
  392. echo '<div class="error"><p>' . $message . '</p></div>'; 
  393.  
  394. /** 
  395. * @since 1.2 
  396. * @return type 
  397. */ 
  398. public function get_missing_dependencies() { 
  399. $missing_extensions = array(); 
  400. foreach ($this->get_dependencies() as $ext) { 
  401. if (!extension_loaded($ext)) { 
  402. $missing_extensions[] = $ext; 
  403. return $missing_extensions; 
  404.  
  405. /** 
  406. * @since 1.2 
  407. * @return type 
  408. */ 
  409. public function get_dependencies() { 
  410. return array('curl', 'json', 'openssl'); 
  411.  
  412. /** 
  413. * @since 1.2 
  414. * @param type $order_id 
  415. * @param type $amount 
  416. * @param type $reason 
  417. * @return \WP_Error|boolean 
  418. */ 
  419. public function payment_Refund($order_id, $amount = null, $reason = '') { 
  420. $order = wc_get_order($order_id); 
  421. $this->add_log('Begin Refund'); 
  422. $this->add_log('Order: ' . print_r($order, true)); 
  423. $this->add_log('Transaction ID: ' . print_r($order->get_transaction_id(), true)); 
  424. if (!$order || !$order->get_transaction_id() || !$this->rest_client_id || !$this->rest_secret_id) { 
  425. return false; 
  426. if ($reason) { 
  427. if (255 < strlen($reason)) { 
  428. $reason = substr($reason, 0, 252) . '...'; 
  429.  
  430. $reason = html_entity_decode($reason, ENT_NOQUOTES, 'UTF-8'); 
  431. $sale = Sale::get($order->get_transaction_id(), $this->getAuth()); 
  432. $this->amount = new Amount(); 
  433. $this->amount->setCurrency(version_compare(WC_VERSION, '3.0', '<') ? $order->get_order_currency() : $order->get_currency()); 
  434. $this->amount->setTotal($this->number_format($amount, $order)); 
  435. $refund = new Refund(); 
  436. $refund->setAmount($this->amount); 
  437. try { 
  438. $this->add_log('Refund Request: ' . print_r($refund, true)); 
  439. $refundedSale = $sale->refund($refund, $this->getAuth()); 
  440. if ($refundedSale->state == 'completed') { 
  441. $order->add_order_note('Refund Transaction ID:' . $refundedSale->getId()); 
  442. if (isset($reason) && !empty($reason)) { 
  443. $order->add_order_note('Reason for Refund :' . $reason); 
  444. $max_remaining_refund = wc_format_decimal($order->get_total() - $order->get_total_refunded()); 
  445. if (!$max_remaining_refund > 0) { 
  446. $order->update_status('refunded'); 
  447. return true; 
  448. } catch (PayPal\Exception\PayPalConnectionException $ex) { 
  449. $this->add_log($ex->getData()); 
  450. $error_data = json_decode($ex->getData()); 
  451. if (is_object($error_data) && !empty($error_data)) { 
  452. $error_message = ($error_data->message) ? $error_data->message : $error_data->information_link; 
  453. return new WP_Error('paypal_credit_card_rest_refund-error', $error_message); 
  454. } else { 
  455. return new WP_Error('paypal_credit_card_rest_refund-error', $ex->getData()); 
  456. } catch (Exception $ex) { 
  457. $this->add_log($ex->getMessage()); 
  458. return new WP_Error('paypal_credit_card_rest_refund-error', $ex->getMessage()); 
  459.  
  460. /** 
  461. * @since 1.2 
  462. * @param type $currency 
  463. * @return boolean 
  464. */ 
  465. public function currency_has_decimals($currency) { 
  466. if (in_array($currency, array('HUF', 'JPY', 'TWD'))) { 
  467. return false; 
  468. return true; 
  469.  
  470. /** 
  471. * @since 1.2 
  472. * @param type $price 
  473. * @param type $order 
  474. * @return type 
  475. */ 
  476. public function round($price, $order) { 
  477. $precision = 2; 
  478. if (!$this->currency_has_decimals(version_compare(WC_VERSION, '3.0', '<') ? $order->get_order_currency() : $order->get_currency())) { 
  479. $precision = 0; 
  480. return round($price, $precision); 
  481.  
  482. /** 
  483. * @since 1.2 
  484. * @param type $price 
  485. * @param type $order 
  486. * @return type 
  487. */ 
  488. public function number_format($price, $order) { 
  489. $decimals = 2; 
  490. if (!$this->currency_has_decimals(version_compare(WC_VERSION, '3.0', '<') ? $order->get_order_currency() : $order->get_currency())) { 
  491. $decimals = 0; 
  492. return number_format($price, $decimals, '.', ''); 
  493.  
  494. public function save_credit_card($card_data) { 
  495. $customer_id = get_current_user_id(); 
  496. $this->card = new CreditCard(); 
  497. $this->set_card_type($card_data); 
  498. $this->set_card_number($card_data); 
  499. $this->set_card_expire_month($card_data); 
  500. $this->set_card_expire_year($card_data); 
  501. $this->set_card_cvv($card_data); 
  502.  
  503. $billtofirstname = (get_user_meta($customer_id, 'billing_first_name', true)) ? get_user_meta($customer_id, 'billing_first_name', true) : get_user_meta($customer_id, 'shipping_first_name', true); 
  504. $billtolastname = (get_user_meta($customer_id, 'billing_last_name', true)) ? get_user_meta($customer_id, 'billing_last_name', true) : get_user_meta($customer_id, 'shipping_last_name', true); 
  505.  
  506. $this->card->setFirstName($billtofirstname); 
  507. $this->card->setLastName($billtolastname); 
  508. $this->card->setMerchantId(get_bloginfo('name') . '_' . $customer_id . '_' . uniqid()); 
  509. $this->card->setExternalCardId($card_data->number . '_' . uniqid()); 
  510. $this->card->setExternalCustomerId($card_data->number . '_' . $customer_id . '_' . uniqid()); 
  511.  
  512. try { 
  513. $this->card->create($this->getAuth()); 
  514. if ($this->card->state == 'ok') { 
  515. $customer_id = get_current_user_id(); 
  516. $creditcard_id = $this->card->getId(); 
  517. $token = new WC_Payment_Token_CC(); 
  518. $token->set_user_id( $customer_id ); 
  519. $token->set_token( $creditcard_id ); 
  520. $token->set_gateway_id( $this->payment_method ); 
  521. $token->set_card_type( $this->card->type ); 
  522. $token->set_last4( substr( $this->card->number, -4 ) ); 
  523. $token->set_expiry_month( $this->card->expire_month ); 
  524. $token->set_expiry_year( $this->card->expire_year ); 
  525. $save_result = $token->save(); 
  526. if ($save_result) { 
  527. return array( 
  528. 'result' => 'success',  
  529. 'redirect' => wc_get_account_endpoint_url('payment-methods') 
  530. ); 
  531. } else { 
  532. wc_add_notice(__("Error processing checkout. Please try again. ", 'paypal-for-woocommerce'), 'error'); 
  533. return array( 
  534. 'result' => 'fail',  
  535. 'redirect' => wc_get_account_endpoint_url('payment-methods') 
  536. ); 
  537. } catch (Exception $ex) { 
  538. wc_add_notice(__("Error processing checkout. Please try again. ", 'paypal-for-woocommerce'), 'error'); 
  539. $this->add_log($ex->getMessage()); 
  540. return array( 
  541. 'result' => 'fail',  
  542. 'redirect' => '' 
  543. ); 
  544.  
  545. function is_subscription($order_id) { 
  546. return ( function_exists('wcs_order_contains_subscription') && ( wcs_order_contains_subscription($order_id) || wcs_is_subscription($order_id) || wcs_order_contains_renewal($order_id) ) ); 
  547.  
  548. public function save_payment_token($order, $payment_tokens_id) { 
  549. // Store source in the order 
  550. $order_id = version_compare(WC_VERSION, '3.0', '<') ? $order->id : $order->get_id(); 
  551. if (!empty($payment_tokens_id)) { 
  552. update_post_meta($order_id, '_payment_tokens_id', $payment_tokens_id); 
  553. if (function_exists('wcs_order_contains_subscription') && wcs_order_contains_subscription($order_id)) { 
  554. $subscriptions = wcs_get_subscriptions_for_order($order_id); 
  555. } elseif (function_exists('wcs_order_contains_renewal') && wcs_order_contains_renewal($order_id)) { 
  556. $subscriptions = wcs_get_subscriptions_for_renewal_order($order_id); 
  557. } else { 
  558. $subscriptions = array(); 
  559. if (!empty($subscriptions)) { 
  560. foreach ($subscriptions as $subscription) { 
  561. update_post_meta($subscription->id, '_payment_tokens_id', $payment_tokens_id); 
  562.  
  563. public function create_payment_with_zero_amount($order, $card_data) { 
  564. global $woocommerce; 
  565. $order_id = version_compare(WC_VERSION, '3.0', '<') ? $order->id : $order->get_id(); 
  566. try { 
  567. $this->set_trnsaction_obj_value($order, $card_data); 
  568. try { 
  569. if (!empty($_POST['wc-paypal_credit_card_rest-payment-token']) && $_POST['wc-paypal_credit_card_rest-payment-token'] != 'new') { 
  570. $creditcard_id = $this->CreditCardToken->getCreditCardId(); 
  571. $this->save_payment_token($order, $creditcard_id); 
  572. $token_id = wc_clean($_POST['wc-paypal_credit_card_rest-payment-token']); 
  573. $token = WC_Payment_Tokens::get($token_id); 
  574. $order->add_payment_token($token); 
  575. } else { 
  576. $this->card->create($this->getAuth()); 
  577. $customer_id = $order->get_user_id(); 
  578. $creditcard_id = $this->card->getId(); 
  579. $this->save_payment_token($order, $creditcard_id); 
  580. $token = new WC_Payment_Token_CC(); 
  581. $token->set_user_id($customer_id); 
  582. $token->set_token($creditcard_id); 
  583. $token->set_gateway_id($this->payment_method); 
  584. $token->set_card_type($this->card->type); 
  585. $token->set_last4(substr($this->card->number, -4)); 
  586. $token->set_expiry_month(date('m')); 
  587. $token->set_expiry_year(date('Y', strtotime($this->card->valid_until))); 
  588. $save_result = $token->save(); 
  589. if ($save_result) { 
  590. $order->add_payment_token($token); 
  591. } catch (Exception $ex) { 
  592.  
  593. $order->payment_complete($creditcard_id); 
  594. $is_sandbox = $this->mode == 'SANDBOX' ? true : false; 
  595. update_post_meta($order_id, 'is_sandbox', $is_sandbox); 
  596. if (!empty($order->subscription_renewal)) { 
  597. return true; 
  598. WC()->cart->empty_cart(); 
  599. $return_url = $order->get_checkout_order_received_url(); 
  600. if (is_ajax()) { 
  601. wp_send_json(array( 
  602. 'result' => 'success',  
  603. 'redirect' => apply_filters('woocommerce_checkout_no_payment_needed_redirect', $return_url, $order) 
  604. )); 
  605. } else { 
  606. wp_safe_redirect( 
  607. apply_filters('woocommerce_checkout_no_payment_needed_redirect', $return_url, $order) 
  608. ); 
  609. exit; 
  610. } catch (PayPal\Exception\PayPalConnectionException $ex) { 
  611. $this->send_failed_order_email($order_id); 
  612. $this->add_log($ex->getData()); 
  613. if (!empty($order->subscription_renewal)) { 
  614. return true; 
  615. wc_add_notice(__("Error processing checkout. Please try again. ", 'paypal-for-woocommerce'), 'error'); 
  616. return array( 
  617. 'result' => 'fail',  
  618. 'redirect' => '' 
  619. ); 
  620. exit; 
  621. } catch (Exception $ex) { 
  622. $this->send_failed_order_email($order_id); 
  623. $this->add_log($ex->getMessage()); 
  624. if (!empty($order->subscription_renewal)) { 
  625. return true; 
  626. wc_add_notice(__("Error processing checkout. Please try again. ", 'paypal-for-woocommerce'), 'error'); 
  627.  
  628. return array( 
  629. 'result' => 'fail',  
  630. 'redirect' => '' 
  631. ); 
  632.  
  633. public function send_failed_order_email($order_id) { 
  634. $emails = WC()->mailer()->get_emails(); 
  635. if (!empty($emails) && !empty($order_id)) { 
  636. $emails['WC_Email_Failed_Order']->trigger($order_id); 
  637.