/** * Generate the paypal button link * * @param int $order_id * @return string */ public function generate_paypal_form($order_id) { $order = new jigoshop_order($order_id); if ($this->testmode == 'yes') { $url = $this->testurl . '?test_ipn=1&'; } else { $url = $this->liveurl . '?'; } if (in_array($order->billing_country, array('US', 'CA'))) { $order->billing_phone = str_replace(array('(', '-', ' ', ')'), '', $order->billing_phone); $phone_args = array('night_phone_a' => substr($order->billing_phone, 0, 3), 'night_phone_b' => substr($order->billing_phone, 3, 3), 'night_phone_c' => substr($order->billing_phone, 6, 4), 'day_phone_a' => substr($order->billing_phone, 0, 3), 'day_phone_b' => substr($order->billing_phone, 3, 3), 'day_phone_c' => substr($order->billing_phone, 6, 4)); } else { $phone_args = array('night_phone_b' => $order->billing_phone, 'day_phone_b' => $order->billing_phone); } // filter redirect page $checkout_redirect = apply_filters('jigoshop_get_checkout_redirect_page_id', jigoshop_get_page_id('thanks')); $paypal_args = array_merge(array('cmd' => '_cart', 'business' => $this->testmode == 'yes' ? $this->testemail : $this->email, 'no_note' => 1, 'currency_code' => Jigoshop_Base::get_options()->get('jigoshop_currency'), 'charset' => 'UTF-8', 'rm' => 2, 'upload' => 1, 'return' => add_query_arg('key', $order->order_key, add_query_arg('order', $order_id, get_permalink($checkout_redirect))), 'cancel_return' => $order->get_cancel_order_url(), 'custom' => $order_id, 'notify_url' => $this->notify_url, 'first_name' => $order->billing_first_name, 'last_name' => $order->billing_last_name, 'company' => $order->billing_company, 'address1' => $order->billing_address_1, 'address2' => $order->billing_address_2, 'city' => $order->billing_city, 'state' => $order->billing_state, 'zip' => $order->billing_postcode, 'country' => $order->billing_country, 'email' => $order->billing_email, 'invoice' => $order->get_order_number(), 'amount' => number_format((double) $order->order_total, $this->decimals), 'bn' => 'Jigoshop_SP'), $phone_args); if ($this->send_shipping == 'yes') { $paypal_args['no_shipping'] = 1; $paypal_args['address_override'] = 1; $paypal_args['first_name'] = $order->shipping_first_name; $paypal_args['last_name'] = $order->shipping_last_name; $paypal_args['address1'] = $order->shipping_address_1; $paypal_args['address2'] = $order->shipping_address_2; $paypal_args['city'] = $order->shipping_city; $paypal_args['state'] = $order->shipping_state; $paypal_args['zip'] = $order->shipping_postcode; $paypal_args['country'] = $order->shipping_country; // PayPal counts Puerto Rico as a US Territory, won't allow payment without it if ($paypal_args['country'] == 'PR') { $paypal_args['country'] = 'US'; $paypal_args['state'] = 'PR'; } } else { $paypal_args['no_shipping'] = 1; $paypal_args['address_override'] = 0; } // If prices include tax, send the whole order as a single item if (Jigoshop_Base::get_options()->get('jigoshop_prices_include_tax') == 'yes') { // Discount $paypal_args['discount_amount_cart'] = number_format((double) $order->order_discount, $this->decimals); // Don't pass items - PayPal breaks tax due to catalog prices include tax. // PayPal has no option for tax inclusive pricing. // Pass 1 item for the order items overall $item_names = array(); foreach ($order->items as $item) { $_product = $order->get_product_from_item($item); $title = $_product->get_title(); //if variation, insert variation details into product title if ($_product instanceof jigoshop_product_variation) { $title .= ' (' . jigoshop_get_formatted_variation($_product, $item['variation'], true) . ')'; } $item_names[] = $title . ' x ' . $item['qty']; } $paypal_args['item_name_1'] = sprintf(__('Order %s', 'jigoshop'), $order->get_order_number()) . ' - ' . implode(', ', $item_names); $paypal_args['quantity_1'] = 1; $paypal_args['amount_1'] = number_format($order->order_total - $order->order_shipping - $order->order_shipping_tax + $order->order_discount, $this->decimals, '.', ''); if ($order->order_shipping + $order->order_shipping_tax > 0) { $paypal_args['item_name_2'] = __('Shipping cost', 'jigoshop'); $paypal_args['quantity_2'] = '1'; $paypal_args['amount_2'] = number_format($order->order_shipping + $order->order_shipping_tax, $this->decimals, '.', ''); } } else { // Cart Contents $item_loop = 0; foreach ($order->items as $item) { $_product = $order->get_product_from_item($item); if ($_product->exists() && $item['qty']) { $item_loop++; $title = $_product->get_title(); //if variation, insert variation details into product title if ($_product instanceof jigoshop_product_variation) { $title .= ' (' . jigoshop_get_formatted_variation($_product, $item['variation'], true) . ')'; } $paypal_args['item_name_' . $item_loop] = $title; $paypal_args['quantity_' . $item_loop] = $item['qty']; $paypal_args['amount_' . $item_loop] = number_format(apply_filters('jigoshop_paypal_adjust_item_price', $item['cost'], $item, 10, 2), $this->decimals); //Apparently, Paypal did not like "28.4525" as the amount. Changing that to "28.45" fixed the issue. } } // Shipping Cost if (jigoshop_shipping::is_enabled() && $order->order_shipping > 0) { $item_loop++; $paypal_args['item_name_' . $item_loop] = __('Shipping cost', 'jigoshop'); $paypal_args['quantity_' . $item_loop] = '1'; $paypal_args['amount_' . $item_loop] = number_format((double) $order->order_shipping, $this->decimals); } $paypal_args['tax'] = $order->get_total_tax(false, false); // no currency sign or pricing options for separators $paypal_args['tax_cart'] = $order->get_total_tax(false, false); // no currency sign or pricing options for separators $paypal_args['discount_amount_cart'] = $order->order_discount; if ($this->force_payment == 'yes') { $sum = 0; for ($i = 1; $i < $item_loop; $i++) { $sum += $paypal_args['amount_' . $i]; } $item_loop++; if ($sum == 0 || $order->order_discount && $sum - $order->order_discount == 0) { $paypal_args['item_name_' . $item_loop] = __('Force payment on free', 'jigoshop'); $paypal_args['quantity_' . $item_loop] = '1'; $paypal_args['amount_' . $item_loop] = 0.01; // force payment } } } $paypal_args = apply_filters('jigoshop_paypal_args', $paypal_args); return jigoshop_render_result('gateways/paypal', array('url' => $url, 'fields' => $paypal_args)); }
/** * Order totals meta box * * Displays the order totals meta box * * @since 1.0 */ function jigoshop_order_totals_meta_box($post) { $_order = new jigoshop_order($post->ID); $coupons = array(); $order_discount_coupons = (array) $_order->_fetch('order_discount_coupons'); if (!empty($order_discount_coupons)) { foreach ($order_discount_coupons as $coupon) { $coupons[] = isset($coupon['code']) ? $coupon['code'] : ''; } } ?> <ul class="totals"> <li class="left"> <label><?php _e('Subtotal:', 'jigoshop'); ?> </label> <input type="text" id="order_subtotal" name="order_subtotal" placeholder="0.00 <?php _e('(ex. tax)', 'jigoshop'); ?> " value="<?php echo esc_attr($_order->_fetch('order_subtotal')); ?> " class="first" /> </li> <li class="right"> <label><?php _e('Discount: ', 'jigoshop'); ?> <span class="applied-coupons-values"><?php echo implode(',', $coupons); ?> </span></label> <input type="text" id="order_discount" name="order_discount" placeholder="0.00" value="<?php echo esc_attr($_order->_fetch('order_discount')); ?> " /> </li> <?php $shipping_methods = jigoshop_shipping::get_all_methods(); $shipping_select = "<select id='shipping_method' name='shipping_method' class='last' data-placeholder=" . __('Choose', 'jigoshop') . ">"; $shipping_select .= "<option></option>"; if (!empty($shipping_methods)) { foreach ($shipping_methods as $index => $method) { $mark = ''; if ($_order->_fetch('shipping_method') == $method->id) { $mark = 'selected="selected"'; } $shipping_select .= "<option value='{$method->id}' {$mark}>{$method->title}</option>"; } } $shipping_select .= "</select>"; ?> <li> <label><?php _e('Shipping:', 'jigoshop'); ?> </label> <input type="text" id="order_shipping" name="order_shipping" placeholder="0.00 <?php _e('(ex. tax)', 'jigoshop'); ?> " value="<?php echo esc_attr($_order->_fetch('order_shipping')); ?> " class="first" /> <?php echo $shipping_select; ?> <script type="text/javascript"> /*<![CDATA[*/ jQuery(function() { jQuery("#shipping_method").select2({ width: '120px' }); }); /*]]>*/ </script> </li> <li class="left"> <label><?php _e('Total Tax:', 'jigoshop'); ?> </label> <input type="text" id="order_tax" name="order_tax_total" placeholder="0.00" value="<?php echo esc_attr($_order->get_total_tax()); ?> " class="first" /> </li> <li class="right"> <label><?php _e('Shipping Tax:', 'jigoshop'); ?> </label> <input type="text" id="order_shipping_tax" name="order_shipping_tax" placeholder="0.00" value="<?php echo esc_attr($_order->_fetch('order_shipping_tax')); ?> " class="first" /> </li> <?php $payment_methods = jigoshop_payment_gateways::get_available_payment_gateways(); $payment_select = "<select id='payment_method' name='payment_method' class='last' data-placeholder=" . __('Choose', 'jigoshop') . ">"; $payment_select .= "<option></option>"; if (!empty($payment_methods)) { foreach ($payment_methods as $index => $method) { $mark = ''; if ($_order->_fetch('payment_method') == $method->id) { $mark = 'selected="selected"'; } $payment_select .= "<option value='{$method->id}' {$mark}>{$method->title}</option>"; } } $payment_select .= "</select>"; ?> <?php do_action('jigoshop_admin_order_totals_after_shipping', $post->ID); ?> <li> <label><?php _e('Total:', 'jigoshop'); ?> </label> <input type="text" id="order_total" name="order_total" placeholder="0.00" value="<?php echo esc_attr($_order->_fetch('order_total')); ?> " class="first" /> <?php echo $payment_select; ?> <script type="text/javascript"> /*<![CDATA[*/ jQuery(function() { jQuery("#payment_method").select2({ width: '120px' }); }); /*]]>*/ </script> </li> </ul> <div class="clear"></div> <?php }
function jigoshop_ga_ecommerce_tracking($order_id) { $options = Jigoshop_Base::get_options(); // Skip if disabled if ($options->get('jigoshop_ga_ecommerce_tracking_enabled') != 'yes') { return; } // Don't track the shop owners roaming if (current_user_can('manage_jigoshop')) { return; } $tracking_id = $options->get('jigoshop_ga_id'); if (!$tracking_id) { return; } // Get the order and output tracking code $order = new jigoshop_order($order_id); ?> <script type="text/javascript"> jigoshopGA('require', 'ecommerce'); jigoshopGA('ecommerce:addTransaction', { 'id': '<?php echo $order->get_order_number(); ?> ', // Transaction ID. Required. 'affiliation': '<?php bloginfo('name'); ?> ', // Affiliation or store name. 'revenue': '<?php echo $order->order_total; ?> ', // Grand Total. 'shipping': '<?php echo $order->order_shipping; ?> ', // Shipping. 'tax': '<?php echo $order->get_total_tax(); ?> ' // Tax. }); <?php foreach ($order->items as $item) { $_product = $order->get_product_from_item($item); ?> jigoshopGA('ecommerce:addItem', { 'id': '<?php echo $order->get_order_number(); ?> ', // Transaction ID. Required. 'name': '<?php echo $item['name']; ?> ', // Product name. Required. 'sku': '<?php echo $_product->sku; ?> ', // SKU/code. 'category': '<?php if (isset($_product->variation_data)) { echo jigoshop_get_formatted_variation($_product, $item['variation'], true); } ?> ', // Category or variation. 'price': '<?php echo $item['cost'] / $item['qty']; ?> ', // Unit price. 'quantity': '<?php echo $item['qty']; ?> ' // Quantity. }); <?php } ?> jigoshopGA('ecommerce:send'); </script> <?php }
function jigoshop_process_shop_order_meta($post_id) { $jigoshop_options = Jigoshop_Base::get_options(); $jigoshop_errors = array(); $order = new jigoshop_order($post_id); // Get old data + attributes $data = (array) maybe_unserialize(get_post_meta($post_id, 'order_data', true)); //Get old order items $old_order_items = (array) maybe_unserialize(get_post_meta($post_id, 'order_items', true)); // Add/Replace data to array $customerDetails = array('billing_first_name', 'billing_last_name', 'billing_company', 'billing_euvatno', 'billing_address_1', 'billing_address_2', 'billing_city', 'billing_postcode', 'billing_country', 'billing_state', 'billing_email', 'billing_phone', 'shipping_first_name', 'shipping_last_name', 'shipping_company', 'shipping_address_1', 'shipping_address_2', 'shipping_city', 'shipping_postcode', 'shipping_country', 'shipping_state'); $order_fields = array('shipping_method', 'shipping_service', 'payment_method', 'order_subtotal', 'order_discount_subtotal', 'order_shipping', 'order_discount', 'order_discount_coupons', 'order_tax_total', 'order_shipping_tax', 'order_total', 'order_total_prices_per_tax_class_ex_tax'); /* Pre-fill the customer addresses */ foreach ($customerDetails as $key) { $order_fields[] = $key; /* Checks if this is a new order from "Add Order" button */ if (!empty($_POST['auto_draft']) && !empty($_POST['customer_user']) && empty($_POST[$key])) { $data[$key] = get_user_meta($_POST['customer_user'], $key, true); } } //Check EUVAT Field if (!empty($data['billing_euvatno']) && !empty($data['billing_country'])) { $data['billing_euvatno'] = str_replace(' ', '', $data['billing_euvatno']); } //run stripslashes on all valid fields foreach ($order_fields as $field_name) { if (isset($_POST[$field_name])) { $data[$field_name] = stripslashes($_POST[$field_name]); } } // Sanitize numeric values $data['order_total'] = jigoshop_sanitize_num($data['order_total']); $data['order_subtotal'] = jigoshop_sanitize_num($data['order_subtotal']); // if a shipping or payment methods has changed, update the method title for pretty display if (isset($_POST['shipping_method'])) { $data['shipping_service'] = ''; $shipping_methods = jigoshop_shipping::get_all_methods(); if (!empty($shipping_methods)) { foreach ($shipping_methods as $method) { if ($_POST['shipping_method'] == $method->id) { $data['shipping_service'] = $method->title; } } } } if (isset($_POST['payment_method'])) { $data['payment_method_title'] = ''; $payment_methods = jigoshop_payment_gateways::get_available_payment_gateways(); if (!empty($payment_methods)) { foreach ($payment_methods as $method) { if ($_POST['payment_method'] == $method->id) { $data['payment_method_title'] = $method->title; } } } } // if total tax has been modified from order tax, then create a customized tax array // just for the order. At this point, we no longer know about multiple tax classes. // Even if we used the old tax array data, we still don't know how to break down // the amounts since they're customized. if (isset($data['order_tax_total']) && $order->get_total_tax() != $data['order_tax_total']) { $new_tax = $data['order_tax_total']; $data['order_tax'] = jigoshop_tax::create_custom_tax($data['order_total'] - $data['order_tax_total'], $data['order_tax_total'], $data['order_shipping_tax'], isset($data['order_tax_divisor']) ? $data['order_tax_divisor'] : null); } // Customer update_post_meta($post_id, 'customer_user', (int) $_POST['customer_user']); // Order items $order_items = array(); if (isset($_POST['item_id'])) { $item_id = $_POST['item_id']; $item_variation = $_POST['item_variation_id']; $item_name = $_POST['item_name']; $item_quantity = $_POST['item_quantity']; $item_cost = $_POST['item_cost']; $item_tax_rate = $_POST['item_tax_rate']; for ($i = 0; $i < count($item_id); $i++) { if (!isset($item_id[$i]) || !isset($item_name[$i]) || !isset($item_quantity[$i]) || !isset($item_cost[$i]) || !isset($item_tax_rate[$i])) { continue; } $variation_id = ''; $variation = ''; if (!empty($item_variation[$i])) { $variation_id = (int) $item_variation[$i]; // if this is a variation, we should check if it is an old one // and copy the 'variation' field describing details of variation foreach ($old_order_items as $old_item_index => $old_item) { if ($old_item['variation_id'] == $variation_id) { $variation = $old_item['variation']; unset($old_order_items[$old_item_index]); break; } } // override variation with values from $_POST if (isset($_POST['order_attributes'][$i]) && is_array($_POST['order_attributes'][$i])) { foreach ($_POST['order_attributes'][$i] as $var_key => $var_value) { $variation[$var_key] = $var_value; } } } $cost_inc_tax = $jigoshop_options->get('jigoshop_prices_include_tax') == 'yes' ? number_format((double) jigowatt_clean($item_cost[$i]), 2, '.', '') : -1; $order_items[] = apply_filters('update_order_item', array('id' => htmlspecialchars(stripslashes($item_id[$i])), 'variation_id' => $variation_id, 'variation' => $variation, 'name' => htmlspecialchars(stripslashes($item_name[$i])), 'qty' => (int) $item_quantity[$i], 'cost' => number_format((double) jigowatt_clean($item_cost[$i]), 2, '.', ''), 'cost_inc_tax' => $cost_inc_tax, 'taxrate' => number_format((double) jigowatt_clean($item_tax_rate[$i]), 4, '.', ''))); } } // Process custom attributes added with "jigoshop_order_data_panels" $data = apply_filters("jigoshop_order_data_save", $data, $post_id); // Save update_post_meta($post_id, 'order_data', $data); update_post_meta($post_id, 'order_items', $order_items); // Order status $order->update_status($_POST['order_status']); // Handle button actions if (isset($_POST['reduce_stock']) && $_POST['reduce_stock'] && count($order_items) > 0) { $order->add_order_note(__('Manually reducing stock.', 'jigoshop')); foreach ($order_items as $order_item) { $_product = $order->get_product_from_item($order_item); if ($_product->exists) { if ($_product->managing_stock()) { $old_stock = $_product->stock; $new_quantity = $_product->reduce_stock($order_item['qty']); $order->add_order_note(sprintf(__('Item #%s stock reduced from %s to %s.', 'jigoshop'), $order_item['id'], $old_stock, $new_quantity)); if ($new_quantity < 0) { if ($old_stock < 0) { $backorder_qty = $order_item['qty']; } else { $backorder_qty = $old_stock - $order_item['qty']; } do_action('jigoshop_product_on_backorder_notification', $post_id, $_product, $backorder_qty); } // stock status notifications if ($jigoshop_options->get('jigoshop_notify_no_stock') == 'yes' && $jigoshop_options->get('jigoshop_notify_no_stock_amount') >= 0 && $jigoshop_options->get('jigoshop_notify_no_stock_amount') >= $new_quantity) { do_action('jigoshop_no_stock_notification', $_product); } else { if ($jigoshop_options->get('jigoshop_notify_low_stock') == 'yes' && $jigoshop_options->get('jigoshop_notify_low_stock_amount') >= $new_quantity) { do_action('jigoshop_low_stock_notification', $_product); } } } } else { $order->add_order_note(sprintf(__('Item %s %s not found, skipping.', 'jigoshop'), $order_item['id'], $order_item['name'])); } } $order->add_order_note(__('Manual stock reduction complete.', 'jigoshop')); } else { if (isset($_POST['restore_stock']) && $_POST['restore_stock'] && sizeof($order_items) > 0) { $order->add_order_note(__('Manually restoring stock.', 'jigoshop')); foreach ($order_items as $order_item) { $_product = $order->get_product_from_item($order_item); if ($_product->exists) { if ($_product->managing_stock()) { $old_stock = $_product->stock; $new_quantity = $_product->increase_stock($order_item['qty']); $order->add_order_note(sprintf(__('Item #%s stock increased from %s to %s.', 'jigoshop'), $order_item['id'], $old_stock, $new_quantity)); } } else { $order->add_order_note(sprintf(__('Item %s %s not found, skipping.', 'jigoshop'), $order_item['id'], $order_item['name'])); } } $order->add_order_note(__('Manual stock restore complete.', 'jigoshop')); } else { if (isset($_POST['invoice']) && $_POST['invoice']) { // Mail link to customer jigoshop_send_customer_invoice($order->id); } } } // Error Handling if (count($jigoshop_errors) > 0) { $jigoshop_options->set('jigoshop_errors', $jigoshop_errors); } }