Skip to content

Instantly share code, notes, and snippets.

@tripflex
Last active August 13, 2023 18:16
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save tripflex/a3123052f36daf18f7cb05391d752223 to your computer and use it in GitHub Desktop.
Save tripflex/a3123052f36daf18f7cb05391d752223 to your computer and use it in GitHub Desktop.
Programmatically create a WooCommerce Subscription and associated WooCommerce Order
<?php
public 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;
}
@harryjin
Copy link

how to integrate with Stripe or PayPal gateway to process payment.

@aresrioja10
Copy link

Hi! How can we integrate with Stripe?

@NeoTechni
Copy link

NeoTechni commented Oct 12, 2021

I get:

Uncaught Error: Call to a member function get_name() on string in /public_html/wp-content/plugins/woocommerce/includes/abstracts/abstract-wc-order.php:1365

Stack trace:

#0: WC_Abstract_Order->add_product('17818', 1)

#1: give_user_subscription('17818', '10754', 'added via automation')

#2 {main} thrown in /public_html/wp-content/plugins/woocommerce/includes/abstracts/abstract-wc-order.php on line 1365

It seems it's cause I calld add_product using a product ID, so the solution is to use wc_get_product($ID)

@NeoTechni
Copy link

NeoTechni commented Oct 12, 2021

So now I get failure to create subscription, invalid billing_period. I switched it to let me choose from wcs_get_subscription_period_strings(), and I used "year"

Now I get

Fatal error: Uncaught Error: Call to a member function backorders_require_notification() on bool in /public_html/wp-content/plugins/woocommerce-subscriptions/includes/class-wc-subscription.php:2467

Stack trace:

#0 /public_html/photoswipe/auto/index.php(577): WC_Subscription->add_product(false, 1)

#1: give_user_subscription(false, '10754', 'year', 'added via automation')

#2 {main} thrown in /public_html/wp-content/plugins/woocommerce-subscriptions/includes/class-wc-subscription.php on line 2467

I know the product ID is correct, why would wc_get_product fail to find it?

@coachmanesh
Copy link

HI could someone assist me with this ? I am looking at using Automate Woo - and custom function to create a subscription from a quote - I am not too familiar with php code so help would be appreciated.
I would need to get the customer and product information from the quote when generated - if a checkbox on the quote is checked.

thanks
M

@qstudio
Copy link

qstudio commented Dec 14, 2022

$order->add_product( $product, 1 ); this should be a WC_Product object instance, not a product ID.

@pixelmultiplo
Copy link

How would you renew an existing subscription?

@bhargav-120
Copy link

Hi,
I want to use this code for the switch subscription, so how can I add switch subscription data in order meta?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment