如何将WC_CREATE_ORDER用于订阅产品

时间:2015-09-16 作者:Samir salem

我想通过编程创建一个新订单。

此代码适用于简单产品,

    $product = get_product($product_id);
    $order = wc_create_order();
    $order->add_product( $product , 1 );
    $order->calculate_totals();
    // assign the order to the current user
    update_post_meta($order->id, \'_customer_user\', get_current_user_id() );
    // payment_complete
    $order->payment_complete();
但当我将其用于订阅产品时,它不会添加订阅,而是只添加订单。

3 个回复
最合适的回答,由SO网友:Jeremy Warne 整理而成

这是我创建订阅的代码——我花了大量的尝试和错误才弄清楚。祝你好运!

function create_test_sub() {

    $email = \'[email protected]\';

    $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>";
}

SO网友:osos

下面是一个示例

     $order_data = array(
        \'status\'        => \'completed\',
        \'customer_id\'   => 1,
        \'customer_note\' => \'\',
        \'total\'         => \'\',
    );

    $_SERVER[\'REMOTE_ADDR\'] = \'127.0.0.1\'; // Required, else wc_create_order throws an exception
    $order                  = wc_create_order( $order_data );

SO网友:sMyles

不幸的是,您必须通过代码手动处理创建订阅,因为仅仅添加订单并不能自动处理它。

这是我根据在SO上找到的所有答案并挖掘订阅代码库构建的自定义函数。

使用测试

WooCommerce订阅2.6.1

https://gist.github.com/tripflex/a3123052f36daf18f7cb05391d752223

function give_user_subscription( $product, $user_id, $note = \'\' ){
    // First make sure all required functions and classes exist
    if( ! function_exists( \'wc_create_order\' ) || ! function_exists( \'wcs_create_subscription\' ) || ! class_exists( \'WC_Subscriptions_Product\' ) ){
        return false;
    }

    $order = wc_create_order( array( \'customer_id\' => $user_id ) );
    if( is_wp_error( $order ) ){
        return false;
    }

    $user = get_user_by( \'ID\', $user_id );

    $fname     = $user->first_name;
    $lname     = $user->last_name;
    $email     = $user->user_email;
    $address_1 = get_user_meta( $user_id, \'billing_address_1\', true );
    $address_2 = get_user_meta( $user_id, \'billing_address_2\', true );
    $city      = get_user_meta( $user_id, \'billing_city\', true );
    $postcode  = get_user_meta( $user_id, \'billing_postcode\', true );
    $country   = get_user_meta( $user_id, \'billing_country\', true );
    $state     = get_user_meta( $user_id, \'billing_state\', true );
    $address         = array(
        \'first_name\' => $fname,
        \'last_name\'  => $lname,
        \'email\'      => $email,
        \'address_1\'  => $address_1,
        \'address_2\'  => $address_2,
        \'city\'       => $city,
        \'state\'      => $state,
        \'postcode\'   => $postcode,
        \'country\'    => $country,
    );

    $order->set_address( $address, \'billing\' );
    $order->set_address( $address, \'shipping\' );
    $order->add_product( $product, 1 );

    $sub = wcs_create_subscription(array(
        \'order_id\' => $order->get_id(),
        \'status\' => \'pending\', // Status should be initially set to pending to match how normal checkout process goes
        \'billing_period\' => WC_Subscriptions_Product::get_period( $product ),
        \'billing_interval\' => WC_Subscriptions_Product::get_interval( $product )
    ));

    if( is_wp_error( $sub ) ){
        return false;
    }

    // Modeled after WC_Subscriptions_Cart::calculate_subscription_totals()
    $start_date = gmdate( \'Y-m-d H:i:s\' );
    // Add product to subscription
    $sub->add_product( $product, 1 );

    $dates = array(
        \'trial_end\'    => WC_Subscriptions_Product::get_trial_expiration_date( $product, $start_date ),
        \'next_payment\' => WC_Subscriptions_Product::get_first_renewal_payment_date( $product, $start_date ),
        \'end\'          => WC_Subscriptions_Product::get_expiration_date( $product, $start_date ),
    );

    $sub->update_dates( $dates );
    $sub->calculate_totals();

    // Update order status with custom note
    $note = ! empty( $note ) ? $note : __( \'Programmatically added order and subscription.\' );
    $order->update_status( \'completed\', $note, true );

    // Also update subscription status to active from pending (and add note)
    $sub->update_status( \'active\', $note, true );
    return $sub;
}

相关推荐