Skip to content

Instantly share code, notes, and snippets.

@woogists
Last active September 9, 2023 07:52
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save woogists/c0cb26faa4f329dc0c01d78f53e797e9 to your computer and use it in GitHub Desktop.
Save woogists/c0cb26faa4f329dc0c01d78f53e797e9 to your computer and use it in GitHub Desktop.
[Shipping Method API] WooCommerce skeleton shipping method plugin code example.
<?php
/*
Plugin Name: Your Shipping plugin
Plugin URI: https://woocommerce.com/
Description: Your shipping method plugin
Version: 1.0.0
Author: WooThemes
Author URI: https://woocommerce.com/
*/
/**
* Check if WooCommerce is active
*/
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
function your_shipping_method_init() {
if ( ! class_exists( 'WC_Your_Shipping_Method' ) ) {
class WC_Your_Shipping_Method extends WC_Shipping_Method {
/**
* Constructor for your shipping class
*
* @access public
* @return void
*/
public function __construct() {
$this->id = 'your_shipping_method'; // Id for your shipping method. Should be uunique.
$this->method_title = __( 'Your Shipping Method' ); // Title shown in admin
$this->method_description = __( 'Description of your shipping method' ); // Description shown in admin
$this->enabled = "yes"; // This can be added as an setting but for this example its forced enabled
$this->title = "My Shipping Method"; // This can be added as an setting but for this example its forced.
$this->init();
}
/**
* Init your settings
*
* @access public
* @return void
*/
function init() {
// Load the settings API
$this->init_form_fields(); // This is part of the settings API. Override the method to add your own settings
$this->init_settings(); // This is part of the settings API. Loads settings you previously init.
// Save settings in admin if you have any defined
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
}
/**
* calculate_shipping function.
*
* @access public
* @param array $package
* @return void
*/
public function calculate_shipping( $package = array() ) {
$rate = array(
'label' => $this->title,
'cost' => '10.99',
'calc_tax' => 'per_item'
);
// Register the rate
$this->add_rate( $rate );
}
}
}
}
add_action( 'woocommerce_shipping_init', 'your_shipping_method_init' );
function add_your_shipping_method( $methods ) {
$methods['your_shipping_method'] = 'WC_Your_Shipping_Method';
return $methods;
}
add_filter( 'woocommerce_shipping_methods', 'add_your_shipping_method' );
}
@nydame
Copy link

nydame commented Feb 27, 2021

The argument for calculate_shipping may need type hinting to avoid a PHP warning, e.g.,
calculate_shipping( $package = array() ) {...}

@jaamo
Copy link

jaamo commented Jun 3, 2021

I had to call super constructor to get this working:

public function __construct($instance_id = 0) {
    parent::__construct($instance_id);

Otherwise instance_id wasn't set.

I think this is quite recent change and is related to shipping zones. Didn't dig too deep to really figure out why this is required :)

@freesouldesign
Copy link

I suggest you don't trust the output of active_plugins to check if WooCommerce is active. That output can be filtered from a mu-plugin to deactivate specific plugins on specific pages.
When you do it you usually remove the filter before the normal plugins are loaded, in another case you would have some issues.
This means that by checking WooCommerce with the option active_plugins you may think WooCommerce is active, but it isn't.
In my opinion, it would be a lot easier, safer and faster if you check the class that you are going to use:

if( class_exists( 'WC_Shipping_Method' ) ){
//your code here
}

@sb39
Copy link

sb39 commented Jul 26, 2021

add_action('woocommerce_review_order_before_payment', array($this, 'update_shipping_charges'));
I have this hook to update charges on payment method change. but the rates are not updating . Any ideas how to do it ?

@iampapagray
Copy link

Hello guys, I have a custom shipping plugin that adds a shipping method to the ones that have been added through shipping options on the Checkout page. The plugin works perfectly and adds the shipping method on the checkout page, however, I tried the plugin on another site that used the Divi Theme and it didn't work. From further investigations, I notice that the developer of the site uses a checkout builder which does not use woocommerce_checkout shortcode or block. But rather the builder places on the checkout page, the individual sections of the checkout page. This seems to be the only difference between this site and all the others I have tested the plugin on.

Does anyone have an idea of how to add the shipping method to the list even on sites that use builders in the same manner?

@ramesh2007
Copy link

how can i integrate with api and how it would be change based on zone

@siliconforks
Copy link

BUG: the value of $rate is not actually a valid argument for the add_rate method here:

$rate = array(
	'label' => $this->title,
	'cost' => '10.99',
	'calc_tax' => 'per_item'
);

// Register the rate
$this->add_rate( $rate );

In the comments for the add_rate method, it says that 'cost' is either a single amount or an array, and 'calc_tax' is either 'per_order' or 'per_item'. But when 'per_item' is used, then 'cost' needs to be an array. If you use 'per_item' with a single amount for 'cost', the result will be that the calculated tax is always zero.

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