PageRenderTime 61ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/www/wp-content/plugins/ithemes-exchange/api/transactions.php

https://github.com/ArzuA/gitwordpress
PHP | 1187 lines | 499 code | 157 blank | 531 comment | 89 complexity | 425103db9a7f1e838416bea4ccf83752 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. <?php
  2. /**
  3. * API Functions for Transaction Method Add-ons
  4. *
  5. * In addition to the functions found below, iThemes Exchange offers the following actions related to transactions
  6. * - it_exchange_save_transaction_unvalidated // Runs every time a transaction is saved.
  7. * - it_exchange_save_transaction_unavalidated-[txn-method] // Runs every time a specific transaction method is saved.
  8. * - it_exchange_save_transaction // Runs every time a transaction is saved if not an autosave and if user has permission to save post
  9. * - it_exchange_save_transaction-[txn-method] // Runs every time a specific transaction method is saved if not an autosave and if user has permission to save transaction
  10. *
  11. * @package IT_Exchange
  12. * @since 0.3.3
  13. */
  14. /**
  15. * Grabs the transaction method of a transaction
  16. *
  17. * @since 0.3.3
  18. * @param mixed Transaction ID or IT_Exchange_Transaction object
  19. * @return string the transaction method
  20. */
  21. function it_exchange_get_transaction_method( $transaction=false ) {
  22. if ( is_object( $transaction ) && 'IT_Exchange_Transaction' == get_class( $transaction ) )
  23. return $transaction->transaction_method;
  24. if ( ! $transaction ) {
  25. global $post;
  26. $transaction = $post;
  27. }
  28. // Return value from IT_Exchange_Transaction if we are able to locate it
  29. $transaction = it_exchange_get_transaction( $transaction );
  30. if ( is_object( $transaction ) && ! empty ( $transaction->transaction_method ) && ! is_null( $transaction->transaction_method ) )
  31. return apply_filters( 'it_exchange_get_transaction_method', $transaction->transaction_method, $transaction );
  32. // Return query arg if is present
  33. if ( ! empty ( $_GET['transaction-method'] ) )
  34. return apply_filters( 'it_exchange_get_transaction_method', $_GET['transaction-method'], $transaction );
  35. return apply_filters( 'it_exchange_get_transaction_method', false, $transaction );
  36. }
  37. /**
  38. * Retreives a transaction object by passing it the WP post object or post id
  39. *
  40. * @since 0.3.3
  41. * @param mixed $post post object or post id
  42. * @rturn object IT_Exchange_Transaction object for passed post
  43. */
  44. function it_exchange_get_transaction( $post ) {
  45. if ( is_object( $post ) && 'IT_Exchange_Transaction' == get_class( $post ) )
  46. return apply_filters( 'it_exchange_get_transaction', $post );
  47. return apply_filters( 'it_exchange_get_transaction', new IT_Exchange_Transaction( $post ) );
  48. }
  49. /**
  50. * Get IT_Exchange_Transactions
  51. *
  52. * @since 0.3.3
  53. * @return array an array of IT_Exchange_Transaction objects
  54. */
  55. function it_exchange_get_transactions( $args=array() ) {
  56. $defaults = array(
  57. 'post_type' => 'it_exchange_tran',
  58. );
  59. // Different defaults depending on where we are.
  60. $confirmation_slug = it_exchange_get_page_slug( 'confirmation' );
  61. if ( it_exchange_is_page( 'confirmation' ) ) {
  62. if ( $transaction_hash = get_query_var( $confirmation_slug ) ) {
  63. if ( $transaction_id = it_exchange_get_transaction_id_from_hash( $transaction_hash ) )
  64. $defaults['p'] = $transaction_id;
  65. }
  66. if ( empty( $transaction_id ) )
  67. return array();
  68. }
  69. $args = wp_parse_args( $args, $defaults );
  70. $args['meta_query'] = empty( $args['meta_query'] ) ? array() : $args['meta_query'];
  71. // Fold in transaction_method
  72. if ( ! empty( $args['transaction_method'] ) ) {
  73. $meta_query = array(
  74. 'key' => '_it_exchange_transaction_method',
  75. 'value' => $args['transaction_method'],
  76. );
  77. $args['meta_query'][] = $meta_query;
  78. }
  79. // Fold in transaction_status
  80. if ( ! empty( $args['transaction_status'] ) ) {
  81. $meta_query = array(
  82. 'key' => '_it_exchange_transaction_status',
  83. 'value' => $args['transaction_status'],
  84. );
  85. $args['meta_query'][] = $meta_query;
  86. }
  87. // Fold in customer
  88. if ( ! empty( $args['customer_id'] ) ) {
  89. $meta_query = array(
  90. 'key' => '_it_exchange_customer_id',
  91. 'value' => $args['customer_id'],
  92. 'type' => 'NUMERIC',
  93. );
  94. $args['meta_query'][] = $meta_query;
  95. }
  96. $args = apply_filters( 'it_exchange_get_transactions_get_posts_args', $args );
  97. if ( $transactions = get_posts( $args ) ) {
  98. foreach( $transactions as $key => $transaction ) {
  99. $transactions[$key] = it_exchange_get_transaction( $transaction );
  100. }
  101. }
  102. return apply_filters( 'it_exchange_get_transactions', $transactions, $args );
  103. }
  104. /**
  105. * Generates the transaction object used by the transaction methods
  106. *
  107. * @since 0.4.20
  108. * @return object Transaction object
  109. */
  110. function it_exchange_generate_transaction_object() {
  111. // Verify products exist
  112. $products = it_exchange_get_cart_products();
  113. if ( count( $products ) < 1 ) {
  114. do_action( 'it_exchange_error-no_products_to_purchase' );
  115. it_exchange_add_message( 'error', __( 'You cannot checkout without any items in your cart.', 'it-l10n-ithemes-exchange' ) );
  116. return false;
  117. }
  118. // Verify cart total is a positive number
  119. $cart_total = number_format( it_exchange_get_cart_total( false ), 2, '.', '' );
  120. if ( number_format( $cart_total, 2, '', '' ) < 0 ) {
  121. do_action( 'it_exchange_error_negative_cart_total_on_checkout', $cart_total );
  122. it_exchange_add_message( 'error', __( 'The cart total must be greater than 0 for you to checkout. Please try again.', 'it-l10n-ithemes-exchange' ) );
  123. return false;
  124. }
  125. // Grab default currency
  126. $settings = it_exchange_get_option( 'settings_general' );
  127. $currency = $settings['default-currency'];
  128. unset( $settings );
  129. // Add totals to each product
  130. foreach( $products as $key => $product ) {
  131. $products[$key]['product_base_price'] = it_exchange_get_cart_product_base_price( $product, false );
  132. $products[$key]['product_subtotal'] = it_exchange_get_cart_product_subtotal( $product, false );
  133. $products[$key]['product_name'] = it_exchange_get_cart_product_title( $product );
  134. $products = apply_filters( 'it_exchange_generate_transaction_object_products', $products, $key, $product );
  135. }
  136. // Package it up and send it to the transaction method add-on
  137. $transaction_object = new stdClass();
  138. $transaction_object->total = $cart_total;
  139. $transaction_object->currency = $currency;
  140. $transaction_object->description = it_exchange_get_cart_description();
  141. $transaction_object->products = $products;
  142. $transaction_object->coupons = it_exchange_get_applied_coupons();
  143. $transaction_object->coupons_total_discount = it_exchange_get_total_coupons_discount( 'cart', array( 'format_price' => false ));
  144. // Tack on Shipping and Billing address
  145. $transaction_object->shipping_address = it_exchange_get_cart_shipping_address();
  146. $transaction_object->billing_address = apply_filters( 'it_exchange_billing_address_purchase_requirement_enabled', false ) ? it_exchange_get_cart_billing_address() : false;
  147. // Shipping Method and total
  148. $transaction_object->shipping_method = it_exchange_get_cart_shipping_method();
  149. $transaction_object->shipping_method_multi = it_exchange_get_cart_data( 'multiple-shipping-methods' );
  150. $transaction_object->shipping_total = it_exchange_convert_to_database_number( it_exchange_get_cart_shipping_cost( false, false ) );
  151. $transaction_object = apply_filters( 'it_exchange_generate_transaction_object', $transaction_object );
  152. return $transaction_object;
  153. }
  154. /**
  155. * Add a transient transaction, default expiry set to 24 hours
  156. *
  157. * @since 0.4.20
  158. * @param string $method name of method that created the transient
  159. * @param string $temp_id temporary transaction ID created by the transient
  160. * @param int $customer_id ID of current customer
  161. * @param object $transaction_object Object used to pass to transaction methods
  162. * @return bool true or false depending on success
  163. */
  164. function it_exchange_add_transient_transaction( $method, $temp_id, $customer_id = false, $transaction_object ) {
  165. return set_transient( $method . '-' . $temp_id, array( 'customer_id' => $customer_id, 'transaction_object' => $transaction_object ), apply_filters( 'it_exchange_transient_transaction_expiry', 60 * 60 * 24 ) );
  166. }
  167. /**
  168. * Gets a transient transaction
  169. *
  170. * @since 0.4.20
  171. * @param string $method name of method that created the transient
  172. * @param string $temp_id temporary transaction ID created by the transient
  173. * @return array of customer_id and transaction_object
  174. */
  175. function it_exchange_get_transient_transaction( $method, $temp_id ) {
  176. return get_transient( $method . '-' . $temp_id );
  177. }
  178. /**
  179. * Deletes a transient transaction
  180. *
  181. * @since 0.4.20
  182. * @param string $method name of method that created the transient
  183. * @param string $temp_id temporary transaction ID created by the transient
  184. * @return bool true or false depending on success
  185. */
  186. function it_exchange_delete_transient_transaction( $method, $temp_id ) {
  187. return delete_transient( $method . '-' . $temp_id );
  188. }
  189. /**
  190. * Adds a transaction post_type to WP
  191. *
  192. * @since 0.3.3
  193. * @param string $method Transaction method (e.g. paypal, stripe, etc)
  194. * @param string $method_id ID from transaction method
  195. * @param string $status Transaction status
  196. * @param int $customer_id Customer ID
  197. * @param object $cart_object passed cart object
  198. * @param array $args same args passed to wp_insert_post plus any additional needed
  199. * @return mixed post id or false
  200. */
  201. function it_exchange_add_transaction( $method, $method_id, $status = 'pending', $customer_id = false, $cart_object, $args = array() ) {
  202. $defaults = array(
  203. 'post_type' => 'it_exchange_tran',
  204. 'post_status' => 'publish',
  205. );
  206. $args = wp_parse_args( $args, $defaults );
  207. if ( !$customer_id )
  208. $customer_id = it_exchange_get_current_customer_id();
  209. $customer = new IT_Exchange_Customer( $customer_id );
  210. // If we don't have a title, create one
  211. if ( empty( $args['post_title'] ) )
  212. $args['post_title'] = $method . '-' . $method_id . '-' . date_i18n( 'Y-m-d-H:i:s' );
  213. if ( $subscription_details = it_exchange_get_session_data( 'cancel_subscription' ) ) {
  214. foreach( $subscription_details as $cancel_subscription ) {
  215. if ( !empty( $cancel_subscription['old_transaction_method'] ) )
  216. do_action( 'it_exchange_cancel_' . $cancel_subscription['old_transaction_method'] . '_subscription', $cancel_subscription );
  217. }
  218. } else {
  219. it_exchange_clear_session_data( 'cancel_subscription' ); // just in case, we don't want any lingering
  220. }
  221. if ( $transaction_id = wp_insert_post( $args ) ) {
  222. update_post_meta( $transaction_id, '_it_exchange_transaction_method', $method );
  223. update_post_meta( $transaction_id, '_it_exchange_transaction_method_id', $method_id );
  224. update_post_meta( $transaction_id, '_it_exchange_transaction_status', $status );
  225. update_post_meta( $transaction_id, '_it_exchange_customer_id', $customer_id );
  226. update_post_meta( $transaction_id, '_it_exchange_cart_object', $cart_object );
  227. // Transaction Hash for confirmation lookup
  228. update_post_meta( $transaction_id, '_it_exchange_transaction_hash', it_exchange_generate_transaction_hash( $transaction_id, $customer_id ) );
  229. do_action( 'it_exchange_add_transaction_success', $transaction_id );
  230. if ( $products = it_exchange_get_transaction_products( $transaction_id ) ) {
  231. // Loop through products
  232. foreach( $products as $cart_id => $data ) {
  233. $product = new IT_Exchange_Product( $data['product_id'] );
  234. $product->add_transaction_to_product( $transaction_id );
  235. }
  236. }
  237. $customer->add_transaction_to_user( $transaction_id );
  238. return apply_filters( 'it_exchange_add_transaction', $transaction_id, $method, $method_id, $status, $customer_id, $cart_object, $args );
  239. }
  240. do_action( 'it_exchange_add_transaction_failed', $method, $method_id, $status, $customer_id, $cart_object, $args );
  241. return apply_filters( 'it_exchange_add_transaction', false, $method, $method_id, $status, $customer_id, $cart_object, $args);
  242. }
  243. /**
  244. * Adds a transaction post_type to WP
  245. * Slimmed down "child" of a parent transaction
  246. *
  247. * @since 1.3.0
  248. * @param string $method Transaction method (e.g. paypal, stripe, etc)
  249. * @param string $method_id ID from transaction method
  250. * @param string $status Transaction status
  251. * @param int $customer_id Customer ID
  252. * @param int $parent_tx_id Parent Transaction ID
  253. * @param object $cart_object really just a dummy array to store the price information
  254. * @param array $args same args passed to wp_insert_post plus any additional needed
  255. * @return mixed post id or false
  256. */
  257. function it_exchange_add_child_transaction( $method, $method_id, $status = 'pending', $customer_id, $parent_tx_id, $cart_object, $args = array() ) {
  258. $defaults = array(
  259. 'post_type' => 'it_exchange_tran',
  260. 'post_status' => 'publish',
  261. );
  262. $args = wp_parse_args( $args, $defaults );
  263. // If we don't have a title, create one
  264. if ( empty( $args['post_title'] ) )
  265. $args['post_title'] = $method . '-' . $method_id . '-' . date_i18n( 'Y-m-d-H:i:s' );
  266. $args['post_parent'] = $parent_tx_id;
  267. if ( $transaction_id = wp_insert_post( $args ) ) {
  268. update_post_meta( $transaction_id, '_it_exchange_transaction_method', $method );
  269. update_post_meta( $transaction_id, '_it_exchange_transaction_method_id', $method_id );
  270. update_post_meta( $transaction_id, '_it_exchange_transaction_status', $status );
  271. update_post_meta( $transaction_id, '_it_exchange_customer_id', $customer_id );
  272. update_post_meta( $transaction_id, '_it_exchange_parent_tx_id', $parent_tx_id );
  273. update_post_meta( $transaction_id, '_it_exchange_cart_object', $cart_object );
  274. do_action( 'it_exchange_add_child_transaction_success', $transaction_id );
  275. return apply_filters( 'it_exchange_add_child_transaction', $transaction_id, $method, $method_id, $status, $customer_id, $parent_tx_id, $cart_object, $args );
  276. }
  277. do_action( 'it_exchange_add_child_transaction_failed', $method, $method_id, $status, $customer_id, $parent_tx_id, $cart_object, $args );
  278. return apply_filters( 'it_exchange_add_child_transaction', false, $method, $method_id, $status, $customer_id, $parent_tx_id, $cart_object, $args );
  279. }
  280. /**
  281. * Generates a unique transaction ID for receipts
  282. *
  283. * @since 0.4.0
  284. *
  285. * @param integer $transaction_id the wp_post ID for the transaction
  286. * @param interger $user_id the wp_users ID for the customer
  287. * @return string
  288. */
  289. function it_exchange_generate_transaction_hash( $transaction_id, $customer_id ) {
  290. // Targeted hash
  291. $hash = wp_hash( time() . $transaction_id . $customer_id );
  292. if ( it_exchange_get_transaction_id_from_hash( $hash ) )
  293. $hash = it_exchange_generate_transaction_hash( $transaction_id, $customer_id );
  294. return apply_filters( 'it_exchange_generate_transaction_hash', $hash, $transaction_id, $customer_id );
  295. }
  296. /**
  297. * Return the transaction ID provided by the gateway (transaction method)
  298. *
  299. * @since 0.4.0
  300. *
  301. * @param mixed $transaction ID or object
  302. * @return mixed
  303. */
  304. function it_exchange_get_gateway_id_for_transaction( $transaction ) {
  305. if ( ! $transaction = it_exchange_get_transaction( $transaction ) )
  306. return;
  307. $gateway_transaction_id = $transaction->get_gateway_id_for_transaction();
  308. return apply_filters( 'it_exchange_get_gateway_id_for_transaction', $gateway_transaction_id, $transaction );
  309. }
  310. /**
  311. * Returns a transaction ID based on the hash
  312. *
  313. * @since 0.4.0
  314. *
  315. * @param string $hash
  316. * @return integer transaction id
  317. */
  318. function it_exchange_get_transaction_id_from_hash( $hash ) {
  319. global $wpdb;
  320. if ( $transaction_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key = %s AND meta_value = %s LIMIT 1;", '_it_exchange_transaction_hash', $hash ) ) )
  321. return apply_filters( 'it_exchange_get_transaction_id_from_hash', $transaction_id, $hash );
  322. return apply_filters( 'it_exchange_get_transaction_id_from_hash', false, $hash );
  323. }
  324. /**
  325. * Returns the transaction hash from an ID
  326. *
  327. * @since 0.4.0
  328. *
  329. * @param integer $id transaction_id
  330. * @return mixed ID or false
  331. */
  332. function it_exchange_get_transaction_hash( $id ) {
  333. return apply_filters( 'it_exchange_get_transaction_hash', get_post_meta( $id, '_it_exchange_transaction_hash', true ), $id );
  334. }
  335. /**
  336. * Updates a transaction
  337. *
  338. * @since 0.3.3
  339. * @param array transaction args. Must include ID of a valid transaction post
  340. * @return object transaction object
  341. */
  342. function it_exchange_update_transaction( $args ) {
  343. $id = empty( $args['id'] ) ? false : $args['id'];
  344. $id = ( empty( $id ) && ! empty( $args['ID'] ) ) ? $args['ID']: $id;
  345. if ( 'it_exchange_tran' != get_post_type( $id ) )
  346. return false;
  347. $args['ID'] = $id;
  348. $result = wp_update_post( $args );
  349. $transaction_method = it_exchange_get_transaction_method( $id );
  350. do_action( 'it_exchange_update_transaction', $args );
  351. do_action( 'it_exchange_update_transaction_' . $transaction_method, $args );
  352. if ( ! empty( $args['_it_exchange_transaction_status'] ) )
  353. it_exchange_update_transaction_status( $id, $args['_it_exchange_transaction_status'] );
  354. return $result;
  355. }
  356. /**
  357. * Updates the transaction status of a transaction
  358. *
  359. * @since 0.3.3
  360. * @param mixed $transaction the transaction id or object
  361. * @param string $status the new transaction status
  362. */
  363. function it_exchange_update_transaction_status( $transaction, $status ) {
  364. if ( is_object( $transaction ) && 'IT_Exchange_Transaction' != get_class( $transaction ) ) {
  365. $transaction = it_exchange_get_transaction( $transaction );
  366. }
  367. if ( ! $transaction->ID )
  368. return false;
  369. $old_status = $transaction->get_status();
  370. $old_status_cleared = it_exchange_transaction_is_cleared_for_delivery( $transaction );
  371. $transaction->update_status( $status );
  372. do_action( 'it_exchange_update_transaction_status', $transaction, $old_status, $old_status_cleared );
  373. do_action( 'it_exchange_update_transaction_status_' . $transaction->transaction_method, $transaction, $old_status, $old_status_cleared );
  374. return $transaction->get_status();
  375. }
  376. /**
  377. * Returns the transaction status for a specific transaction
  378. *
  379. * @since 0.3.3
  380. * @param mixed $transaction the transaction id or object
  381. * @return string the transaction status
  382. */
  383. function it_exchange_get_transaction_status( $transaction ) {
  384. $transaction = it_exchange_get_transaction( $transaction );
  385. $transaction_status = empty( $transaction->status ) ? false : $transaction->status;
  386. return apply_filters( 'it_exchange_get_transaction_status', $transaction_status, $transaction );
  387. }
  388. /**
  389. * Grab a list of all possible transactions stati
  390. *
  391. * @since 0.4.11
  392. *
  393. * @param mixed $transaction transaction id or object
  394. * @return array
  395. */
  396. function it_exchange_get_status_options_for_transaction( $transaction ) {
  397. if ( ! $method = it_exchange_get_transaction_method( $transaction ) )
  398. return array();
  399. return apply_filters( 'it_exchange_get_status_options_for_' . $method . '_transaction', array(), $transaction );
  400. }
  401. /**
  402. * Return the default transaction status for a transaction
  403. *
  404. * Leans on transaction methods to do the work
  405. *
  406. * @since 0.4.11
  407. *
  408. * @param mixed $transaction id or object
  409. * @return param
  410. */
  411. function it_exchange_get_default_transaction_status( $transaction ) {
  412. if ( $method = it_exchange_get_transaction_method( $transaction ) )
  413. return false;
  414. return apply_filters( 'it_exchange_get_default_transaction_status_for_' . $method, false );
  415. }
  416. /**
  417. * Returns the label for a transaction status (provided by addon)
  418. *
  419. * @since 0.4.0
  420. *
  421. * @param string $transaction_method the transaction method
  422. * @param array $options
  423. * @return string
  424. */
  425. function it_exchange_get_transaction_status_label( $transaction, $options=array() ){
  426. $transaction = it_exchange_get_transaction( $transaction );
  427. $defaults = array(
  428. 'status' => it_exchange_get_transaction_status( $transaction ),
  429. );
  430. $options = ITUtility::merge_defaults( $options, $defaults );
  431. return apply_filters( 'it_exchange_transaction_status_label_' . $transaction->transaction_method, $options['status'], $options );
  432. }
  433. /**
  434. * Returns the instructions for a transaction instructions (provided by addon)
  435. *
  436. * @since 0.4.0
  437. *
  438. * @param string $transaction_method the transaction method
  439. * @return string
  440. */
  441. function it_exchange_get_transaction_instructions( $transaction ){
  442. $transaction = it_exchange_get_transaction( $transaction );
  443. return apply_filters( 'it_exchange_transaction_instructions_' . $transaction->transaction_method, '' );
  444. }
  445. /**
  446. * Return the transaction date
  447. *
  448. * @since 0.4.0
  449. *
  450. * @param mixed $transaction ID or object
  451. * @param string $format php date format
  452. * @param boolean $gmt return the gmt date?
  453. * @return string date
  454. */
  455. function it_exchange_get_transaction_date( $transaction, $format=false, $gmt=false ) {
  456. $format = empty( $format ) ? get_option( 'date_format' ) : $format;
  457. // Try to locate the IT_Exchange_Transaction object from the var
  458. if ( $transaction = it_exchange_get_transaction( $transaction ) ) {
  459. if ( $date = $transaction->get_date() )
  460. return apply_filters( 'it_exchange_get_transaction_date', date_i18n( $format, strtotime( $date ), $gmt ), $transaction, $format, $gmt );
  461. }
  462. return apply_filters( 'it_exchange_get_transaction_date', false, $transaction, $format, $gmt );
  463. ;
  464. }
  465. /**
  466. * Return the transaction subtotal
  467. *
  468. * @since 0.4.0
  469. *
  470. * @param mixed $transaction ID or object
  471. * @param string $format php date format
  472. * @param boolean $gmt return the gmt date?
  473. * @return string date
  474. */
  475. function it_exchange_get_transaction_subtotal( $transaction, $format_currency=true ) {
  476. // Try to locate the IT_Exchange_Transaction object from the var
  477. if ( $transaction = it_exchange_get_transaction( $transaction ) ) {
  478. if ( $subtotal = $transaction->get_subtotal() ) {
  479. $subtotal = $format_currency ? it_exchange_format_price( $subtotal ) : $subtotal;
  480. return apply_filters( 'it_exchange_get_transaction_subtotal', $subtotal, $transaction, $format_currency );
  481. }
  482. }
  483. return apply_filters( 'it_exchange_get_transaction_subtotal', false, $transaction, $format_currency );
  484. }
  485. /**
  486. * Return the transaction total
  487. *
  488. * @since 0.4.0
  489. *
  490. * @param mixed $transaction ID or object
  491. * @param boolean $format format the price?
  492. * @param boolean $subtract_refunds if refunds are present, subtract the difference?
  493. * @return string date
  494. */
  495. function it_exchange_get_transaction_total( $transaction, $format_currency=true, $subtract_refunds=true ) {
  496. // Try to locate the IT_Exchange_Transaction object from the var
  497. if ( $transaction = it_exchange_get_transaction( $transaction ) ) {
  498. $total = $transaction->get_total( $subtract_refunds );
  499. $total = $format_currency ? it_exchange_format_price( $total ) : $total;
  500. return apply_filters( 'it_exchange_get_transaction_total', $total, $transaction, $format_currency, $subtract_refunds );
  501. }
  502. return apply_filters( 'it_exchange_get_transaction_total', false, $transaction, $format_currency, $subtract_refunds );
  503. }
  504. /**
  505. * Return the currency used in the transaction
  506. *
  507. * @since 0.4.0
  508. *
  509. * @param mixed $transaction ID or object
  510. * @return string date
  511. */
  512. function it_exchange_get_transaction_currency( $transaction ) {
  513. // Try to locate the IT_Exchange_Transaction object from the var
  514. if ( $transaction = it_exchange_get_transaction( $transaction ) )
  515. return apply_filters( 'it_exchange_get_transaction_currency', $transaction->get_currency(), $transaction );
  516. return apply_filters( 'it_exchange_get_transaction_currency', false, $transaction );
  517. }
  518. /**
  519. * Returns an array of all coupons applied to a given transaction
  520. *
  521. * @since 0.4.0
  522. *
  523. * @param mixed $transaction ID or object
  524. * @return string date
  525. */
  526. function it_exchange_get_transaction_coupons( $transaction ) {
  527. // Try to locate the IT_Exchange_Transaction object from the var
  528. if ( $transaction = it_exchange_get_transaction( $transaction ) )
  529. return apply_filters( 'it_exchange_get_transaction_coupons', $transaction->get_coupons(), $transaction );
  530. return apply_filters( 'it_exchange_get_transaction_coupons', false, $transaction );
  531. }
  532. /**
  533. * Return the total discount of all coupons applied to a given transaction
  534. *
  535. * @since 0.4.0
  536. *
  537. * @param mixed $transaction ID or object
  538. * @param bool $format Format the price
  539. * @return string date
  540. */
  541. function it_exchange_get_transaction_coupons_total_discount( $transaction, $format = true ) {
  542. if ( $transaction = it_exchange_get_transaction( $transaction ) ) {
  543. $total_discount = ( $format ) ? it_exchange_format_price( $transaction->get_coupons_total_discount() ) : $transaction->get_coupons_total_discount();
  544. return apply_filters( 'it_exchange_get_transaction_coupons_total_discount', $total_discount, $transaction, $format );
  545. }
  546. return apply_filters( 'it_exchange_get_transaction_coupons_total_discount', false, $transaction, $format );
  547. }
  548. /**
  549. * Adds a refund to a transaction
  550. *
  551. * @since 0.4.0
  552. *
  553. * @param string $method slug for transaction_method
  554. * @param mixed $options
  555. */
  556. function it_exchange_add_refund_to_transaction( $transaction, $amount, $date=false, $options=array() ) {
  557. if ( $transaction = it_exchange_get_transaction( $transaction ) )
  558. $transaction->add_refund( $amount, $date, $options );
  559. do_action( 'it_exchange_add_refund_to_transaction', $transaction, $amount, $date, $options );
  560. }
  561. /**
  562. * Grab refunds for a transaction
  563. *
  564. * @since 0.4.0
  565. *
  566. * @param mixed $transaction ID or object
  567. * @return array
  568. */
  569. function it_exchange_get_transaction_refunds( $transaction ) {
  570. if ( $transaction = it_exchange_get_transaction( $transaction ) )
  571. return apply_filters( 'it_exchange_get_transaction_refunds', $transaction->get_transaction_refunds(), $transaction );
  572. return apply_filters( 'it_exchange_get_transaction_refunds', false, $transaction );
  573. }
  574. /**
  575. * Checks if there are refunds for a transaction
  576. *
  577. * @since 0.4.0
  578. *
  579. * @param mixed $transaction ID or object
  580. * @return array
  581. */
  582. function it_exchange_has_transaction_refunds( $transaction ) {
  583. if ( $transaction = it_exchange_get_transaction( $transaction ) )
  584. return apply_filters( 'it_exchange_has_transaction_refunds', true, $transaction );
  585. return apply_filters( 'it_exchange_has_transaction_refunds', false, $transaction );
  586. }
  587. /**
  588. * Returns the a sum of all the applied refund amounts for this transaction
  589. *
  590. * @since 0.4.0
  591. *
  592. * @param mixed $transaction ID or object
  593. * @param bool $format Format the price
  594. * @return numeric
  595. */
  596. function it_exchange_get_transaction_refunds_total( $transaction, $format = true ) {
  597. $refunds = it_exchange_get_transaction_refunds( $transaction );
  598. $total_refund = 0;
  599. foreach ( $refunds as $refund ) {
  600. $total_refund += $refund['amount'];
  601. }
  602. $total_refund = ( $format ) ? it_exchange_format_price( $total_refund ) : $total_refund;
  603. return apply_filters( 'it_exchange_get_transaction_refunds_total', $total_refund, $transaction, $format );
  604. }
  605. /**
  606. * Returns the transaction description
  607. *
  608. * @since 0.4.0
  609. *
  610. * @param mixed $transaction ID or object
  611. * @return string
  612. */
  613. function it_exchange_get_transaction_description( $transaction ) {
  614. if ( $transaction = it_exchange_get_transaction( $transaction ) )
  615. return apply_filters( 'it_exchange_get_transaction_description', $transaction->get_description(), $transaction );
  616. return apply_filters( 'it_exchange_get_transaction_description', __( 'Unknown', 'it-l10n-ithemes-exchange' ), $transaction );
  617. }
  618. /**
  619. * Returns the customer object associated with a transaction
  620. *
  621. * @since 0.4.0
  622. *
  623. * @param mixed $transaction ID or object
  624. * @return object
  625. */
  626. function it_exchange_get_transaction_customer( $transaction ) {
  627. if ( $transaction = it_exchange_get_transaction( $transaction ) ) {
  628. $customer = empty( $transaction->customer_id ) ? false : it_exchange_get_customer( $transaction->customer_id );
  629. return apply_filters( 'it_exchange_get_transaction_customer', $customer, $transaction );
  630. }
  631. return apply_filters( 'it_exchange_get_transaction_customer', false, $transaction );
  632. }
  633. /**
  634. * Returns the transaction customer's Display Name
  635. *
  636. * @since 0.4.0
  637. *
  638. * @param mixed $transaction ID or object
  639. * @return string
  640. */
  641. function it_exchange_get_transaction_customer_display_name( $transaction ) {
  642. $unknown = __( 'Deleted Customer', 'it-l10n-ithemes-exchange' );
  643. if ( $customer = it_exchange_get_transaction_customer( $transaction ) ) {
  644. $display_name = empty( $customer->wp_user->display_name ) ? $unknown : $customer->wp_user->display_name;
  645. return apply_filters( 'it_exchange_get_transaction_customer_display_name', $display_name, $transaction );
  646. }
  647. return apply_filters( 'it_exchange_get_transaction_customer_display_name', $unknown, $transaction );
  648. }
  649. /**
  650. * Returns the transaction customer's ID
  651. *
  652. * @since 0.4.0
  653. *
  654. * @param mixed $transaction ID or object
  655. * @return string
  656. */
  657. function it_exchange_get_transaction_customer_id( $transaction ) {
  658. $unknown = 0;
  659. if ( $customer = it_exchange_get_transaction_customer( $transaction ) )
  660. return apply_filters( 'it_exchange_get_transaction_customer_id', empty( $customer->wp_user->ID ) ? $unknown : $customer->wp_user->ID, $transaction );
  661. return apply_filters( 'it_exchange_get_transaction_customer_id', $unknown, $transaction );
  662. }
  663. /**
  664. * Returns the transaction customer's email
  665. *
  666. * @since 0.4.0
  667. *
  668. * @param mixed $transaction ID or object
  669. * @return string
  670. */
  671. function it_exchange_get_transaction_customer_email( $transaction ) {
  672. $unknown = __( 'Unknown', 'it-l10n-ithemes-exchange' );
  673. if ( $customer = it_exchange_get_transaction_customer( $transaction ) )
  674. return apply_filters( 'it_exchange_get_transaction_customer_email', empty( $customer->wp_user->user_email ) ? $unknown : $customer->wp_user->user_email, $transaction );
  675. return apply_filters( 'it_exchange_get_transaction_customer_email', $unknown, $transaction );
  676. }
  677. /**
  678. * Returns the transaction customer's profile URL
  679. *
  680. * @since 0.4.0
  681. *
  682. * @param mixed $transaction ID or object
  683. * @return string
  684. */
  685. function it_exchange_get_transaction_customer_admin_profile_url( $transaction, $options=array() ) {
  686. if ( ! $customer = it_exchange_get_transaction_customer( $transaction ) )
  687. return false;
  688. $defaults = array(
  689. 'tab' => 'transactions',
  690. );
  691. $options = ITUtility::merge_defaults( $options, $defaults );
  692. $url = add_query_arg( array( 'user_id' => $customer->id, 'it_exchange_customer_data' => 1, 'tab' => $options['tab'] ), get_admin_url() . 'user-edit.php' );
  693. return apply_filters( 'it_exchange_get_transaction_customer_admin_profile_url', $url, $transaction, $options );
  694. }
  695. /**
  696. * Get Transaction Order Number
  697. *
  698. * @since 0.4.0
  699. *
  700. * @param mixed $transaction id or object
  701. * @return string
  702. */
  703. function it_exchange_get_transaction_order_number( $transaction, $prefix='#' ) {
  704. if ( ! $transaction = it_exchange_get_transaction( $transaction ) )
  705. return false;
  706. // Translate default prefix
  707. $prefix = ( '#' == $prefix ) ? __( '#', 'it-l10n-ithemes-exchange' ) : $prefix;
  708. $order_number = sprintf( '%06d', $transaction->ID );
  709. $order_number = empty( $prefix ) ? $order_number : $prefix . $order_number;
  710. return apply_filters( 'it_exchange_get_transaction_order_number', $order_number, $transaction, $prefix );
  711. }
  712. /**
  713. * Returns the shipping addresss saveed with the transaction
  714. *
  715. * @since 1.4.0
  716. *
  717. * @param array transaction shipping address
  718. *
  719. */
  720. function it_exchange_get_transaction_shipping_address( $transaction ) {
  721. if ( ! $transaction = it_exchange_get_transaction( $transaction ) )
  722. return false;
  723. $shipping_address = empty( $transaction->cart_details->shipping_address ) ? false: $transaction->cart_details->shipping_address;
  724. return apply_filters( 'it_exchange_get_transaction_shipping_address', $shipping_address, $transaction );
  725. }
  726. /**
  727. * Returns the billing addresss saveed with the transaction
  728. *
  729. * @since 1.3.0
  730. *
  731. * @param array transaction billing address
  732. *
  733. */
  734. function it_exchange_get_transaction_billing_address( $transaction ) {
  735. if ( ! $transaction = it_exchange_get_transaction( $transaction ) )
  736. return false;
  737. $billing_address = empty( $transaction->cart_details->billing_address ) ? false: $transaction->cart_details->billing_address;
  738. return apply_filters( 'it_exchange_get_transaction_billing_address', $billing_address, $transaction );
  739. }
  740. /**
  741. * Returns an array of product objects as they existed when added to the transaction
  742. *
  743. * @since 0.4.0
  744. *
  745. * @param mixed $transaction id or objec
  746. * @return array
  747. */
  748. function it_exchange_get_transaction_products( $transaction ) {
  749. if ( ! $transaction = it_exchange_get_transaction( $transaction ) )
  750. return apply_filters( 'it_exchange_get_transaction_products', array(), $transaction );
  751. if ( ! $transaction_products = $transaction->get_products() )
  752. return apply_filters( 'it_exchange_get_transaction_products', array(), $transaction );
  753. // There is a filter in transaction class: it_exchange_get_transaction_products
  754. return apply_filters( 'it_exchange_get_transaction_products', $transaction_products, $transaction );
  755. }
  756. /**
  757. * Returns a specific product from a transaction based on the product_cart_id
  758. *
  759. * @since 0.4.0
  760. *
  761. * @param string $product_cart_id
  762. * @return object
  763. */
  764. function it_exchange_get_transaction_product( $transaction, $product_cart_id ) {
  765. if ( $products = it_exchnage_get_transaction_products( $transaction ) )
  766. return apply_filters( 'it_exchange_get_transaction_product', empty( $products[$product_cart_id] ) ? false : $products[$product_cart_id], $transaction, $product_cart_id );
  767. return apply_filters( 'it_exchange_get_transaction_product', false, $transaction, $product_cart_id );
  768. }
  769. /**
  770. * Returns data from the transaction product
  771. *
  772. * @since 0.4.0
  773. *
  774. * @param object $transaction_product
  775. *
  776. */
  777. function it_exchange_get_transaction_product_feature( $product, $feature ) {
  778. $return = false;
  779. if ( 'title' == $feature || 'name' == $feature )
  780. $feature = 'product_name';
  781. $feature_value = isset( $product[$feature] ) ? $product[$feature] : '';
  782. return apply_filters( 'it_exchange_get_transaction_product_feature', $feature_value, $product, $feature );
  783. }
  784. /**
  785. * Returns the transaction method name from the add-on's slug
  786. *
  787. * @since 0.3.7
  788. * @return string
  789. */
  790. function it_exchange_get_transaction_method_name_from_slug( $slug ) {
  791. if ( $method = it_exchange_get_addon( $slug ) )
  792. return apply_filters( 'it_exchange_get_transaction_method_name_' . $slug, $method['name'] );
  793. return apply_filters( 'it_exchange_get_transaction_method_name_' . $slug, $slug );
  794. }
  795. /**
  796. * Returns the name of a transaction method used for a specific transaction
  797. *
  798. * @since 0.4.0
  799. *
  800. * @param mixed $transaction ID or object
  801. * @return string
  802. */
  803. function it_exchange_get_transaction_method_name( $transaction ) {
  804. if ( $slug = it_exchange_get_transaction_method( $transaction ) )
  805. return apply_filters( 'it_exchange_get_transaction_method_name', it_exchange_get_transaction_method_name_from_slug( $slug ), $transaction );
  806. return apply_filters( 'it_exchange_get_transaction_method_name', false, $transaction );
  807. }
  808. /**
  809. * Updates the ID of a transaction method used for a specific transaction
  810. *
  811. * @since 0.4.0
  812. *
  813. * @param mixed $transaction ID or object
  814. * @param string $method_id ID from the transaction method
  815. * @return string
  816. */
  817. function it_exchange_update_transaction_method_id( $transaction, $method_id ) {
  818. $transaction = it_exchange_get_transaction( $transaction );
  819. return update_post_meta( $transaction->ID, '_it_exchange_transaction_method_id', $method_id );
  820. }
  821. /**
  822. * Updates the Cart Object of a transaction
  823. *
  824. * @since 0.4.0
  825. *
  826. * @param mixed $transaction ID or object
  827. * @param object $cart_object Cart Object for specific transaction
  828. * @return string
  829. */
  830. function it_exchange_update_transaction_cart_object( $transaction, $cart_object ) {
  831. $transaction = it_exchange_get_transaction( $transaction );
  832. return update_post_meta( $transaction->ID, '_it_exchange_cart_object', $cart_object );
  833. }
  834. /**
  835. * Returns the ID of a transaction method used for a specific transaction
  836. *
  837. * @since 0.4.0
  838. *
  839. * @param mixed $transaction ID or object
  840. * @return string
  841. */
  842. function it_exchange_get_transaction_method_id( $transaction ){
  843. $transaction = it_exchange_get_transaction( $transaction );
  844. return apply_filters( 'it_exchange_get_transaction_method_id', get_post_meta( $transaction->ID, '_it_exchange_transaction_method_id', true ), $transaction );
  845. }
  846. /**
  847. * For processing a transaction
  848. *
  849. * @since 0.3.7
  850. * @return mixed
  851. */
  852. function it_exchange_do_transaction( $method, $transaction_object ) {
  853. return apply_filters( 'it_exchange_do_transaction_' . $method, false, $transaction_object );
  854. }
  855. /**
  856. * Does the given transaction have a status that warants delivery of product(s)
  857. *
  858. * Returns true/false. Rely on transaction method addon to give us that. Default is false.
  859. *
  860. * @since 0.4.2
  861. *
  862. * @param mixed $transaction id or object
  863. * @return boolean
  864. */
  865. function it_exchange_transaction_is_cleared_for_delivery( $transaction ) {
  866. if ( ! $transaction = it_exchange_get_transaction( $transaction ) )
  867. return false;
  868. $transaction_method = it_exchange_get_transaction_method( $transaction );
  869. return apply_filters( 'it_exchange_' . $transaction_method . '_transaction_is_cleared_for_delivery', false, $transaction );
  870. }
  871. /**
  872. * Returns the make-payment action
  873. *
  874. * Leans on tranasction_method to actually provide it.
  875. *
  876. * @since 0.4.0
  877. *
  878. * @param string $tranasction_method slug registered with addon
  879. * @param array $options
  880. * @return mixed
  881. */
  882. function it_exchange_get_transaction_method_make_payment_button ( $transaction_method, $options=array() ) {
  883. return apply_filters( 'it_exchange_get_' . $transaction_method . '_make_payment_button', '', $options );
  884. }
  885. /**
  886. * Grab all registered webhook / IPN keys
  887. *
  888. * @since 0.4.0
  889. * @return array
  890. */
  891. function it_exchange_get_webhooks() {
  892. $webhooks = empty( $GLOBALS['it_exchange']['webhooks'] ) ? array() : (array) $GLOBALS['it_exchange']['webhooks'];
  893. return apply_filters( 'it_exchange_get_webhooks', $webhooks );
  894. }
  895. /**
  896. * Register a webhook / IPN key
  897. *
  898. * @since 0.4.0
  899. *
  900. * @param string $key the addon slug or ID
  901. * @param string $param the REQUEST param we are listening for
  902. * @return void
  903. */
  904. function it_exchange_register_webhook( $key, $param ) {
  905. $GLOBALS['it_exchange']['webhooks'][$key] = $param;
  906. do_action( 'it_exchange_register_webhook', $key, $param );
  907. }
  908. /**
  909. * Grab a specific registered webhook / IPN param
  910. *
  911. * @since 0.4.0
  912. *
  913. * @param string $key the key for the param we are looking for
  914. * @return string or false
  915. */
  916. function it_exchange_get_webhook( $key ) {
  917. $webhooks = it_exchange_get_webhooks();
  918. $webhook = empty( $GLOBALS['it_exchange']['webhooks'][$key] ) ? false : $GLOBALS['it_exchange']['webhooks'][$key];
  919. return apply_filters( 'it_exchange_get_webhook', $webhook, $key );
  920. }
  921. /**
  922. * Get the confirmation URL for a transaction
  923. *
  924. * @since 0.4.0
  925. *
  926. * @param integer $transaction_id id of the transaction
  927. * @return string url
  928. */
  929. function it_exchange_get_transaction_confirmation_url( $transaction_id ) {
  930. // If we can't grab the hash, return false
  931. if ( ! $transaction_hash = it_exchange_get_transaction_hash( $transaction_id ) )
  932. return apply_filters( 'it_exchange_get_transaction_confirmation_url', false, $transaction_id );
  933. // Get base page URL
  934. $confirmation_url = it_exchange_get_page_url( 'confirmation' );
  935. if ( '' != get_option( 'permalink_structure' ) ) {
  936. $confirmation_url = trailingslashit( $confirmation_url ) . $transaction_hash;
  937. } else {
  938. $slug = it_exchange_get_page_slug( 'confirmation' );
  939. $confirmation_url = remove_query_arg( $slug, $confirmation_url );
  940. $confirmation_url = add_query_arg( $slug, $transaction_hash, $confirmation_url );
  941. }
  942. return apply_filters( 'it_exchange_get_transaction_confirmation_url', $confirmation_url, $transaction_id );
  943. }
  944. /**
  945. * Can this transaction status be manually updated?
  946. *
  947. * @since 0.4.11
  948. *
  949. * @param mixed $transaction the id or object
  950. * @return boolean
  951. */
  952. function it_exchange_transaction_status_can_be_manually_changed( $transaction ) {
  953. if( ! $method = it_exchange_get_transaction_method( $transaction ) )
  954. return false;
  955. return apply_filters( 'it_exchange_' . $method . '_transaction_status_can_be_manually_changed', false );
  956. }
  957. /**
  958. * Does this transaction include shipping details
  959. *
  960. * @since 1.4.0
  961. *
  962. * @param mixed $transaction the id or object
  963. * @return boolean
  964. */
  965. function it_exchange_transaction_includes_shipping( $transaction ) {
  966. $includes_shipping = it_exchange_get_transaction_shipping_method( $transaction );
  967. $includes_shipping = ! empty( $includes_shipping->label );
  968. return apply_filters( 'it_exchange_transaction_includes_shipping', $includes_shipping, $transaction );
  969. }
  970. /**
  971. * Return the total for shipping for this transaction
  972. *
  973. * @since 1.4.0
  974. *
  975. * @param mixed $transaction the id or object
  976. * @return string
  977. */
  978. function it_exchange_get_transaction_shipping_total( $transaction, $format_price=false ) {
  979. if( ! $transaction= it_exchange_get_transaction( $transaction ) )
  980. return false;
  981. $shipping_total = empty( $transaction->cart_details->shipping_total ) ? false : it_exchange_convert_from_database_number( $transaction->cart_details->shipping_total );
  982. if ( ! empty( $shipping_total ) && $format_price )
  983. $shipping_total = it_exchange_format_price( $shipping_total );
  984. return apply_filters( 'it_exchange_get_transaction_shipping_total', $shipping_total, $transaction );
  985. }
  986. /**
  987. * Returns the shipping method object used with this transaction
  988. *
  989. * If Multiple Methods was used, returns a stdClass with slug and label properties
  990. *
  991. * @since 1.4.0
  992. *
  993. * @param mixed $transaction the id or object
  994. * @return boolean
  995. */
  996. function it_exchange_get_transaction_shipping_method( $transaction ) {
  997. if( ! $transaction= it_exchange_get_transaction( $transaction ) )
  998. return false;
  999. $shipping_method = empty( $transaction->cart_details->shipping_method ) ? false : $transaction->cart_details->shipping_method;
  1000. // If Multiple, Just return the string since its not a registered method
  1001. if ( 'multiple-methods' == $shipping_method ) {
  1002. $method = new stdClass();
  1003. $method->slug = 'multiple-methods';
  1004. $method->label = __( 'Multiple Shipping Methods', 'it-l10n-ithemes-exchange' );
  1005. return apply_filters( 'it_exchange_get_transaction_shipping_method', $method, $transaction );
  1006. }
  1007. $shipping_method = it_exchange_get_registered_shipping_method( $shipping_method );
  1008. return apply_filters( 'it_exchange_get_transaction_shipping_method', $shipping_method, $transaction );
  1009. }
  1010. /**
  1011. * Prints Shipping Method used for a specific product in the transaction
  1012. *
  1013. * @since 1.4.0
  1014. *
  1015. * @param mixed $transaction
  1016. * @return string
  1017. */
  1018. function it_exchange_get_transaction_shipping_method_for_product( $transaction, $product_cart_id ) {
  1019. if( ! $transaction= it_exchange_get_transaction( $transaction ) )
  1020. return false;
  1021. $transaction_method = it_exchange_get_transaction_shipping_method( $transaction );
  1022. if ( 'multiple-methods' == $transaction_method->slug ) {
  1023. $product_method = empty( $transaction->cart_details->shipping_method_multi[$product_cart_id] ) ? false : $transaction->cart_details->shipping_method_multi[$product_cart_id];
  1024. $product_method = it_exchange_get_registered_shipping_method( $product_method );
  1025. $method = empty( $product_method->label ) ? __( 'Unknown Method', 'it-l10n-ithemes-exchange' ) : $product_method->label;
  1026. } else {
  1027. $method = $transaction_method->label;
  1028. }
  1029. return apply_filters( 'it_exchange_get_transaction_shipping_method_for_product', $method, $transaction, $product_cart_id );
  1030. }