17

我想以编程方式创建一个新订单。

工作流程很简单:提交简单的表单后,将创建用户以及随之而来的新订单。

我设法创建了一个新用户并返回了 user_id,现在我需要一步分配一个新订单。

我怎样才能做到这一点?

4

8 回答 8

16

这是我以编程方式创建订单的方式。我主要遵循上面@pavel 的建议中的 WC_Checkout::create_order() 。这直接来自我正在编写的插件,因此您必须调整源数据的来源。

// build order data
$order_data = array(
    'post_name'     => 'order-' . date_format($order_date, 'M-d-Y-hi-a'), //'order-jun-19-2014-0648-pm'
    'post_type'     => 'shop_order',
    'post_title'    => 'Order – ' . date_format($order_date, 'F d, Y @ h:i A'), //'June 19, 2014 @ 07:19 PM'
    'post_status'   => 'wc-completed',
    'ping_status'   => 'closed',
    'post_excerpt'  => $order->note,
    'post_author'   => $account->user_id,
    'post_password' => uniqid( 'order_' ),   // Protects the post just in case
    'post_date'     => date_format($order_date, 'Y-m-d H:i:s e'), //'order-jun-19-2014-0648-pm'
    'comment_status' => 'open'
);

// create order
$order_id = wp_insert_post( $order_data, true );

if ( is_wp_error( $order_id ) ) {

    $order->errors = $order_id;

} else {

    $order->imported = true;

    // add a bunch of meta data
    add_post_meta($order_id, 'transaction_id', $order->transaction_id, true); 
    add_post_meta($order_id, '_payment_method_title', 'Import', true);
    add_post_meta($order_id, '_order_total', $order->gross, true);
    add_post_meta($order_id, '_customer_user', $account->user_id, true);
    add_post_meta($order_id, '_completed_date', date_format( $order_date, 'Y-m-d H:i:s e'), true);
    add_post_meta($order_id, '_order_currency', $order->currency, true);
    add_post_meta($order_id, '_paid_date', date_format( $order_date, 'Y-m-d H:i:s e'), true);

    // billing info
    add_post_meta($order_id, '_billing_address_1', $order->address_line_1, true);
    add_post_meta($order_id, '_billing_address_2', $order->address_line_2, true);
    add_post_meta($order_id, '_billing_city', $order->city, true);
    add_post_meta($order_id, '_billing_state', $order->state, true);
    add_post_meta($order_id, '_billing_postcode', $order->zip, true);
    add_post_meta($order_id, '_billing_country', $order->country, true);
    add_post_meta($order_id, '_billing_email', $order->from_email, true);
    add_post_meta($order_id, '_billing_first_name', $order->first_name, true);
    add_post_meta($order_id, '_billing_last_name', $order->last_name, true);
    add_post_meta($order_id, '_billing_phone', $order->phone, true);

    // get product by item_id
    $product = get_product_by_sku( $order->item_id );

    if( $product ) {

        // add item
        $item_id = wc_add_order_item( $order_id, array(
            'order_item_name'       => $product->get_title(),
            'order_item_type'       => 'line_item'
        ) );

        if ( $item_id ) {

            // add item meta data
            wc_add_order_item_meta( $item_id, '_qty', 1 ); 
            wc_add_order_item_meta( $item_id, '_tax_class', $product->get_tax_class() );
            wc_add_order_item_meta( $item_id, '_product_id', $product->ID );
            wc_add_order_item_meta( $item_id, '_variation_id', '' );
            wc_add_order_item_meta( $item_id, '_line_subtotal', wc_format_decimal( $order->gross ) );
            wc_add_order_item_meta( $item_id, '_line_total', wc_format_decimal( $order->gross ) );
            wc_add_order_item_meta( $item_id, '_line_tax', wc_format_decimal( 0 ) );
            wc_add_order_item_meta( $item_id, '_line_subtotal_tax', wc_format_decimal( 0 ) );

        }

        // set order status as completed
        wp_set_object_terms( $order_id, 'completed', 'shop_order_status' );

        // if downloadable 
        if( $product->is_downloadable() ) {

            // add downloadable permission for each file
            $download_files = $product->get_files();
            foreach ( $download_files as $download_id => $file ) {
                wc_downloadable_file_permission( $download_id, $product->id, new WC_Order( $order_id ) );
            }

        }

    } else {

        $order->errors = 'Product SKU (' . $order->$item_id . ') not found.';
    }
}


function get_product_by_sku( $sku ) {

    global $wpdb;

    $product_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_sku' AND meta_value='%s' LIMIT 1", $sku ) );

    if ( $product_id ) return new WC_Product( $product_id );

    return null;
}

订单类

这是我在导入 WordPress/WooCommerce 之前用来存储订单的临时类。

class ImportOrder
{
    // public vars
    public $date;
    public $time;
    public $time_zone;
    public $first_name;
    public $middle_name;
    public $last_name;
    public $type;
    public $status;
    public $currency;
    public $gross;
    public $fee;
    public $net;
    public $note;
    public $to_email;
    public $from_email;
    public $transaction_id;
    public $counterparty_status;
    public $address_status;
    public $item_title;
    public $item_id;
    public $address_line_1;
    public $address_line_2;
    public $city;
    public $state;
    public $zip;
    public $country;
    public $phone;
    public $imported;
    public $errors;
}

添加订单

此处的数据是从 PayPal CSV 下载的历史交易中导入的。$row 变量代表 CSV 中的一行。您可以根据自己的需要进行调整。

function add_import_order( $row ) {

    // create new order
    $order = new ImportOrder();

    // done this before?
    $order->exists = order_exists( $row[PayPalCols::TRANSACTION_ID] );

    // add a bunch of fields
    $order->date = $row[PayPalCols::DATE];
    $order->time = $row[PayPalCols::TIME];
    $order->time_zone = $row[PayPalCols::TIME_ZONE];
    $order->type = $row[PayPalCols::TYPE];
    $order->status = $row[PayPalCols::STATUS];
    $order->currency = $row[PayPalCols::CURRENCY];
    $order->gross = $row[PayPalCols::GROSS];
    $order->fee = $row[PayPalCols::FEE];
    $order->net = $row[PayPalCols::NET];
    $order->note = $row[PayPalCols::NOTE];
    $order->from_email = $row[PayPalCols::FROM_EMAIL];
    $order->to_email = $row[PayPalCols::TO_EMAIL];
    $order->transaction_id = $row[PayPalCols::TRANSACTION_ID];
    $order->counterparty_status = $row[PayPalCols::COUNTERPARTY_STATUS];
    $order->address_status = $row[PayPalCols::ADDRESS_STATUS];
    $order->item_title = $row[PayPalCols::ITEM_TITLE];
    $order->item_id = $row[PayPalCols::ITEM_ID];
    $order->address_line_1 = utf8_encode( $row[PayPalCols::ADDRESS_LINE_1] );
    $order->address_line_2 = utf8_encode( $row[PayPalCols::ADDRESS_LINE_2] );
    $order->city = utf8_encode( $row[PayPalCols::TOWN_CITY] );
    $order->state = utf8_encode( $row[PayPalCols::STATE] );
    $order->zip = utf8_encode( $row[PayPalCols::ZIP] );
    $order->country = utf8_encode( $row[PayPalCols::COUNTRY] );
    $order->phone = utf8_encode( $row[PayPalCols::PHONE] );

    return $order;

}
于 2014-06-30T17:37:45.907 回答
6

要创建新订单,您必须创建 Object of WC_Order,如果您在 WooCommerce 之外或在其中工作,function.php则首先定义全局$woocommerce变量。

因此,将只有 2 行代码。

global $woocommerce;

$order = new WC_Order( $order_id );

希望,它会帮助你。

于 2013-06-18T13:02:09.910 回答
6

从 WooCommerce 2.2(或者可能是 2.1,我不确定 100%)开始,现在有一个专门为此设计的功能。

wc_create_order( $args = array() )

使用以下默认参数。

$default_args = array(
    'status'        => '',
    'customer_id'   => null,
    'customer_note' => null,
    'order_id'      => 0
);

includes/wc-core-functions.php您可以在文件中看到整个函数。

于 2014-09-22T22:24:23.360 回答
6

有一种更简单的方法,使用wc_create_order(). 这是一个示例,它还添加了运输和产品行项目。它还创建了一个 Woocommerce 订阅,但是对于普通产品,您可以忽略该部分,相同的代码将起作用。

function create_test_sub() {

    $email = 'test@test.com';

    $start_date = '2015-01-01 00:00:00';

    $address = array(
        'first_name' => 'Jeremy',
        'last_name'  => 'Test',
        'company'    => '',
        'email'      => $email,
        'phone'      => '777-777-777-777',
        'address_1'  => '31 Main Street',
        'address_2'  => '', 
        'city'       => 'Auckland',
        'state'      => 'AKL',
        'postcode'   => '12345',
        'country'    => 'AU'
    );

    $default_password = wp_generate_password();

    if (!$user = get_user_by('login', $email)) $user = wp_create_user( $email, $default_password, $email );

    // I've used one product with multiple variations

    $parent_product = wc_get_product(22998);

    $args = array(
        'attribute_billing-period' => 'Yearly',
        'attribute_subscription-type' => 'Both'
    );

    $product_variation = $parent_product->get_matching_variation($args);

    $product = wc_get_product($product_variation);  

    // Each variation also has its own shipping class

    $shipping_class = get_term_by('slug', $product->get_shipping_class(), 'product_shipping_class');

    WC()->shipping->load_shipping_methods();
    $shipping_methods = WC()->shipping->get_shipping_methods();

    // I have some logic for selecting which shipping method to use; your use case will likely be different, so figure out the method you need and store it in $selected_shipping_method

    $selected_shipping_method = $shipping_methods['free_shipping'];

    $class_cost = $selected_shipping_method->get_option('class_cost_' . $shipping_class->term_id);

    $quantity = 1;

    // As far as I can see, you need to create the order first, then the sub

    $order = wc_create_order(array('customer_id' => $user->id));

    $order->add_product( $product, $quantity, $args);
    $order->set_address( $address, 'billing' );
    $order->set_address( $address, 'shipping' );

    $order->add_shipping((object)array (
        'id' => $selected_shipping_method->id,
        'label'    => $selected_shipping_method->title,
        'cost'     => (float)$class_cost,
        'taxes'    => array(),
        'calc_tax'  => 'per_order'
    ));

    $order->calculate_totals();

    $order->update_status("completed", 'Imported order', TRUE);

    // Order created, now create sub attached to it -- optional if you're not creating a subscription, obvs

    // Each variation has a different subscription period

    $period = WC_Subscriptions_Product::get_period( $product );
    $interval = WC_Subscriptions_Product::get_interval( $product );

    $sub = wcs_create_subscription(array('order_id' => $order->id, 'billing_period' => $period, 'billing_interval' => $interval, 'start_date' => $start_date));

    $sub->add_product( $product, $quantity, $args);
    $sub->set_address( $address, 'billing' );
    $sub->set_address( $address, 'shipping' );

    $sub->add_shipping((object)array (
        'id' => $selected_shipping_method->id,
        'label'    => $selected_shipping_method->title,
        'cost'     => (float)$class_cost,
        'taxes'    => array(),
        'calc_tax'  => 'per_order'
    ));

    $sub->calculate_totals();

    WC_Subscriptions_Manager::activate_subscriptions_for_order($order);

    print "<a href='/wp-admin/post.php?post=" . $sub->id . "&action=edit'>Sub created! Click here to edit</a>";
}
于 2016-02-09T23:10:53.553 回答
4

看看我的解决方案: 使用 line_item 以编程方式创建 Woocommerce 订单

像魅力一样工作并转到新 REST API 使用的正确 WC 类

于 2014-10-27T05:10:49.077 回答
0

不幸的是,恐怕我认为没有简单的方法可以做到这一点。

您需要使用添加订单发布wp_insert_post();,然后使用添加所有元数据update_post_meta()。然后,您需要添加 usingwoocommerce_add_order_item()woocommerce_add_order_item_meta()。最后,您需要使用 设置订单状态wp_set_object_terms()

这是相当多的步骤和陷阱。您需要仔细检查您的数据库并添加您需要处理和完成订单的所有数据和元数据。

于 2013-06-20T20:42:39.783 回答
0

在 woocommerce WC_Checkout 类中有一个“create_order”方法。您可以克隆 WC_Checkout 类,给它另一个名称,根据您的目的更改方法的代码并调用

include 'path_to_Cloned_WC_Checkout';
$chk = new Cloned_WC_Checkout();
$chk->create_order();

在表单处理程序中

于 2014-05-07T14:58:21.463 回答
0

也许这样..

    function insert_order_to_db($seller,$order_date){
        global $wpdb;
        $result   = $wpdb->query(
            "
            INSERT INTO `wp_posts`(`ID`, `post_author`, `post_date`, `post_date_gmt`, `post_content`, `post_title`, `post_excerpt`, `post_status`, `comment_status`, `ping_status`, `post_password`, `post_name`, `to_ping`, `pinged`, `post_modified`, `post_modified_gmt`, `post_content_filtered`, `post_parent`, `guid`, `menu_order`, `post_type`, `post_mime_type`, `comment_count`)

            VALUES (
            17188,
            $seller,
            '".date_format($order_date, 'Y-m-d H:i:s e')."',
            '".date_format($order_date, 'Y-m-d H:i:s e')."',
            'no',
            'Order &ndash;". date_format($order_date, 'F d, Y @ h:i A')."',
            'noxp',
            'wc-completed',
            'open',
            'close',
            '".uniqid( 'order_' )."',
            'order-". date_format($order_date, 'M-d-Y-hi-a')."',
            '',
            '',
            '2017-07-24',
            '2017-07-24',
            '',
            0,
            '',
            0,
            'shop_order',
            '',
            0)

            "
        );
        $order_id = $wpdb->insert_id;
        return $order_id;
    }
function proccess_order_meta(){
        $date     = date_create("2017-07-24");
        $order_id = insert_order_to_db(194816,$date);
        if( is_wp_error( $order_id ) ){
            $order->errors = $order_id;
        }
        else
        {
            $order_id = 17188;
            add_post_meta($order_id, '_payment_method_title', 'پرداخت آنلاین', true);
            add_post_meta($order_id, '_order_total', 30000, true);
            add_post_meta($order_id, '_customer_user',  194816, true);
            add_post_meta($order_id, '_completed_date', date_format( $date, 'Y-m-d H:i:s e'), true);
            add_post_meta($order_id, '_paid_date', date_format( $date, 'Y-m-d H:i:s e'), true);
            add_post_meta($order_id, '_billing_email', "mavaezi46@gmail.com", true);
            add_post_meta($order_id, '_billing_first_name', "علی", true);

        }

    }
    proccess_order_meta();
于 2017-08-25T07:14:02.013 回答