コード例 #1
1
 /**
  * Process payment for an order:
  * 1) If the order contains a subscription, process the initial subscription payment (could be $0 if a free trial exists)
  * 2) If the order contains a pre-order, process the pre-order total (could be $0 if the pre-order is charged upon release)
  * 3) Otherwise use the parent::process_payment() method for regular product purchases
  *
  * @since 2.0
  * @param int $order_id
  * @return array
  */
 public function process_payment($order_id)
 {
     global $wc_braintree;
     $order = $this->get_order($order_id);
     try {
         /* processing subscription */
         if ($wc_braintree->is_subscriptions_active() && WC_Subscriptions_Order::order_contains_subscription($order_id)) {
             return $this->process_subscription_payment($order);
             /* processing pre-order */
         } elseif ($wc_braintree->is_pre_orders_active() && WC_Pre_Orders_Order::order_contains_pre_order($order_id)) {
             return $this->process_pre_order_payment($order);
             /* processing regular product */
         } else {
             return parent::process_payment($order_id);
         }
     } catch (WC_Gateway_Braintree_Exception $e) {
         // mark order as failed, which adds an order note for the admin and displays a generic "payment error" to the customer
         $this->mark_order_as_failed($order, $e->getMessage());
         // add detailed debugging information
         $this->add_debug_message($e->getErrors());
     } catch (Braintree_Exception_Authorization $e) {
         $this->mark_order_as_failed($order, __('Authorization failed, ensure that your API key is correct and has permissions to create transactions.', WC_Braintree::TEXT_DOMAIN));
     } catch (Exception $e) {
         $this->mark_order_as_failed($order, sprintf(__('Error Type %s', WC_Braintree::TEXT_DOMAIN), get_class($e)));
     }
 }
コード例 #2
0
 /**
  * Check if order contains pre-orders.
  *
  * @param  int $order_id
  * @return bool
  */
 protected function order_contains_pre_order($order_id)
 {
     return class_exists('WC_Pre_Orders_Order') && WC_Pre_Orders_Order::order_contains_pre_order($order_id);
 }
 /**
  * Process the payment
  *
  * @param  int $order_id
  * @return array
  */
 public function process_payment($order_id)
 {
     // Processing subscription
     if (class_exists('WC_Subscriptions_Order') && WC_Subscriptions_Order::order_contains_subscription($order_id)) {
         return $this->process_subscription($order_id);
         // Processing pre-order
     } elseif (class_exists('WC_Pre_Orders_Order') && WC_Pre_Orders_Order::order_contains_pre_order($order_id)) {
         return $this->process_pre_order($order_id);
         // Processing regular product
     } else {
         return parent::process_payment($order_id);
     }
 }
コード例 #4
0
 /**
  * Marks the order as being a pre order if it contains pre order products in
  * case an order gets added manually from the administration panel
  *
  * @since 1.0.4
  * @param int $order_id id of the newly saved order
  * @return void
  */
 public function check_manual_order_for_pre_order_products($order_id)
 {
     // Make sure we are in the administration panel and we're saving an order
     if (!is_admin() || !isset($_POST['post_type']) || 'shop_order' != $_POST['post_type']) {
         return;
     }
     $order = new WC_Order($order_id);
     // Check if the order hasn't been processed already
     if (WC_Pre_Orders_Order::order_contains_pre_order($order)) {
         return;
     }
     // Order has not been processed yet (or doesn't contain pre orders)
     $contains_pre_orders = false;
     foreach ($order->get_items() as $item) {
         if ('line_item' == $item['type']) {
             $product = get_product($item['item_meta']['_product_id'][0]);
             if ('yes' == $product->wc_pre_orders_enabled) {
                 // Set correct flags for this order, making it a pre order
                 update_post_meta($order_id, '_wc_pre_orders_is_pre_order', 1);
                 update_post_meta($order_id, '_wc_pre_orders_when_charged', $product->wc_pre_orders_when_to_charge);
                 return;
             }
         }
     }
 }
 /**
  * Handle the pre-order initial payment/tokenization, or defer back to the normal payment
  * processing flow
  *
  * @since 4.1.0
  * @see SV_WC_Payment_Gateway::process_payment()
  * @param boolean $result the result of this pre-order payment process
  * @param int $order_id the order identifier
  * @return true|array true to process this payment as a regular transaction, otherwise
  *         return an array containing keys 'result' and 'redirect'
  */
 public function process_payment($result, $order_id)
 {
     if (WC_Pre_Orders_Order::order_contains_pre_order($order_id) && WC_Pre_Orders_Order::order_requires_payment_tokenization($order_id)) {
         $order = $this->get_gateway()->get_order($order_id);
         try {
             // using an existing tokenized payment method
             if (isset($order->payment->token) && $order->payment->token) {
                 // save the tokenized card info for completing the pre-order in the future
                 $this->get_gateway()->add_transaction_data($order);
             } else {
                 // otherwise tokenize the payment method
                 $order = $this->get_gateway()->create_payment_token($order);
             }
             // mark order as pre-ordered / reduce order stock
             WC_Pre_Orders_Order::mark_order_as_pre_ordered($order);
             // empty cart
             WC()->cart->empty_cart();
             // redirect to thank you page
             return array('result' => 'success', 'redirect' => $this->get_gateway()->get_return_url($order));
         } catch (SV_WC_Payment_Gateway_Exception $e) {
             $this->get_gateway()->mark_order_as_failed($order, sprintf(__('Pre-Order Tokenization attempt failed (%s)', 'woocommerce-plugin-framework'), $this->get_gateway()->get_method_title(), $e->getMessage()));
         }
     }
     // processing regular product
     return $result;
 }
コード例 #6
0
 /**
  * Automatically change the pre-order status when the order status changes
  * 1) Change the pre-order status to 'active' when the order status changes to 'pre-ordered'
  * 2) Change the pre-order status to 'active' when the order status changes to 'on-hold' -- this ensures the pre-orders using
  *    a gateway that does not call WC_Order::payment_complete() like BACS or Cheque will still show on the 'Manage Pre-Orders' page
  * 3) Change the pre-order status to 'cancelled' when the order status changes to 'cancelled' and the order contains a pre-order
  *
  * @since 1.0
  * @param int $order_id post ID of the order
  * @param string $old_order_status the prior order status
  * @param string $new_order_status the new order status
  */
 public function auto_update_pre_order_status($order_id, $old_order_status, $new_order_status)
 {
     // change to 'active' when changing order status to 'pre-ordered'
     if ('pre-ordered' === $new_order_status) {
         $this->update_pre_order_status($order_id, 'active');
     }
     // change to 'active when changing order status to on-hold
     if ('on-hold' === $new_order_status && $this->order_contains_pre_order($order_id)) {
         $this->update_pre_order_status($order_id, 'active');
     }
     // change to 'cancelled' when changing order status to 'cancelled', except when the pre-order status is already cancelled. this prevents sending double emails when bulk-cancelling pre-orders
     if ('cancelled' === $new_order_status && WC_Pre_Orders_Order::order_contains_pre_order($order_id) && 'cancelled' !== get_post_meta($order_id, '_wc_pre_orders_status', true)) {
         $this->update_pre_order_status($order_id, 'cancelled');
     }
 }
コード例 #7
0
 /**
  * Process the transaction after receiving the token from Amazon
  *
  * @since 2.0
  * @param WC_Order $order the WC Order object
  */
 protected function process_transaction(WC_Order $order)
 {
     /* processing subscription */
     if (wc_amazon_fps()->is_subscriptions_active() && WC_Subscriptions_Order::order_contains_subscription($order)) {
         // set the initial payment total
         $order->amazon_order_total = WC_Subscriptions_Order::get_total_initial_payment($order);
         // if there is a free trial, mark the order as paid, otherwise process it
         if (0 == $order->amazon_order_total) {
             $this->mark_order_as_processing($order);
         } else {
             parent::process_transaction($order);
         }
         /* processing pre-order */
     } elseif (wc_amazon_fps()->is_pre_orders_active() && WC_Pre_Orders_Order::order_contains_pre_order($order) && WC_Pre_Orders_Order::order_requires_payment_tokenization($order)) {
         // mark order as pre-ordered / reduce order stock
         WC_Pre_Orders_Order::mark_order_as_pre_ordered($order);
         /* processing regular product (or a pre-order charged upfront) */
     } else {
         parent::process_transaction($order);
     }
 }
コード例 #8
0
 /**
  * Maybe cancel pre order when product is trashed
  *
  * @param int $product_id Product ID
  * @return void
  */
 public function maybe_cancel_pre_order_product_trashed($product_id)
 {
     global $wpdb;
     $orders = $wpdb->get_results($wpdb->prepare("\n\t\t\t\tSELECT order_items.order_id\n\t\t\t\tFROM {$wpdb->prefix}woocommerce_order_items AS order_items\n\t\t\t\t\tLEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS order_itemmeta\n\t\t\t\t\tON order_itemmeta.order_item_id = order_items.order_item_id\n\t\t\t\tWHERE order_itemmeta.meta_key = '_product_id'\n\t\t\t\tAND order_itemmeta.meta_value = %d\n\t\t\t", $product_id));
     foreach ($orders as $order_data) {
         $order = new WC_Order($order_data->order_id);
         if (WC_Pre_Orders_Order::order_contains_pre_order($order) && WC_Pre_Orders_Manager::can_pre_order_be_changed_to('cancelled', $order)) {
             WC_Pre_Orders_Order::update_pre_order_status($order, 'cancelled');
         }
     }
 }
コード例 #9
0
 /**
  * updates order status to pre-ordered for orders that are charged upfront. This handles gateways that don't call
  * payment_complete(). Unfortunately status changes show like pending->processing/completed->pre-ordered
  *
  * @since 1.0
  * @param int $order_id the post ID of the order
  * @return string
  */
 public function update_manual_payment_complete_order_status($order_id)
 {
     $order = new WC_Order($order_id);
     // don't update status for non pre-order orders
     if (!WC_Pre_Orders_Order::order_contains_pre_order($order)) {
         return;
     }
     // don't update if pre-order will be charged upon release
     if (WC_Pre_Orders_Order::order_will_be_charged_upon_release($order)) {
         return;
     }
     // change order status to pre-ordered
     $order->update_status('pre-ordered');
 }
コード例 #10
0
 /**
  * Prevent order stock reduction when WC_Order::payment_complete() is called for a pre-order charged upon release.
  * Because order stock for pre-orders charged upon release is reduced during initial checkout, this prevents stock from
  * being reduced twice.
  *
  * @since 1.0
  * @param bool $reduce_stock whether to reduce stock for the order or not
  * @param int $order_id the post ID of the order
  * @return bool true if the order stock should be reduced, false otherwise
  */
 public function maybe_prevent_payment_complete_order_stock_reduction($reduce_stock, $order_id)
 {
     $order = new WC_Order($order_id);
     if (WC_Pre_Orders_Order::order_contains_pre_order($order) && WC_Pre_Orders_Order::order_will_be_charged_upon_release($order)) {
         $reduce_stock = false;
     }
     return $reduce_stock;
 }
コード例 #11
0
 /**
  * Handle the pre-order initial payment/tokenization, or defer back to the normal payment
  * processing flow
  *
  * @since 1.0
  * @see SV_WC_Payment_Gateway::process_payment()
  * @param boolean $result the result of this pre-order payment process
  * @param int $order_id the order identifier
  * @return true|array true to process this payment as a regular transaction, otherwise
  *         return an array containing keys 'result' and 'redirect'
  * @throws SV_WC_Payment_Gateway_Feature_Unsupported_Exception if pre-orders are not supported by this gateway or its current configuration
  */
 public function process_pre_order_payment($result, $order_id)
 {
     if (!$this->supports_pre_orders()) {
         throw new SV_WC_Payment_Gateway_Feature_Unsupported_Exception('Pre-Orders not supported by gateway');
     }
     if (WC_Pre_Orders_Order::order_contains_pre_order($order_id) && WC_Pre_Orders_Order::order_requires_payment_tokenization($order_id)) {
         $order = $this->get_order($order_id);
         try {
             // using an existing tokenized payment method
             if (isset($order->payment->token) && $order->payment->token) {
                 // save the tokenized card info for completing the pre-order in the future
                 $this->add_transaction_data($order);
             } else {
                 // otherwise tokenize the payment method
                 $order = $this->create_payment_token($order);
             }
             // mark order as pre-ordered / reduce order stock
             WC_Pre_Orders_Order::mark_order_as_pre_ordered($order);
             // empty cart
             SV_WC_Plugin_Compatibility::WC()->cart->empty_cart();
             // redirect to thank you page
             return array('result' => 'success', 'redirect' => $this->get_return_url($order));
         } catch (Exception $e) {
             $this->mark_order_as_failed($order, sprintf(_x('Pre-Order Tokenization attempt failed (%s)', 'Supports direct payment method pre-orders', $this->text_domain), $this->get_method_title(), $e->getMessage()));
         }
     }
     // processing regular product
     return $result;
 }
コード例 #12
0
 /**
  * Process the payment
  *
  * @param  int $order_id
  * @return array
  */
 public function process_payment($order_id, $retry = true)
 {
     // Processing subscription
     if (function_exists('wcs_order_contains_subscription') && (wcs_order_contains_subscription($order_id) || wcs_is_subscription($order_id) || wcs_order_contains_renewal($order_id))) {
         return $this->process_subscription($order_id, $retry);
         // Processing pre-order
     } elseif (class_exists('WC_Pre_Orders_Order') && WC_Pre_Orders_Order::order_contains_pre_order($order_id)) {
         return $this->process_pre_order($order_id, $retry);
         // Processing regular product
     } else {
         return parent::process_payment($order_id, $retry);
     }
 }