I'm working on a custom plugin that processes order data & sends it to another Web application.
I hook in to order processing using WooCommerce's woocommerce_checkout_order_processed
hook, so, I get the order id as an argument & hence can easily obtain WC_Order
.
The problem I got stuck with is the following:
I want to calculate some data based on the shipping method chosen by the customer, but I need more data than just the shipping method name in order to perform the calculation.
A simplified version of what I want to achieve is essentially something very similar to:
$order = wc_get_order($order_id);
$is_express_shipping = strpos($order->get_shipping_method(), 'Express') !== false;
But the whole problem is that the shipping method name does not contain (and in fact, it should not) any hint regarding whether it is an express shipping method or not, so, the only option is to pass some additional information about the shipping method through.
I've tried to add a custom shipping method as described in this question & in its accepted answer, so, I added the desired data into shipping method settings like this:
But it looks like WooCommerce doesn't expect custom shipping classes to register custom fields or at least, I didn't figure out how to get the Launch Simple Shipping's "Shipping Mode" property from within the order object (it does not appear anywhere within $order->get_shipping_methods()
output).
Here is the full code of the custom shipping class in case if needed. It's a copy-paste from the previously mentioned question + a new field.
function launch_shipping_method() {
if (!class_exists('Launch_Shipping_Method')) {
class Launch_Shipping_Method extends WC_Shipping_Method {
public function __construct( $instance_id = 0 ) {
$this->id = 'launch_shipping';
$this->instance_id = absint( $instance_id );
$this->method_title = __('Launch Simple Shipping', 'launch_shipping');
$this->method_description = __('Custom Simple Shipping Method', 'launch_shipping');
$this->supports = array(
'shipping-zones',
'instance-settings',
'instance-settings-modal',
);
$this->init();
}
/**
* Initialize Launch Simple Shipping.
*/
public function init() {
// Load the settings.
$this->init_form_fields();
$this->init_settings();
// Define user set variables.
$this->title = isset($this->settings['title']) ? $this->settings['title'] : __('Launch Shipping', 'launch_shipping');
$this->shipping_mode = isset($this->settings['shipping_mode']) ? $this->settings['shipping_mode'] : __('Launch Shipping', 'launch_shipping');
add_action('woocommerce_update_options_shipping_' . $this->id, array($this, 'process_admin_options'));
}
/**
* Init form fields.
*/
public function init_form_fields() {
$this->form_fields = array(
'title' => array(
'title' => __( 'Title', 'launch_shipping' ),
'type' => 'text',
'description' => __( 'This controls the title which the user sees during checkout.', 'launch_shipping' ),
'default' => $this->method_title,
'desc_tip' => true,
),
'shipping_mode' => array(
'title' => __( 'Shipping Mode', 'launch_shipping' ),
'type' => 'select',
'default' => 'Standard',
'options' => [
'Standard' => 'Standard',
'Express' => 'Express',
],
)
);
}
/**
* Get setting form fields for instances of this shipping method within zones.
*
* @return array
*/
public function get_instance_form_fields() {
return parent::get_instance_form_fields();
}
/**
* Always return shipping method is available
*
* @param array $package Shipping package.
* @return bool
*/
public function is_available( $package ) {
$is_available = true;
return apply_filters( 'woocommerce_shipping_' . $this->id . '_is_available', $is_available, $package, $this );
}
/**
* Free shipping rate applied for this method.
*
* @uses WC_Shipping_Method::add_rate()
*
* @param array $package Shipping package.
*/
public function calculate_shipping( $package = array() ) {
$this->add_rate(
array(
'label' => $this->title,
'cost' => 0,
'taxes' => false,
'package' => $package,
'shipping_mode' => $this->shipping_mode,
)
);
}
}
}
}
add_action('woocommerce_shipping_init', 'Launch_Shipping_Method');
function add_launch_shipping_method($methods) {
$methods['launch_shipping'] = 'launch_shipping_method';
return $methods;
}
add_filter('woocommerce_shipping_methods', 'add_launch_shipping_method');
Is there a way to somehow pass additional data about the chosen shipping method into WC_Order
object or somehow obtain it having WC_Order
at hand?