/** * Complete a purchase * * Performs all necessary actions to complete a purchase. * Triggered by the edd_update_payment_status() function. * * @since 1.0.8.3 * @param int $payment_id the ID number of the payment * @param string $new_status the status of the payment, probably "publish" * @param string $old_status the status of the payment prior to being marked as "complete", probably "pending" * @return void */ function edd_complete_purchase($payment_id, $new_status, $old_status) { if ($old_status == 'publish' || $old_status == 'complete') { return; } // Make sure that payments are only completed once // Make sure the payment completion is only processed when new status is complete if ($new_status != 'publish' && $new_status != 'complete') { return; } $creation_date = get_post_field('post_date', $payment_id, 'raw'); $completed_date = edd_get_payment_completed_date($payment_id); $user_info = edd_get_payment_meta_user_info($payment_id); $customer_id = edd_get_payment_customer_id($payment_id); $amount = edd_get_payment_amount($payment_id); $cart_details = edd_get_payment_meta_cart_details($payment_id); do_action('edd_pre_complete_purchase', $payment_id); if (is_array($cart_details)) { // Increase purchase count and earnings foreach ($cart_details as $cart_index => $download) { // "bundle" or "default" $download_type = edd_get_download_type($download['id']); $price_id = isset($download['item_number']['options']['price_id']) ? (int) $download['item_number']['options']['price_id'] : false; // Increase earnings and fire actions once per quantity number for ($i = 0; $i < $download['quantity']; $i++) { // Ensure these actions only run once, ever if (empty($completed_date)) { edd_record_sale_in_log($download['id'], $payment_id, $price_id, $creation_date); do_action('edd_complete_download_purchase', $download['id'], $payment_id, $download_type, $download, $cart_index); } } // Increase the earnings for this download ID edd_increase_earnings($download['id'], $download['price']); edd_increase_purchase_count($download['id'], $download['quantity']); } // Clear the total earnings cache delete_transient('edd_earnings_total'); // Clear the This Month earnings (this_monththis_month is NOT a typo) delete_transient(md5('edd_earnings_this_monththis_month')); delete_transient(md5('edd_earnings_todaytoday')); } // Increase the customer's purchase stats $customer = new EDD_Customer($customer_id); $customer->increase_purchase_count(); $customer->increase_value($amount); edd_increase_total_earnings($amount); // Check for discount codes and increment their use counts if (!empty($user_info['discount']) && $user_info['discount'] !== 'none') { $discounts = array_map('trim', explode(',', $user_info['discount'])); if (!empty($discounts)) { foreach ($discounts as $code) { edd_increase_discount_usage($code); } } } // Ensure this action only runs once ever if (empty($completed_date)) { // Save the completed date edd_update_payment_meta($payment_id, '_edd_completed_date', current_time('mysql')); do_action('edd_complete_purchase', $payment_id); } // Empty the shopping cart edd_empty_cart(); }
/** * Process the payment details edit * * @access private * @since 1.9 * @return void */ function edd_update_payment_details($data) { if (!current_user_can('edit_shop_payments', $data['edd_payment_id'])) { wp_die(__('You do not have permission to edit this payment record', 'easy-digital-downloads'), __('Error', 'easy-digital-downloads'), array('response' => 403)); } check_admin_referer('edd_update_payment_details_nonce'); // Retrieve the payment ID $payment_id = absint($data['edd_payment_id']); $payment = new EDD_Payment($payment_id); // Retrieve existing payment meta $meta = $payment->get_meta(); $user_info = $payment->user_info; $status = $data['edd-payment-status']; $unlimited = isset($data['edd-unlimited-downloads']) ? '1' : ''; $date = sanitize_text_field($data['edd-payment-date']); $hour = sanitize_text_field($data['edd-payment-time-hour']); // Restrict to our high and low if ($hour > 23) { $hour = 23; } elseif ($hour < 0) { $hour = 00; } $minute = sanitize_text_field($data['edd-payment-time-min']); // Restrict to our high and low if ($minute > 59) { $minute = 59; } elseif ($minute < 0) { $minute = 00; } $address = array_map('trim', $data['edd-payment-address'][0]); $curr_total = edd_sanitize_amount($payment->total); $new_total = edd_sanitize_amount($_POST['edd-payment-total']); $tax = isset($_POST['edd-payment-tax']) ? edd_sanitize_amount($_POST['edd-payment-tax']) : 0; $date = date('Y-m-d', strtotime($date)) . ' ' . $hour . ':' . $minute . ':00'; $curr_customer_id = sanitize_text_field($data['edd-current-customer']); $new_customer_id = sanitize_text_field($data['customer-id']); // Setup purchased Downloads and price options $updated_downloads = isset($_POST['edd-payment-details-downloads']) ? $_POST['edd-payment-details-downloads'] : false; if ($updated_downloads && !empty($_POST['edd-payment-downloads-changed'])) { foreach ($updated_downloads as $download) { // If this item doesn't have a log yet, add one for each quantity count $has_log = absint($download['has_log']); $has_log = empty($has_log) ? false : true; if ($has_log) { continue; } if (empty($download['item_price'])) { $download['item_price'] = 0.0; } $item_price = $download['item_price']; $download_id = absint($download['id']); $quantity = absint($download['quantity']) > 0 ? absint($download['quantity']) : 1; $price_id = false; if (edd_has_variable_prices($download_id) && isset($download['price_id'])) { $price_id = absint($download['price_id']); } // Set some defaults $args = array('quantity' => $quantity, 'item_price' => $item_price, 'price_id' => $price_id); $payment->add_download($download_id, $args); } $deleted_downloads = json_decode(stripcslashes($data['edd-payment-removed']), true); foreach ($deleted_downloads as $deleted_download) { $deleted_download = $deleted_download[0]; if (empty($deleted_download['id'])) { continue; } $price_id = empty($deleted_download['price_id']) ? 0 : (int) $deleted_download['price_id']; $args = array('quantity' => (int) $deleted_download['quantity'], 'price_id' => (int) $price_id, 'item_price' => (double) $deleted_download['amount']); $payment->remove_download($deleted_download['id'], $args); do_action('edd_remove_download_from_payment', $payment_id, $deleted_download['id']); } } do_action('edd_update_edited_purchase', $payment_id); $payment->date = $date; $updated = $payment->save(); if (0 === $updated) { wp_die(__('Error Updating Payment', 'easy-digital-downloads'), __('Error', 'easy-digital-downloads'), array('response' => 400)); } $customer_changed = false; if (isset($data['edd-new-customer']) && $data['edd-new-customer'] == '1') { $email = isset($data['edd-new-customer-email']) ? sanitize_text_field($data['edd-new-customer-email']) : ''; $names = isset($data['edd-new-customer-name']) ? sanitize_text_field($data['edd-new-customer-name']) : ''; if (empty($email) || empty($names)) { wp_die(__('New Customers require a name and email address', 'easy-digital-downloads')); } $customer = new EDD_Customer($email); if (empty($customer->id)) { $customer_data = array('name' => $names, 'email' => $email); $user_id = email_exists($email); if (false !== $user_id) { $customer_data['user_id'] = $user_id; } if (!$customer->create($customer_data)) { // Failed to crete the new customer, assume the previous customer $customer_changed = false; $customer = new EDD_Customer($curr_customer_id); edd_set_error('edd-payment-new-customer-fail', __('Error creating new customer', 'easy-digital-downloads')); } } $new_customer_id = $customer->id; $previous_customer = new EDD_Customer($curr_customer_id); $customer_changed = true; } elseif ($curr_customer_id !== $new_customer_id) { $customer = new EDD_Customer($new_customer_id); $email = $customer->email; $names = $customer->name; $previous_customer = new EDD_Customer($curr_customer_id); $customer_changed = true; } else { $customer = new EDD_Customer($curr_customer_id); $email = $customer->email; $names = $customer->name; } // Setup first and last name from input values $names = explode(' ', $names); $first_name = !empty($names[0]) ? $names[0] : ''; $last_name = ''; if (!empty($names[1])) { unset($names[0]); $last_name = implode(' ', $names); } if ($customer_changed) { // Remove the stats and payment from the previous customer and attach it to the new customer $previous_customer->remove_payment($payment_id, false); $customer->attach_payment($payment_id, false); // If purchase was completed and not ever refunded, adjust stats of customers if ('revoked' == $status || 'publish' == $status) { $previous_customer->decrease_purchase_count(); $previous_customer->decrease_value($new_total); $customer->increase_purchase_count(); $customer->increase_value($new_total); } $payment->customer_id = $customer->id; } // Set new meta values $payment->user_id = $customer->user_id; $payment->email = $customer->email; $payment->first_name = $first_name; $payment->last_name = $last_name; $payment->address = $address; $payment->total = $new_total; $payment->tax = $tax; $payment->has_unlimited_downloads = $unlimited; // Check for payment notes if (!empty($data['edd-payment-note'])) { $note = wp_kses($data['edd-payment-note'], array()); edd_insert_payment_note($payment->ID, $note); } // Set new status $payment->status = $status; // Adjust total store earnings if the payment total has been changed if ($new_total !== $curr_total && ('publish' == $status || 'revoked' == $status)) { if ($new_total > $curr_total) { // Increase if our new total is higher $difference = $new_total - $curr_total; edd_increase_total_earnings($difference); } elseif ($curr_total > $new_total) { // Decrease if our new total is lower $difference = $curr_total - $new_total; edd_decrease_total_earnings($difference); } } $payment->save(); do_action('edd_updated_edited_purchase', $payment_id); wp_safe_redirect(admin_url('edit.php?post_type=download&page=edd-payment-history&view=view-order-details&edd-message=payment-updated&id=' . $payment_id)); exit; }
/** * Increments customer purchase stats * * @access public * @since 2.1 */ public function increment_stats($customer_id = 0, $amount = 0.0) { $customer = new EDD_Customer($customer_id); if (empty($customer->id)) { return false; } $increased_count = $customer->increase_purchase_count(); $increased_value = $customer->increase_value($amount); return $increased_count && $increased_value ? true : false; }
/** * One items have been set, an update is needed to save them to the database. * * @return bool True of the save occured, false if it failed or wasn't needed */ public function save() { $saved = false; if (empty($this->ID)) { $payment_id = $this->insert_payment(); if (false === $payment_id) { $saved = false; } else { $this->ID = $payment_id; } } if ($this->ID !== $this->_ID) { $this->ID = $this->_ID; } // If we have something pending, let's save it if (!empty($this->pending)) { $total_increase = 0; $total_decrease = 0; foreach ($this->pending as $key => $value) { switch ($key) { case 'downloads': // Update totals for pending downloads foreach ($this->pending[$key] as $item) { switch ($item['action']) { case 'add': $price = $item['price']; $taxes = $item['tax']; if ('publish' === $this->status || 'complete' === $this->status || 'revoked' === $this->status) { // Add sales logs $log_date = date('Y-m-d G:i:s', current_time('timestamp', true)); $price_id = isset($item['item_number']['options']['price_id']) ? $item['item_number']['options']['price_id'] : 0; $y = 0; while ($y < $item['quantity']) { edd_record_sale_in_log($item['id'], $this->ID, $price_id, $log_date); $y++; } $download = new EDD_Download($item['id']); $download->increase_sales($item['quantity']); $download->increase_earnings($price); $total_increase += $price; } break; case 'remove': $log_args = array('post_type' => 'edd_log', 'post_parent' => $item['id'], 'numberposts' => $item['quantity'], 'meta_query' => array(array('key' => '_edd_log_payment_id', 'value' => $this->ID, 'compare' => '='), array('key' => '_edd_log_price_id', 'value' => $item['price_id'], 'compare' => '='))); $found_logs = get_posts($log_args); foreach ($found_logs as $log) { wp_delete_post($log->ID, true); } if ('publish' === $this->status || 'complete' === $this->status || 'revoked' === $this->status) { $download = new EDD_Download($item['id']); $download->decrease_sales($item['quantity']); $download->decrease_earnings($item['amount']); $total_decrease += $item['amount']; } break; } } break; case 'fees': if (!empty($this->pending[$key])) { foreach ($this->pending[$key] as $fee) { switch ($fee['action']) { case 'add': $total_increase += $fee['amount']; break; case 'remove': $total_decrease += $fee['amount']; break; } } } break; case 'status': $this->update_status($this->status); break; case 'gateway': $this->update_meta('_edd_payment_gateway', $this->gateway); break; case 'mode': $this->update_meta('_edd_payment_mode', $this->mode); break; case 'transaction_id': $this->update_meta('_edd_payment_transaction_id', $this->transaction_id); break; case 'ip': $this->update_meta('_edd_payment_user_ip', $this->ip); break; case 'customer_id': $this->update_meta('_edd_payment_customer_id', $this->customer_id); break; case 'user_id': $this->update_meta('_edd_payment_user_id', $this->user_id); break; case 'first_name': $this->user_info['first_name'] = $this->first_name; break; case 'last_name': $this->user_info['last_name'] = $this->last_name; break; case 'discounts': $this->user_info['discount'] = $this->discounts; break; case 'address': $this->user_info['address'] = $this->address; break; case 'email': $this->update_meta('_edd_payment_user_email', $this->email); break; case 'key': $this->update_meta('_edd_payment_purchase_key', $this->key); break; case 'number': $this->update_meta('_edd_payment_number', $this->number); break; case 'completed_date': $this->update_meta('_edd_completed_date', $this->completed_date); break; case 'has_unlimited_downloads': $this->update_meta('_edd_payment_unlimited_downloads', $this->has_unlimited_downloads); break; case 'parent_payment': $args = array('ID' => $this->ID, 'post_parent' => $this->parent_payment); wp_update_post($args); break; default: do_action('edd_payment_save', $this, $key); break; } } if ('pending' !== $this->status) { $customer = new EDD_Customer($this->customer_id); $total_change = $total_increase - $total_decrease; if ($total_change < 0) { $total_chnage = -$total_change; // Decrease the customer's purchase stats $customer->decrease_value($total_change); edd_decrease_total_earnings($total_change); } else { if ($total_change > 0) { // Increase the customer's purchase stats $customer->increase_value($total_change); edd_increase_total_earnings($total_change); } } } $this->update_meta('_edd_payment_total', $this->total); $this->update_meta('_edd_payment_tax', $this->tax); $new_meta = array('downloads' => $this->downloads, 'cart_details' => $this->cart_details, 'fees' => $this->fees, 'currency' => $this->currency, 'user_info' => $this->user_info); $meta = $this->get_meta(); $merged_meta = array_merge($meta, $new_meta); // Only save the payment meta if it's changed if (md5(serialize($meta)) !== md5(serialize($merged_meta))) { $updated = $this->update_meta('_edd_payment_meta', $merged_meta); if (false !== $updated) { $saved = true; } } $this->pending = array(); $saved = true; } if (true === $saved) { $this->setup_payment($this->ID); } return $saved; }
/** * Process the payment details edit * * @access private * @since 1.9 * @return void */ function edd_update_payment_details($data) { if (!current_user_can('edit_shop_payments', $data['edd_payment_id'])) { wp_die(__('You do not have permission to edit this payment record', 'edd'), __('Error', 'edd'), array('response' => 403)); } check_admin_referer('edd_update_payment_details_nonce'); // Retrieve the payment ID $payment_id = absint($data['edd_payment_id']); // Retrieve existing payment meta $meta = edd_get_payment_meta($payment_id); $user_info = edd_get_payment_meta_user_info($payment_id); $status = $data['edd-payment-status']; $unlimited = isset($data['edd-unlimited-downloads']) ? '1' : ''; $date = sanitize_text_field($data['edd-payment-date']); $hour = sanitize_text_field($data['edd-payment-time-hour']); // Restrict to our high and low if ($hour > 23) { $hour = 23; } elseif ($hour < 0) { $hour = 00; } $minute = sanitize_text_field($data['edd-payment-time-min']); // Restrict to our high and low if ($minute > 59) { $minute = 59; } elseif ($minute < 0) { $minute = 00; } $address = array_map('trim', $data['edd-payment-address'][0]); $curr_total = edd_sanitize_amount(edd_get_payment_amount($payment_id)); $new_total = edd_sanitize_amount($_POST['edd-payment-total']); $tax = isset($_POST['edd-payment-tax']) ? edd_sanitize_amount($_POST['edd-payment-tax']) : 0; $date = date('Y-m-d', strtotime($date)) . ' ' . $hour . ':' . $minute . ':00'; $curr_customer_id = sanitize_text_field($data['edd-current-customer']); $new_customer_id = sanitize_text_field($data['customer-id']); // Setup purchased Downloads and price options $updated_downloads = isset($_POST['edd-payment-details-downloads']) ? $_POST['edd-payment-details-downloads'] : false; if ($updated_downloads && !empty($_POST['edd-payment-downloads-changed'])) { $downloads = array(); $cart_details = array(); $i = 0; foreach ($updated_downloads as $download) { if (empty($download['amount'])) { $download['amount'] = '0.00'; } $item = array(); $item['id'] = absint($download['id']); $item['quantity'] = absint($download['quantity']) > 0 ? absint($download['quantity']) : 1; $price_id = (int) $download['price_id']; $has_log = absint($download['has_log']); if ($price_id !== false && edd_has_variable_prices($item['id'])) { $item['options'] = array('price_id' => $price_id); } $downloads[] = $item; $cart_item = array(); $cart_item['item_number'] = $item; $item_price = round($download['amount'] / $item['quantity'], edd_currency_decimal_filter()); $cart_details[$i] = array('name' => get_the_title($download['id']), 'id' => $download['id'], 'item_number' => $item, 'price' => $download['amount'], 'item_price' => $item_price, 'subtotal' => $download['amount'], 'quantity' => $download['quantity'], 'discount' => 0, 'tax' => 0); // If this item doesn't have a log yet, add one for each quantity count if (empty($has_log)) { $log_date = date('Y-m-d G:i:s', current_time('timestamp', true)); $price_id = $price_id !== false ? $price_id : 0; $y = 0; while ($y < $download['quantity']) { edd_record_sale_in_log($download['id'], $payment_id, $price_id, $log_date); $y++; } edd_increase_purchase_count($download['id'], $download['quantity']); edd_increase_earnings($download['id'], $download['amount']); } $i++; } $meta['downloads'] = $downloads; $meta['cart_details'] = $cart_details; $deleted_downloads = json_decode(stripcslashes($data['edd-payment-removed']), true); foreach ($deleted_downloads as $deleted_download) { $deleted_download = $deleted_download[0]; if (empty($deleted_download['id'])) { continue; } $price_id = empty($deleted_download['price_id']) ? 0 : (int) $deleted_download['price_id']; $log_args = array('post_type' => 'edd_log', 'post_parent' => $deleted_download['id'], 'numberposts' => $deleted_download['quantity'], 'meta_query' => array(array('key' => '_edd_log_payment_id', 'value' => $payment_id, 'compare' => '='), array('key' => '_edd_log_price_id', 'value' => $price_id, 'compare' => '='))); $found_logs = get_posts($log_args); foreach ($found_logs as $log) { wp_delete_post($log->ID, true); } edd_decrease_purchase_count($deleted_download['id'], $deleted_download['quantity']); edd_decrease_earnings($deleted_download['id'], $deleted_download['amount']); do_action('edd_remove_download_from_payment', $payment_id, $deleted_download['id']); } } do_action('edd_update_edited_purchase', $payment_id); // Update main payment record $updated = wp_update_post(array('ID' => $payment_id, 'post_date' => $date)); if (0 === $updated) { wp_die(__('Error Updating Payment', 'edd'), __('Error', 'edd'), array('response' => 400)); } $customer_changed = false; if (isset($data['edd-new-customer']) && $data['edd-new-customer'] == '1') { $email = isset($data['edd-new-customer-email']) ? sanitize_text_field($data['edd-new-customer-email']) : ''; $names = isset($data['edd-new-customer-name']) ? sanitize_text_field($data['edd-new-customer-name']) : ''; if (empty($email) || empty($names)) { wp_die(__('New Customers require a name and email address', 'edd')); } $customer = new EDD_Customer($email); if (empty($customer->id)) { $customer_data = array('name' => $names, 'email' => $email); $user_id = email_exists($email); if (false !== $user_id) { $customer_data['user_id'] = $user_id; } if (!$customer->create($customer_data)) { // Failed to crete the new customer, assume the previous customer $customer_changed = false; $customer = new EDD_Customer($curr_customer_id); edd_set_error('edd-payment-new-customer-fail', __('Error creating new customer', 'edd')); } } $new_customer_id = $customer->id; $previous_customer = new EDD_Customer($curr_customer_id); $customer_changed = true; } elseif ($curr_customer_id !== $new_customer_id) { $customer = new EDD_Customer($new_customer_id); $email = $customer->email; $names = $customer->name; $previous_customer = new EDD_Customer($curr_customer_id); $customer_changed = true; } else { $customer = new EDD_Customer($curr_customer_id); $email = $customer->email; $names = $customer->name; } // Setup first and last name from input values $names = explode(' ', $names); $first_name = !empty($names[0]) ? $names[0] : ''; $last_name = ''; if (!empty($names[1])) { unset($names[0]); $last_name = implode(' ', $names); } if ($customer_changed) { // Remove the stats and payment from the previous customer and attach it to the new customer $previous_customer->remove_payment($payment_id, false); $customer->attach_payment($payment_id, false); // If purchase was completed and not ever refunded, adjust stats of customers if ('revoked' == $status || 'publish' == $status) { $previous_customer->decrease_purchase_count(); $previous_customer->decrease_value($new_total); $customer->increase_purchase_count(); $customer->increase_value($new_total); } update_post_meta($payment_id, '_edd_payment_customer_id', $customer->id); } // Set new meta values $user_info['id'] = $customer->user_id; $user_info['email'] = $customer->email; $user_info['first_name'] = $first_name; $user_info['last_name'] = $last_name; $user_info['address'] = $address; $meta['user_info'] = $user_info; $meta['tax'] = $tax; // Check for payment notes if (!empty($data['edd-payment-note'])) { $note = wp_kses($data['edd-payment-note'], array()); edd_insert_payment_note($payment_id, $note); } // Set new status edd_update_payment_status($payment_id, $status); edd_update_payment_meta($payment_id, '_edd_payment_user_id', $customer->user_id); edd_update_payment_meta($payment_id, '_edd_payment_user_email', $customer->email); edd_update_payment_meta($payment_id, '_edd_payment_meta', $meta); edd_update_payment_meta($payment_id, '_edd_payment_total', $new_total); // Adjust total store earnings if the payment total has been changed if ($new_total !== $curr_total && ('publish' == $status || 'revoked' == $status)) { if ($new_total > $curr_total) { // Increase if our new total is higher $difference = $new_total - $curr_total; edd_increase_total_earnings($difference); } elseif ($curr_total > $new_total) { // Decrease if our new total is lower $difference = $curr_total - $new_total; edd_decrease_total_earnings($difference); } } edd_update_payment_meta($payment_id, '_edd_payment_downloads', $new_total); edd_update_payment_meta($payment_id, '_edd_payment_unlimited_downloads', $unlimited); do_action('edd_updated_edited_purchase', $payment_id); wp_safe_redirect(admin_url('edit.php?post_type=download&page=edd-payment-history&view=view-order-details&edd-message=payment-updated&id=' . $payment_id)); exit; }
/** * One items have been set, an update is needed to save them to the database. * * @return bool True of the save occurred, false if it failed or wasn't needed */ public function save() { $saved = false; if (empty($this->ID)) { $payment_id = $this->insert_payment(); if (false === $payment_id) { $saved = false; } else { $this->ID = $payment_id; } } if ($this->ID !== $this->_ID) { $this->ID = $this->_ID; } // If we have something pending, let's save it if (!empty($this->pending)) { $total_increase = 0; $total_decrease = 0; foreach ($this->pending as $key => $value) { switch ($key) { case 'downloads': // Update totals for pending downloads foreach ($this->pending[$key] as $item) { switch ($item['action']) { case 'add': $price = $item['price']; $taxes = $item['tax']; if ('publish' === $this->status || 'complete' === $this->status || 'revoked' === $this->status) { // Add sales logs $log_date = date_i18n('Y-m-d G:i:s', current_time('timestamp')); $price_id = isset($item['item_number']['options']['price_id']) ? $item['item_number']['options']['price_id'] : 0; $y = 0; while ($y < $item['quantity']) { edd_record_sale_in_log($item['id'], $this->ID, $price_id, $log_date); $y++; } $increase_earnings = $price; if (!empty($item['fees'])) { foreach ($item['fees'] as $fee) { // Only let negative fees affect the earnings if ($fee['amount'] > 0) { continue; } $increase_earnings += (double) $fee['amount']; } } $download = new EDD_Download($item['id']); $download->increase_sales($item['quantity']); $download->increase_earnings($increase_earnings); $total_increase += $price; } break; case 'remove': $log_args = array('post_type' => 'edd_log', 'post_parent' => $item['id'], 'numberposts' => $item['quantity'], 'meta_query' => array(array('key' => '_edd_log_payment_id', 'value' => $this->ID, 'compare' => '='), array('key' => '_edd_log_price_id', 'value' => $item['price_id'], 'compare' => '='))); $found_logs = get_posts($log_args); foreach ($found_logs as $log) { wp_delete_post($log->ID, true); } if ('publish' === $this->status || 'complete' === $this->status || 'revoked' === $this->status) { $download = new EDD_Download($item['id']); $download->decrease_sales($item['quantity']); $decrease_amount = $item['amount']; if (!empty($item['fees'])) { foreach ($item['fees'] as $fee) { // Only let negative fees affect the earnings if ($fee['amount'] > 0) { continue; } $decrease_amount += $fee['amount']; } } $download->decrease_earnings($decrease_amount); $total_decrease += $item['amount']; } break; } } break; case 'fees': if ('publish' !== $this->status && 'complete' !== $this->status && 'revoked' !== $this->status) { break; } if (empty($this->pending[$key])) { break; } foreach ($this->pending[$key] as $fee) { switch ($fee['action']) { case 'add': $total_increase += $fee['amount']; break; case 'remove': $total_decrease += $fee['amount']; break; } } break; case 'status': $this->update_status($this->status); break; case 'gateway': $this->update_meta('_edd_payment_gateway', $this->gateway); break; case 'mode': $this->update_meta('_edd_payment_mode', $this->mode); break; case 'transaction_id': $this->update_meta('_edd_payment_transaction_id', $this->transaction_id); break; case 'ip': $this->update_meta('_edd_payment_user_ip', $this->ip); break; case 'customer_id': $this->update_meta('_edd_payment_customer_id', $this->customer_id); break; case 'user_id': $this->update_meta('_edd_payment_user_id', $this->user_id); break; case 'first_name': $this->user_info['first_name'] = $this->first_name; break; case 'last_name': $this->user_info['last_name'] = $this->last_name; break; case 'discounts': if (!is_array($this->discounts)) { $this->discounts = explode(',', $this->discounts); } $this->user_info['discount'] = implode(',', $this->discounts); break; case 'address': $this->user_info['address'] = $this->address; break; case 'email': $this->update_meta('_edd_payment_user_email', $this->email); break; case 'key': $this->update_meta('_edd_payment_purchase_key', $this->key); break; case 'number': $this->update_meta('_edd_payment_number', $this->number); break; case 'date': $args = array('ID' => $this->ID, 'post_date' => $this->date, 'edit_date' => true); wp_update_post($args); break; case 'completed_date': $this->update_meta('_edd_completed_date', $this->completed_date); break; case 'has_unlimited_downloads': $this->update_meta('_edd_payment_unlimited_downloads', $this->has_unlimited_downloads); break; case 'parent_payment': $args = array('ID' => $this->ID, 'post_parent' => $this->parent_payment); wp_update_post($args); break; default: /** * Used to save non-standard data. Developers can hook here if they want to save * specific payment data when $payment->save() is run and their item is in the $pending array */ do_action('edd_payment_save', $this, $key); break; } } if ('pending' !== $this->status) { $customer = new EDD_Customer($this->customer_id); $total_change = $total_increase - $total_decrease; if ($total_change < 0) { $total_change = -$total_change; // Decrease the customer's purchase stats $customer->decrease_value($total_change); edd_decrease_total_earnings($total_change); } else { if ($total_change > 0) { // Increase the customer's purchase stats $customer->increase_value($total_change); edd_increase_total_earnings($total_change); } } } $this->update_meta('_edd_payment_total', $this->total); $this->update_meta('_edd_payment_tax', $this->tax); $this->downloads = array_values($this->downloads); $new_meta = array('downloads' => $this->downloads, 'cart_details' => $this->cart_details, 'fees' => $this->fees, 'currency' => $this->currency, 'user_info' => is_array($this->user_info) ? array_filter($this->user_info) : array(), 'date' => $this->date); // Do some merging of user_info before we merge it all, to honor the edd_payment_meta filter if (!empty($this->payment_meta['user_info'])) { $stored_discount = !empty($new_meta['user_info']['discount']) ? $new_meta['user_info']['discount'] : ''; $new_meta['user_info'] = array_replace_recursive((array) $this->payment_meta['user_info'], $new_meta['user_info']); if ('none' !== $stored_discount) { $new_meta['user_info']['discount'] = $stored_discount; } } $meta = $this->get_meta(); $merged_meta = array_merge($meta, $new_meta); // Only save the payment meta if it's changed if (md5(serialize($meta)) !== md5(serialize($merged_meta))) { $updated = $this->update_meta('_edd_payment_meta', $merged_meta); if (false !== $updated) { $saved = true; } } $this->pending = array(); $saved = true; } if (true === $saved) { $this->setup_payment($this->ID); /** * This action fires anytime that $payment->save() is run, allowing developers to run actions * when a payment is updated */ do_action('edd_payment_saved', $this->ID, $this); } return $saved; }