Custom settings sections don't works
Describe the bug
The section is registered but the fields do not show.
To Reproduce
<?php
add_filter( 'woocommerce_get_sections_shipping', 'prefix_add_section' );
function prefix_add_section ( $sections ) {
$sections['my-custom-section'] = 'My Custom Section';
return $sections; // WORKS
}
add_filter( 'woocommerce_get_settings_shipping', 'prefix_add_settings', 10, 2 );
function prefix_add_settings ( $settings, $current ) {
if ( 'my-custom-section' === $current ) {
$prefix = 'my_custom_section_';
$settings = [
[
'id' => $prefix . 'settings',
'type' => 'title',
'name' => 'My Custom Title'
],
[
'id' => $prefix . 'input',
'type' => 'text',
'name' => 'My Custom Option'
],
[
'id' => $prefix . 'settings',
'type' => 'sectionend',
],
];
}
return $settings;
}
Screenshots

Expected behavior
The fields should appear.
Isolating the problem (mark completed items with an [x]):
- [x] I have deactivated other plugins and confirmed this bug occurs when only Classic Commerce plugin is active.
- [x] This bug happens with a default ClassicPress theme active.
- [x] I can reproduce this bug consistently using the steps above.
ClassicPress Environment
### CMS Environment ###
Home URL: https://classic.ddev.site
Site URL: https://classic.ddev.site
CC Version: 1.0.3
WC Version: 3.5.3
Log Directory Writable: ✔
CMS Version: ✔ You are running ClassicPress Version 1.4.2
Multisite: –
Memory Limit: 1 GB
Debug Mode: ✔
Cron: ✔
Language: pt_BR
External object cache: –
### Server Environment ###
Server Info: nginx/1.22.0
PHP Version: 7.4.30
PHP Post Max Size: 100 MB
PHP Time Limit: 600
PHP Max Input Vars: 3000
cURL Version: 7.74.0
OpenSSL/1.1.1n
SUHOSIN Installed: –
MySQL Version: 5.5.5-10.3.35-MariaDB-1:10.3.35+maria~focal-log
Max Upload Size: 100 MB
Default Timezone is UTC: ✔
fsockopen/cURL: ✔
SoapClient: ✔
DOMDocument: ✔
GZip: ✔
Multibyte String: ✔
Remote Post: ✔
Remote Get: ✔
### Database ###
CC Database Version: 3.5.3
WC Database Prefix: wp_
MaxMind GeoIP Database: ❌ The MaxMind GeoIP Database does not exist - Geolocation will not function. You can download and install it manually from https://dev.maxmind.com/geoip/geoip2/geolite2/ to the path: . Scroll down to "Downloads" and download the "MaxMind DB binary
gzipped" file next to "GeoLite2 Country". Please remember to uncompress GeoLite2-Country_xxxxxxxx.tar.gz and upload the GeoLite2-Country.mmdb file only.
Total Database Size: 1.67MB
Database Data Size: 0.79MB
Database Index Size: 0.88MB
wp_woocommerce_sessions: Data: 0.02MB + Index: 0.02MB
wp_woocommerce_api_keys: Data: 0.02MB + Index: 0.03MB
wp_woocommerce_attribute_taxonomies: Data: 0.02MB + Index: 0.02MB
wp_woocommerce_downloadable_product_permissions: Data: 0.02MB + Index: 0.05MB
wp_woocommerce_order_items: Data: 0.02MB + Index: 0.02MB
wp_woocommerce_order_itemmeta: Data: 0.02MB + Index: 0.03MB
wp_woocommerce_tax_rates: Data: 0.02MB + Index: 0.06MB
wp_woocommerce_tax_rate_locations: Data: 0.02MB + Index: 0.03MB
wp_woocommerce_shipping_zones: Data: 0.02MB + Index: 0.00MB
wp_woocommerce_shipping_zone_locations: Data: 0.02MB + Index: 0.03MB
wp_woocommerce_shipping_zone_methods: Data: 0.02MB + Index: 0.00MB
wp_woocommerce_payment_tokens: Data: 0.02MB + Index: 0.02MB
wp_woocommerce_payment_tokenmeta: Data: 0.02MB + Index: 0.03MB
wp_woocommerce_log: Data: 0.02MB + Index: 0.02MB
wp_commentmeta: Data: 0.02MB + Index: 0.03MB
wp_comments: Data: 0.02MB + Index: 0.09MB
wp_links: Data: 0.02MB + Index: 0.02MB
wp_options: Data: 0.23MB + Index: 0.02MB
wp_postmeta: Data: 0.02MB + Index: 0.03MB
wp_posts: Data: 0.02MB + Index: 0.06MB
wp_snippets: Data: 0.02MB + Index: 0.03MB
wp_termmeta: Data: 0.02MB + Index: 0.03MB
wp_terms: Data: 0.02MB + Index: 0.03MB
wp_term_relationships: Data: 0.02MB + Index: 0.02MB
wp_term_taxonomy: Data: 0.02MB + Index: 0.03MB
wp_usermeta: Data: 0.02MB + Index: 0.03MB
wp_users: Data: 0.02MB + Index: 0.05MB
wp_wc_download_log: Data: 0.02MB + Index: 0.03MB
wp_wc_webhooks: Data: 0.02MB + Index: 0.02MB
### Post Type Counts ###
page: 6
post: 2
product: 1
### Security ###
Secure connection (HTTPS): ✔
Hide errors from visitors: ❌Error messages should not be shown to visitors.
### Active Plugins (2) ###
Classic Commerce: by ClassicPress Research Team – 1.0.4
Code Snippets: by Code Snippets Pro – 3.2.0
### Settings ###
API Enabled: –
Force SSL: –
Currency: BRL (R$)
Currency Position: left
Thousand Separator: .
Decimal Separator: ,
Number of Decimals: 2
Taxonomies: Product Types: external (external)
grouped (grouped)
simple (simple)
variable (variable)
Taxonomies: Product Visibility: exclude-from-catalog (exclude-from-catalog)
exclude-from-search (exclude-from-search)
featured (featured)
outofstock (outofstock)
rated-1 (rated-1)
rated-2 (rated-2)
rated-3 (rated-3)
rated-4 (rated-4)
rated-5 (rated-5)
### WC Pages ###
Shop base: #7 - /shop/
Cart: #8 - /cart/
Checkout: #9 - /checkout/
My account: #10 - /my-account/
Terms and conditions: ❌ Page not set
### Theme ###
Name: ClassicPress TwentySeventeen
Version: 1.0.0
Author URL: https://www.classicpress.net
Child Theme: ✔
Parent Theme Name: Twenty Seventeen
Parent Theme Version: 99.1-upstream1.7
Parent Theme Author URL: https://wordpress.org/
Classic Commerce Support: ✔
### Templates ###
Overrides: –
I did a test the issue with Full code
It works fine. Issue could be something with your code.
Code sample
if ( ! defined( 'WPINC' ) ) {
die;
}
/*
* Check if WooCommerce is active
*/
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
function tutsplus_shipping_method() {
if ( ! class_exists( 'TutsPlus_Shipping_Method' ) ) {
class TutsPlus_Shipping_Method extends WC_Shipping_Method {
/**
* Constructor for your shipping class
*
* @access public
* @return void
*/
public function __construct() {
$this->id = 'tutsplus';
$this->method_title = __( 'TutsPlus Shipping', 'tutsplus' );
$this->method_description = __( 'Custom Shipping Method for TutsPlus', 'tutsplus' );
// Availability & Countries
$this->availability = 'including';
$this->countries = array(
'US', // Unites States of America
'CA', // Canada
'DE', // Germany
'GB', // United Kingdom
'IT', // Italy
'ES', // Spain
'HR' // Croatia
);
$this->init();
$this->enabled = isset( $this->settings['enabled'] ) ? $this->settings['enabled'] : 'yes';
$this->title = isset( $this->settings['title'] ) ? $this->settings['title'] : __( 'TutsPlus Shipping', 'tutsplus' );
}
/**
* Init your settings
*
* @access public
* @return void
*/
function init() {
// Load the settings API
$this->init_form_fields();
$this->init_settings();
// Save settings in admin if you have any defined
add_action( 'woocommerce_update_options_shipping_' . $this->id, array( $this, 'process_admin_options' ) );
}
/**
* Define settings field for this shipping
* @return void
*/
function init_form_fields() {
$this->form_fields = array(
'enabled' => array(
'title' => __( 'Enable', 'tutsplus' ),
'type' => 'checkbox',
'description' => __( 'Enable this shipping.', 'tutsplus' ),
'default' => 'yes'
),
'title' => array(
'title' => __( 'Title', 'tutsplus' ),
'type' => 'text',
'description' => __( 'Title to be display on site', 'tutsplus' ),
'default' => __( 'TutsPlus Shipping', 'tutsplus' )
),
'weight' => array(
'title' => __( 'Weight (kg)', 'tutsplus' ),
'type' => 'number',
'description' => __( 'Maximum allowed weight', 'tutsplus' ),
'default' => 100
),
);
}
/**
* This function is used to calculate the shipping cost. Within this function we can check for weights, dimensions and other parameters.
*
* @access public
* @param mixed $package
* @return void
*/
public function calculate_shipping( $package ) {
$weight = 0;
$cost = 0;
$country = $package["destination"]["country"];
foreach ( $package['contents'] as $item_id => $values )
{
$_product = $values['data'];
$weight = $weight + $_product->get_weight() * $values['quantity'];
}
$weight = wc_get_weight( $weight, 'kg' );
if( $weight <= 10 ) {
$cost = 0;
} elseif( $weight <= 30 ) {
$cost = 5;
} elseif( $weight <= 50 ) {
$cost = 10;
} else {
$cost = 20;
}
$countryZones = array(
'HR' => 0,
'US' => 3,
'GB' => 2,
'CA' => 3,
'ES' => 2,
'DE' => 1,
'IT' => 1
);
$zonePrices = array(
0 => 10,
1 => 30,
2 => 50,
3 => 70
);
$zoneFromCountry = $countryZones[ $country ];
$priceFromZone = $zonePrices[ $zoneFromCountry ];
$cost += $priceFromZone;
$rate = array(
'id' => $this->id,
'label' => $this->title,
'cost' => $cost
);
$this->add_rate( $rate );
}
}
}
}
add_action( 'woocommerce_shipping_init', 'tutsplus_shipping_method' );
function add_tutsplus_shipping_method( $methods ) {
$methods[] = 'TutsPlus_Shipping_Method';
return $methods;
}
add_filter( 'woocommerce_shipping_methods', 'add_tutsplus_shipping_method' );
function tutsplus_validate_order( $posted ) {
$packages = WC()->shipping->get_packages();
$chosen_methods = WC()->session->get( 'chosen_shipping_methods' );
if( is_array( $chosen_methods ) && in_array( 'tutsplus', $chosen_methods ) ) {
foreach ( $packages as $i => $package ) {
if ( $chosen_methods[ $i ] != "tutsplus" ) {
continue;
}
$TutsPlus_Shipping_Method = new TutsPlus_Shipping_Method();
$weightLimit = (int) $TutsPlus_Shipping_Method->settings['weight'];
$weight = 0;
foreach ( $package['contents'] as $item_id => $values )
{
$_product = $values['data'];
$weight = $weight + $_product->get_weight() * $values['quantity'];
}
$weight = wc_get_weight( $weight, 'kg' );
if( $weight > $weightLimit ) {
$message = sprintf( __( 'Sorry, %d kg exceeds the maximum weight of %d kg for %s', 'tutsplus' ), $weight, $weightLimit, $TutsPlus_Shipping_Method->title );
$messageType = "error";
if( ! wc_has_notice( $message, $messageType ) ) {
wc_add_notice( $message, $messageType );
}
}
}
}
}
add_action( 'woocommerce_review_order_before_cart_contents', 'tutsplus_validate_order' , 10 );
add_action( 'woocommerce_after_checkout_validation', 'tutsplus_validate_order' , 10 );
}
Post code screenshot.

I did a test the issue with Full code
This code create a shipping method. I just want to create a settings section.
It works fine. Issue could be something with your code.
My code works perfectly fine in woocommerce. Source: https://woocommerce.com/document/adding-a-section-to-a-settings-tab/

Apologies @luizbills, I hadn't looked for the hooks in the codebase. Classic-commerce is based off Woo 3.5.3 and this feature you are using was introduced in Woo 3.6.0 so it hasn't been backported. Ref: https://github.com/woocommerce/woocommerce/pull/21719
This is a legitimate request.