3

我想(以编程方式)创建订阅产品的订单。我从这个问题中找到了代码:Programmatically created new order in Woocommerce,我曾经尝试过让它工作。

我无法使用“简单订阅”或“简单产品”使其工作。

 function create_vip_order() {

  global $woocommerce;
  $product_id = 123;

  $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( $product_id ), 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_checkout_process', 'create_vip_order' );

如果您有任何解决方案,我将不胜感激。:)

最好的问候, Ledung

编辑:似乎我的产品设置方式导致该功能不起作用。我目前使用的是简单订阅产品,已选中“虚拟”参数,订阅期限为 3 个月。

在这里,您可以看到适用于我的设置的当前代码:

    function create_test_sub() {

    $email = 'test@test.se';

    $start_date = date( "Y-m-d H:i:s", strtotime( "now" ) );


    $address = array(
        'first_name' => 'Firstname',
        'last_name'  => 'Secondname',
        'company'    => 'Company',
        'email'      => $email,
        'phone'      => '',
        'address_1'  => 'Streetname 123',
        'address_2'  => '',
        'city'       => 'City',
        'postcode'   => '12345',
        'country'    => 'Country'
    );

    $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( 3901 );

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

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

    $product = wc_get_product( $product_variation );

    $product_month_length = $parent_product->subscription_length;
    $end_date = date( "Y-m-d H:i:s", strtotime( $product_month_length . "months" ) );

    $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( $parent_product, $quantity, $args );
    $order->set_address( $address, 'billing' );
    $order->set_address( $address, 'shipping' );


    $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( $parent_product );
    $interval = WC_Subscriptions_Product::get_interval( $product );


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

    if ( ! is_wp_error( $sub ) ){
      $sub->add_product( $parent_product, $quantity, $args );

      $sub->set_address( $address, 'billing' );
      $sub->set_address( $address, 'shipping' );
      $dates = array(
        'end' => $end_date,
      );
      $sub->update_dates( $dates );
      $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>";
    $returnarray = array(
      'subscription_id' => $sub->id,
      'order_id'        => $order->id,
    );

    return  $returnarray;
}
$test = create_test_sub();
4

1 回答 1

5

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

经测试

  • WordPress 5.2.5
  • WooCommerce 3.8.0
  • 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;
}
于 2019-11-14T18:40:03.257 回答