cum să utilizezi wc_create_order cu produse de tip abonament

16 sept. 2015, 17:39:11
Vizualizări: 24.8K
Voturi: 5

Vreau să creez o nouă comandă programatic.

Acest cod funcționează bine cu produse simple,

    $product = get_product($product_id);
    $order = wc_create_order();
    $order->add_product( $product , 1 );
    $order->calculate_totals();
    // atribuie comanda utilizatorului curent
    update_post_meta($order->id, '_customer_user', get_current_user_id() );
    // finalizare plată
    $order->payment_complete();

dar când îl folosesc pentru un produs de tip abonament, nu adaugă abonamentul, ci doar comanda.

0
Toate răspunsurile la întrebare 3
6
19

Iată codul meu pentru crearea unei abonări -- a fost nevoie de multă încercare și eroare pentru a descoperi totul. Mult succes!

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 );

    // Am folosit un singur produs cu multiple variații

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

    // Fiecare variație are și propria clasă de livrare

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

    // Am o logică pentru selectarea metodei de livrare; cazul tău va fi probabil diferit, așa că identifică metoda de care ai nevoie și stocheaz-o în $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;

    // După câte văd, trebuie să creezi mai întâi comanda, apoi abonamentul

    $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", 'Comandă importată', TRUE);

    // Comanda creată, acum creează abonamentul atașat -- opțional dacă nu creezi un abonament

    // Fiecare variație are o perioadă diferită de abonament

    $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'>Abonament creat! Click aici pentru editare</a>";
}
10 feb. 2016 01:07:01
Comentarii

Mulțumesc pentru asta, dar nu reușesc să o fac să funcționeze. Ce funcție este wcs_create_subscription()? Nu este definită, nici wc_create_subscription() dacă e o greșeală de scriere.

Pekz0r Pekz0r
24 feb. 2016 16:09:55

Pentru această parte ai nevoie de extensia Subscriptions! (Nu uita că poți căuta numele de funcții pe Google, de obicei sunt foarte ușor de găsit pentru că sunt foarte specifice.)

Jeremy Warne Jeremy Warne
25 feb. 2016 04:26:12

Da, aveam pluginul Subscriptions, dar se pare că aveam o versiune mai veche (1.5.). Am actualizat la 2.0. acum și codul pare să funcționeze. Mulțumesc mult!

Pekz0r Pekz0r
25 feb. 2016 11:11:20

Utilizare interesantă și exemplu bun pentru wc_create_order + wcs_create_subscription!

Scott Kingsley Clark Scott Kingsley Clark
21 apr. 2016 09:34:52

Continuă să mi se afișeze eroarea Call to undefined method WP_Error::add_product(), aveți vreo idee de ce?

Kravitz Kravitz
9 sept. 2019 23:12:22

@Kravitz verifică pe ce linie apare eroarea și folosește if (is_wp_error($order) var_dump($order) sau aceeași linie cu $sub în loc de $order, înainte de apelul către add_product(). Asta îți va spune ce se întâmplă greșit.

Jeremy Warne Jeremy Warne
10 sept. 2019 03:03:35
Arată celelalte 1 comentarii
1

Iată un exemplu:

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

    $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; // Necesar, altfel wc_create_order va genera o excepție
    $order                  = wc_create_order( $order_data );
25 dec. 2015 15:55:44
Comentarii

te rog să încerci să eviți răspunsurile doar cu cod fără a explica de ce rezolvă problema

Mark Kaplun Mark Kaplun
25 dec. 2015 17:06:53
0

Din păcate, trebuie să gestionați manual crearea abonamentului prin cod, deoarece simpla adăugare a unei comenzi nu se ocupă automat de acest lucru.

Iată funcția mea personalizată pe care am construit-o pe baza tuturor răspunsurilor găsite pe SO și a analizării codului sursă al abonamentelor.

Testat cu

  • WordPress 5.2.5
  • WooCommerce 3.8.0
  • WooCommerce Subscriptions 2.6.1

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

function give_user_subscription( $product, $user_id, $note = '' ){
    // Mai întâi verificăm dacă toate funcțiile și clasele necesare 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', // Starea trebuie setată inițial la "pending" pentru a corespunde procesului normal de checkout
        'billing_period' => WC_Subscriptions_Product::get_period( $product ),
        'billing_interval' => WC_Subscriptions_Product::get_interval( $product )
    ));

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

    // Modelat după WC_Subscriptions_Cart::calculate_subscription_totals()
    $start_date = gmdate( 'Y-m-d H:i:s' );
    // Adăugăm produsul la abonament
    $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();

    // Actualizăm starea comenzii cu o notă personalizată
    $note = ! empty( $note ) ? $note : __( 'Comandă și abonament adăugate programatic.' );
    $order->update_status( 'completed', $note, true );

    // De asemenea, actualizăm starea abonamentului la "active" din "pending" (și adăugăm nota)
    $sub->update_status( 'active', $note, true );
    return $sub;
}
14 nov. 2019 20:41:15