Php 使用Woocommerce 3+;中的行项目以编程方式创建订单;
我需要以编程方式创建Woocommerce订单,但是使用“旧”Woocommerce使这成为一个非常肮脏的过程 我必须手动插入所有类型的数据库记录,使用许多update\u post\u meta调用Php 使用Woocommerce 3+;中的行项目以编程方式创建订单;,php,wordpress,woocommerce,methods,orders,Php,Wordpress,Woocommerce,Methods,Orders,我需要以编程方式创建Woocommerce订单,但是使用“旧”Woocommerce使这成为一个非常肮脏的过程 我必须手动插入所有类型的数据库记录,使用许多update\u post\u meta调用 正在寻找更好的解决方案。随着新版本的WC 2的发布,它变得更好了 然而: 我不想使用RESTAPI,因为我直接从我自己的WP插件进行调用。我认为对本地主机进行卷曲没有用 “”对我没有用处,因为它在REST API上,不支持Create Order调用 老实说,WooCom是有限的,也许他们还在
正在寻找更好的解决方案。随着新版本的WC 2的发布,它变得更好了 然而:
- 我不想使用RESTAPI,因为我直接从我自己的WP插件进行调用。我认为对本地主机进行卷曲没有用
- “”对我没有用处,因为它在REST API上,不支持Create Order调用
class WP_MyPlugin_woocommerce
{
public static function init()
{
// required classes to create an order
require_once WOOCOMMERCE_API_DIR . 'class-wc-api-exception.php';
require_once WOOCOMMERCE_API_DIR . 'class-wc-api-server.php';
require_once WOOCOMMERCE_API_DIR . 'class-wc-api-resource.php';
require_once WOOCOMMERCE_API_DIR . 'interface-wc-api-handler.php';
require_once WOOCOMMERCE_API_DIR . 'class-wc-api-json-handler.php';
require_once WOOCOMMERCE_API_DIR . 'class-wc-api-orders.php';
}
public static function create_order()
{
global $wp;
// create order
$server = new WC_API_Server( $wp->query_vars['wc-api-route'] );
$order = new WC_API_Orders( $server );
$order_id = $order->create_order( array
(
'order' => array
(
'status' => 'processing'
, 'customer_id' => get_current_user_id()
// , 'order_meta' => array
// (
// 'some order meta' => 'a value
// , some more order meta' => 1
// )
, 'shipping_address' => array
(
'first_name' => $firstname
, 'last_name' => $lastname
, 'address_1' => $address
, 'address_2' => $address2
, 'city' => $city
, 'postcode' => $postcode
, 'state' => $state
, 'country' => $country
)
, 'billing_address' => array(..can be same as shipping )
, 'line_items' => array
(
array
(
'product_id' => 258
, 'quantity' => 1
)
)
)
) );
var_dump($order_id);
die();
}
}
重要:
- “WOOCOMMERCE\u API\u DIR”常量指向插件目录中的“/WOOCOMMERCE/includes/API/”
- 订单分配给客户,在我的情况下是当前登录的用户。确保您的用户具有能够读取、编辑、创建和删除订单的角色。我的角色如下:
$result = add_role( 'customer' , __( 'Customer' ) , array ( 'read' => true // , 'read_private_posts' => true // , 'read_private_products' => true , 'read_private_shop_orders' => true , 'edit_private_shop_orders' => true , 'delete_private_shop_orders' => true , 'publish_shop_orders' => true // , 'read_private_shop_coupons' => true , 'edit_posts' => false , 'delete_posts' => false , 'show_admin_bar_front' => false ) );
- 如果你想看看商店经理的,查一下 var_dump(get_选项(“wp_用户角色”)
希望我帮了你的忙,我花了一些时间才把它做好。最新版本的WooCommerce可能会让你像这样尝试一下
$address = array(
'first_name' => 'Fresher',
'last_name' => 'StAcK OvErFloW',
'company' => 'stackoverflow',
'email' => 'test@test.com',
'phone' => '777-777-777-777',
'address_1' => '31 Main Street',
'address_2' => '',
'city' => 'Chennai',
'state' => 'TN',
'postcode' => '12345',
'country' => 'IN'
);
$order = wc_create_order();
$order->add_product( get_product( '12' ), 2 ); //(get_product with id and next is for quantity)
$order->set_address( $address, 'billing' );
$order->set_address( $address, 'shipping' );
$order->add_coupon('Fresher','10','2'); // accepted param $couponcode, $couponamount,$coupon_tax
$order->calculate_totals();
用你的函数调用上面的代码,它就会相应地工作
注意,它不适用于WooCommerce的旧版本,如2.1.12,它只适用于WooCommerce的2.2版本。
希望它对WooCommerce 3及以上的2017-2021年有所帮助 Woocommerce 3已经引入了CRUD对象,订单项目也有很多变化……另外一些
WC\u Order
方法现在已经被弃用,如add\u-coupon()
这是一个函数,允许通过编程方式创建订单,其中包含所有必需的数据,包括税费:
function create_wc_order( $data ){
$gateways = WC()->payment_gateways->get_available_payment_gateways();
$order = new WC_Order();
// Set Billing and Shipping adresses
foreach( array('billing_', 'shipping_') as $type ) {
foreach ( $data['address'] as $key => $value ) {
if( $type === 'shipping_' && in_array( $key, array( 'email', 'phone' ) ) )
continue;
$type_key = $type.$key;
if ( is_callable( array( $order, "set_{$type_key}" ) ) ) {
$order->{"set_{$type_key}"}( $value );
}
}
}
// Set other details
$order->set_created_via( 'programatically' );
$order->set_customer_id( $data['user_id'] );
$order->set_currency( get_woocommerce_currency() );
$order->set_prices_include_tax( 'yes' === get_option( 'woocommerce_prices_include_tax' ) );
$order->set_customer_note( isset( $data['order_comments'] ) ? $data['order_comments'] : '' );
$order->set_payment_method( isset( $gateways[ $data['payment_method'] ] ) ? $gateways[ $data['payment_method'] ] : $data['payment_method'] );
$calculate_taxes_for = array(
'country' => $data['address']['country'],
'state' => $data['address']['state'],
'postcode' => $data['address']['postcode'],
'city' => $data['address']['city']
);
// Line items
foreach( $data['line_items'] as $line_item ) {
$args = $line_item['args'];
$product = wc_get_product( isset($args['variation_id']) && $args['variation_id'] > 0 ? $$args['variation_id'] : $args['product_id'] );
$item_id = $order->add_product( $product, $line_item['quantity'], $line_item['args'] );
$item = $order->get_item( $item_id, false );
$item->calculate_taxes($calculate_taxes_for);
$item->save();
}
// Coupon items
if( isset($data['coupon_items'])){
foreach( $data['coupon_items'] as $coupon_item ) {
$order->apply_coupon(sanitize_title($coupon_item['code']));
}
}
// Fee items
if( isset($data['fee_items'])){
foreach( $data['fee_items'] as $fee_item ) {
$item = new WC_Order_Item_Fee();
$item->set_name( $fee_item['name'] );
$item->set_total( $fee_item['total'] );
$tax_class = isset($fee_item['tax_class']) && $fee_item['tax_class'] != 0 ? $fee_item['tax_class'] : 0;
$item->set_tax_class( $tax_class ); // O if not taxable
$item->calculate_taxes($calculate_taxes_for);
$item->save();
$order->add_item( $item );
}
}
// Set calculated totals
$order->calculate_totals();
if( isset($data['order_status']) ) {
// Update order status from pending to your defined status and save data
$order->update_status($data['order_status']['status'], $data['order_status']['note']);
$order_id = $order->get_id();
} else {
// Save order to database (returns the order ID)
$order_id = $order->save();
}
// Returns the order ID
return $order_id;
}
代码位于活动子主题(或活动主题)的function.php文件或插件文件中
数据数组的用法示例:
create_wc_order( array(
'address' => array(
'first_name' => 'Fresher',
'last_name' => 'StAcK OvErFloW',
'company' => 'stackoverflow',
'email' => 'test1@testoo.com',
'phone' => '777-777-777-777',
'address_1' => '31 Main Street',
'address_2' => '',
'city' => 'Chennai',
'state' => 'TN',
'postcode' => '12345',
'country' => 'IN',
),
'user_id' => '',
'order_comments' => '',
'payment_method' => 'bacs',
'order_status' => array(
'status' => 'on-hold',
'note' => '',
),
'line_items' => array(
array(
'quantity' => 1,
'args' => array(
'product_id' => 37,
'variation_id' => '',
'variation' => array(),
)
),
),
'coupon_items' => array(
array(
'code' => 'summer',
),
),
'fee_items' => array(
array(
'name' => 'Delivery',
'total' => 5,
'tax_class' => 0, // Not taxable
),
),
) );
很多答案都显示了最佳过滤器(挂钩)的使用。我搜索了好几天,因为当我使用“init”时,它不断发出更多的订单。在2分钟内,我收到了30份订单。无论如何,使用此代码,将创建一个订单。另外,将$product=wc\U get\U product('1001')更改为您的产品id。参考信息见第144行:
是的,这将绕过RESTAPI类。说得好。您可能不需要包含任何文件来实现此功能,对吗?短得多的解决方案,不错!我会尝试一下并让您知道。使用此函数
get\u class\u methods($order))
查看当您拥有order对象时哪些函数对您可用非常有帮助!美好的我会打什么电话来下订单?根据我所做的,这与客户用户有关联。如何让它与当前登录的用户关联?我也有同样的问题。看起来像是某种API更改,因为它以前没有与来宾用户关联。在calculate_totals()之后添加以下内容以使其运行($orderId=ID为新创建的订单,$userId=wp的客户的用户ID):更新_post_meta($orderId,''u customer_user',$userId);请您检查我的问题。您是否处理了通知:woocommerce\u order\u add\u产品自3.0版起已弃用!当您调用add\u product时,请改用woocommerce\u new\u order\u item action?@Dan Yes,但它与此线程无关(在您的情况下是关于钩子的,具体取决于您尝试执行的操作)。你应该问一个新问题可能是…
function my_init2() {
$order = wc_create_order();
$order_id = $order->get_id();
$product = wc_get_product( '10001' );
$address = array(
'first_name' => 'John2',
'last_name' => 'Smith1',
'email' => 'johnsmith1@gmail.com',
);
//$order->date_created(2020-07-21 );
$order->add_product( $product, 1 );
$order->set_address( $address, 'billing' );
$order->set_created_via( 'programatically' );
$order->calculate_totals();
$order->set_total( $product->get_price() );
$order->update_status( 'wc-completed' );
error_log( '$order_id: ' . $order_id );
}
//add_action('admin_init','my_init2');
function my_run_only_once() {
if ( get_option( 'my_run_only_once_20' ) != 'completed' ) {
my_init2();
update_option( 'my_run_only_once_20', 'completed' );
}
}
add_action( 'admin_init', 'my_run_only_once' );