【问题标题】:Programmatically creating new order in Woocommerce在 Woocommerce 中以编程方式创建新订单
【发布时间】:2016-08-12 07:11:23
【问题描述】:

我在 WooCommerce 中以编程方式创建订单最困难。我正在使用下面的代码,并且确实创建了订单,但我无法获取客户信息或添加到订单中的产品线项目。创建的新订单只是作为访客,没有项目、用户信息等。

问题似乎是,一旦创建了订单对象,尝试向订单添加数据时就会失败。

function create_vip_order() {

  global $woocommerce;

  $address = array(
      'first_name' => '111Joe',
      'last_name'  => 'Conlin',
      'company'    => 'Speed Society',
      'email'      => 'joe@testing.com',
      'phone'      => '760-555-1212',
      'address_1'  => '123 Main st.',
      'address_2'  => '104',
      'city'       => 'San Diego',
      'state'      => 'Ca',
      'postcode'   => '92121',
      'country'    => 'US'
  );

  // Now we create the order
  $order = wc_create_order();

  // The add_product() function below is located in /plugins/woocommerce/includes/abstracts/abstract_wc_order.php
  $order->add_product( get_product( '275962' ), 1 ); // This is an existing SIMPLE product
  $order->set_address( $address, 'billing' );
  //
  $order->calculate_totals();
  $order->update_status("Completed", 'Imported order', TRUE);

}

add_action( 'woocommerce_init', 'create_vip_order' );

这是我在日志中遇到的错误:

[19-Apr-2016 21:16:38 UTC] PHP Fatal error:  Uncaught Error: Call to a member function add_product() on boolean in /Users/joe/Sites/speedsociety-2/wp-content/themes/ss/lib/contests/order.php:107
Stack trace:
#0 /Users/joe/Sites/speedsociety-2/wp-includes/plugin.php(525): create_vip_order('')
#1 /Users/joe/Sites/speedsociety-2/wp-content/plugins/woocommerce/woocommerce.php(330): do_action('woocommerce_ini...')
#2 /Users/joe/Sites/speedsociety-2/wp-includes/plugin.php(525): WooCommerce->init('')
#3 /Users/joe/Sites/speedsociety-2/wp-settings.php(392): do_action('init')
#4 /Users/joe/Sites/speedsociety-2/wp-config.php(67): require_once('/Users/joe/Site...')
#5 /Users/joe/Sites/speedsociety-2/wp-load.php(37): require_once('/Users/joe/Site...')
#6 /Users/joe/Sites/speedsociety-2/wp-admin/admin.php(31): require_once('/Users/joe/Site...')
#7 /Users/joe/Sites/speedsociety-2/wp-admin/edit.php(10): require_once('/Users/joe/Site...')
#8 {main}
  thrown in /Users/joe/Sites/speedsociety-2/wp-content/themes/ss/lib/contests/order.php on line 107

对此的任何帮助将不胜感激!

【问题讨论】:

  • 没有看到 add_product 函数,我们只能猜测,但很可能是问题所在。
  • 它是 WooCommerce 的一个函数,我现在已经在代码中包含了这个函数的完整路径。经过研究,在我发现使用 $order->add_product、$order->set_address 等的大多数示例中似乎很常见。如果有其他方法我应该这样做,请告诉我。
  • 当 $product 或 $item_id 不存在时,该函数似乎返回 false。您可能想查看是否传递了有效变量。使用对象时,建议在 try/catch 块中运行您的代码,以便它们可以捕获错误,尽管我不熟悉 woocommerce 类有多少错误处理。
  • 试试woocommerce_loaded... 因为wc_create_order 需要woocommerce_init...

标签: php wordpress woocommerce


【解决方案1】:

我实际上无法弄清楚您的问题,但为您提供另一种选择,这可能会对您有所帮助。

我首先在$woocommerce->cart 中添加了产品,然后将该购物车数据分配给这样创建的新订单:

//对于简单的产品

$woocommerce->cart->add_to_cart($product_id, $quantity);

//对于可变产品

    $woocommerce->cart->add_to_cart($product_id, $quantity, $variationID, $attr_array);

    $order_data = array(
         'status' => apply_filters('woocommerce_default_order_status', 'processing'),
         'customer_id' => $user_id
    );
    $new_order = wc_create_order($order_data);
    foreach ($woocommerce->cart->get_cart() as $cart_item_key => $values) {
            $item_id = $new_order->add_product(
                    $values['data'], $values['quantity'], array(
                'variation' => $values['variation'],
                'totals' => array(
                    'subtotal' => $values['line_subtotal'],
                    'subtotal_tax' => $values['line_subtotal_tax'],
                    'total' => $values['line_total'],
                    'tax' => $values['line_tax'],
                    'tax_data' => $values['line_tax_data'] // Since 2.2
                )
                    )
            );
        }
    $new_order->set_address($address, 'billing');
    $new_order->set_address($address, 'shipping');

【讨论】:

  • @Maha..我尝试了这段代码,但仍然出现成员函数错误。 Fatal error: Uncaught Error: Call to a member function add_to_cart() on null in /Users/joe...
  • 您是否使用我的代码声明了$woocommerce global?
  • 是的,声明了 $woocommerce 并且仍然出现错误。在新版本上也试过这个,结果相同,所以我正在使用的代码仍然存在问题。
  • Ofcorse woocommerce_init 会出现这个问题,因为 woocommerce 组件尚未正确加载。你需要改变你的钩子。
  • @MahaDev 我也有同样的问题,但我不确定你所说的改变钩子是什么意思。我假设,你的意思是添加一个函数来获取丢失的初始化变量并返回它们,但我不太确定这是什么样的。我有$checkout_url = $woocommerce->cart->get_checkout_url(); 并且收到call to member function get_checkout_url() on null 消息...我的电话是在我使用 wc_create_order() 创建订单后直接打来的...所以我猜我必须先以编程方式将订单添加到购物车或者我必须启动其他东西......想法?
【解决方案2】:

问题出在你的动作钩子上。使用以下钩子:

add_action('woocommerce_checkout_process', 'create_vip_order');

function create_vip_order() {

  global $woocommerce;

  $address = array(
      'first_name' => '111Joe',
      'last_name'  => 'Conlin',
      'company'    => 'Speed Society',
      'email'      => 'joe@testing.com',
      'phone'      => '760-555-1212',
      'address_1'  => '123 Main st.',
      'address_2'  => '104',
      'city'       => 'San Diego',
      'state'      => 'Ca',
      'postcode'   => '92121',
      'country'    => 'US'
  );

  // Now we create the order
  $order = wc_create_order();

  // The add_product() function below is located in /plugins/woocommerce/includes/abstracts/abstract_wc_order.php
  $order->add_product( get_product('275962'), 1); // This is an existing SIMPLE product
  $order->set_address( $address, 'billing' );
  //
  $order->calculate_totals();
  $order->update_status("Completed", 'Imported order', TRUE);  
}

确保给定的产品 ID 应该存在于系统中。

【讨论】:

  • Prolem 与 woocommerce_init 挂钩,有几个人指出了这一点,但我奖励你第一个提供完整“答案”的赏金。感谢您的帮助!
  • 很高兴我的回答对您有所帮助。谢谢。 :)
  • 现在应该使用“wc_get_product”而不是“get_product”
【解决方案3】:

你几乎拥有它,add_action( 'woocommerce_init', 'create_vip_order' ); woocommerce_init 太早了,你需要把你的钩子至少改成init, 你的错误

[19-Apr-2016 21:16:38 UTC] PHP Fatal error:  Uncaught Error: Call to a member function add_product() on boolean in /Users/joe/Sites/speedsociety-2/wp-content/themes/ss/lib/contests/order.php:107
Stack trace:
#0 /Users/joe/Sites/speedsociety-2/wp-includes/plugin.php(525): create_vip_order('')
#1 /Users/joe/Sites/speedsociety-2/wp-content/plugins/woocommerce/woocommerce.php(330): do_action('woocommerce_ini...')
#2 /Users/joe/Sites/speedsociety-2/wp-includes/plugin.php(525): WooCommerce->init('')
#3 /Users/joe/Sites/speedsociety-2/wp-settings.php(392): do_action('init')
#4 /Users/joe/Sites/speedsociety-2/wp-config.php(67): require_once('/Users/joe/Site...')
#5 /Users/joe/Sites/speedsociety-2/wp-load.php(37): require_once('/Users/joe/Site...')
#6 /Users/joe/Sites/speedsociety-2/wp-admin/admin.php(31): require_once('/Users/joe/Site...')
#7 /Users/joe/Sites/speedsociety-2/wp-admin/edit.php(10): require_once('/Users/joe/Site...')
#8 {main}
  thrown in /Users/joe/Sites/speedsociety-2/wp-content/themes/ss/lib/contests/order.php on line 107

表明它正在发生 $order 变量已返回 false,因此您不能使用 $order->add_product

这是我的工作代码

function create_vip_order() {

  global $woocommerce;

  $address = array(
      'first_name' => '111Joe',
      'last_name'  => 'Conlin',
      'company'    => 'Speed Society',
      'email'      => 'joe@testing.com',
      'phone'      => '760-555-1212',
      'address_1'  => '123 Main st.',
      'address_2'  => '104',
      'city'       => 'San Diego',
      'state'      => 'Ca',
      'postcode'   => '92121',
      'country'    => 'US'
  );

  // Now we create the order
  $order = wc_create_order();

  // The add_product() function below is located in /plugins/woocommerce/includes/abstracts/abstract_wc_order.php
  $order->add_product( get_product( '129' ), 1 ); // This is an existing SIMPLE product
  $order->set_address( $address, 'billing' );
  //
  $order->calculate_totals();
  $order->update_status("Completed", 'Imported order', TRUE);

}

add_action( 'init', 'create_vip_order' );

祝你好运,编码愉快:D

【讨论】:

  • 你是对的,但必须将赏金奖励给@maha,因为他首先回答但想说谢谢你的回答。
【解决方案4】:

不用 wc_create_order 函数你也可以做到这一点。

            $order_data                        = array();
            $order_data[ 'post_type' ]         = 'shop_order';
            $order_data[ 'post_status' ]       = 'wc-' . apply_filters( 'woocommerce_default_order_status', 'pending' );
            $order_data[ 'ping_status' ]       = 'closed';
            $order_data[ 'post_author' ]       = 1;
            $order_data[ 'post_password' ]     = uniqid( 'order_' );
            $order_data[ 'post_title' ]        = sprintf( __( 'Order – %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Order date parsed by strftime', 'woocommerce' ), strtotime( $post_date ) ) );
            $order_data[ 'post_parent' ]       = 12; // parent post id
            $order_data[ 'post_content' ]      = "";
            $order_data[ 'comment_status' ]    = "open";
            $order_data[ 'post_name' ]         = sanitize_title( sprintf( __( 'Order – %s', 'woocommerce' ), strftime( _x( '%b %d, %Y @ %I:%M %p', 'Order date parsed by strftime', 'woocommerce' ), strtotime( $post_date) ) ) );

            $order_id = wp_insert_post( apply_filters( 'woocommerce_new_order_data', $order_data ), true );

然后您可以使用此 $order_id 添加其他详细信息,例如...

$order = wc_get_order( $order_id );
$product_item_id = $order->add_product( wc_get_product( $product_id ));
wc_add_order_item_meta($product_item_id,"meta_key","meta_values");
$addressShipping = array(
       'first_name' => $shippingName,
       'email'      => $user_email_id,
       'phone'      => $billingPhone,
       'address_1'  => $shippingAddress,
       'address_2'  => $shippingAddress2,
       'city'       => $shippingCity,
       'state'      => $shippingStateCode,
       'postcode'   => $shippingZip,
       'country'    => 'US');
$order->set_address( $addressShipping, 'shipping' );
    $addressBilling = array(
       'first_name' => $billingName,
       'email'      => $user_email_id,
       'phone'      => $billingPhone,
       'address_1'  => $billingAddress,
       'address_2'  => $billingAddress2,
       'city'       => $billingCity,
       'state'      => $billingStateCode,
       'postcode'   => $billingZip,
       'country'    => 'US');
$order->set_address( $addressBilling, 'billing' );
$order->calculate_totals();

【讨论】:

  • 在没有 wc API 的情况下这样做
  • 我有一个自定义表单,我想根据表单项创建一个订单,表单保存后我有钩子,创建这个自定义订单后如何重定向客户到结帐页面?
猜你喜欢
  • 2018-08-06
  • 2013-06-14
  • 1970-01-01
  • 2014-12-22
  • 2018-08-21
  • 2013-03-19
  • 2019-10-14
  • 2021-03-01
  • 1970-01-01
相关资源
最近更新 更多