I've used the 'cash on delivery/cod' payment method as a 'credit account' payment method. I've setup a custom user role for customers who will have a credit account. Those customers can then see the cod payment method if logged in.
But I'm having trouble setting a credit limit on these accounts.
I've added a custom meta field in the user editor to set a credit limit (e.g. $500). But I keep getting errors when I use the below code.
add_action('show_user_profile', 'custom_user_profile_fields');
add_action('edit_user_profile', 'custom_user_profile_fields');
function custom_user_profile_fields( $user ) {
?>
<table class="form-table">
<tr>
<th>
<label for="code"><?php _e( 'Credit Limit' ); ?></label>
</th>
<td>
<input type="text" name="code" id="credit_limit" value="<?php echo esc_attr( get_the_author_meta( 'credit_limit', $user->ID ) ); ?>" class="regular-text" />
</td>
</tr>
</table>
<?php
}
add_action( 'personal_options_update', 'update_extra_profile_fields' );
add_action( 'edit_user_profile_update', 'update_extra_profile_fields' );
function update_extra_profile_fields( $user_id ) {
if ( current_user_can( 'edit_user', $user_id ) )
update_user_meta( $user_id, 'credit_limit', $_POST['credit_limit'] );
}
function payment_gateway_disable_on_account( $available_gateways ) {
global $woocommerce;
$user = wp_get_current_user();
$user_id = $user->ID;
$credit_limit = get_user_meta( $user_id, 'credit_limit', true );
$amount = floatval( preg_replace( '#[^\d.]#', '', $woocommerce->cart->get_cart_subtotal() ) );
if ( empty( $credit_limit ) ) {
$credit_limit = 500;
}
$credit_remaining = $credit_limit - $amount;
if ( isset( $available_gateways['cod'] ) && !in_array( 'credit_account', $user->roles ) || $credit_remaining < 0 ) {
unset( $available_gateways['cod'] );
}
return $available_gateways;
}
add_filter( 'woocommerce_available_payment_gateways', 'payment_gateway_disable_on_account' );
Here is the error messages I'm getting:
Your PHP code changes were not applied due to an error on line 765 of file wp-content/themes/shoptimizer-child-theme/functions.php. Please fix and try saving again.
Uncaught Error: Call to a member function get_cart_subtotal() on null in wp-content/themes/shoptimizer-child-theme/functions.php:765
Stack trace:
#0 wp-includes/class-wp-hook.php(324): payment_gateway_disable_on_account()
#1 wp-includes/plugin.php(205): WP_Hook->apply_filters()
#2 wp-content/plugins/woocommerce/includes/class-wc-payment-gateways.php(336): apply_filters()
#3 wp-content/plugins/woocommerce/src/Admin/Features/OnboardingTasks/Tasks/AdditionalPayments.php(185): WC_Payment_Gateways->get_available_payment_gateways()
#4 wp-content/plugins/woocommerce/src/Admin/Features/OnboardingTasks/Tasks/AdditionalPayments.php(157): Automattic\WooCommerce\Admin\Features\OnboardingTasks\Tasks\AdditionalPayments::has_enabled_gateways()
#5 wp-content/plugins/woocommerce/src/Admin/Features/OnboardingTasks/Tasks/AdditionalPayments.php(115): Automattic\WooCommerce\Admin\Features\OnboardingTasks\Tasks\AdditionalPayments::has_enabled_other_category_gateways()
#6 wp-content/plugins/woocommerce/src/Admin/Features/OnboardingTasks/TaskList.php(305): Automattic\WooCommerce\Admin\Features\OnboardingTasks\Tasks\AdditionalPayments->can_view()
#7 [internal function]: Automattic\WooCommerce\Admin\Features\OnboardingTasks\TaskList->Automattic\WooCommerce\Admin\Features\OnboardingTasks\{closure}()
#8 wp-content/plugins/woocommerce/src/Admin/Features/OnboardingTasks/TaskList.php(306): array_filter()
#9 wp-content/plugins/woocommerce/src/Admin/Features/OnboardingTasks/TaskList.php(171): Automattic\WooCommerce\Admin\Features\OnboardingTasks\TaskList->get_viewable_tasks()
#10 wp-content/plugins/woocommerce/src/Internal/Admin/WcPayWelcomePage.php(364): Automattic\WooCommerce\Admin\Features\OnboardingTasks\TaskList->is_visible()
#11 wp-content/plugins/woocommerce/src/Internal/Admin/WcPayWelcomePage.php(151): Automattic\WooCommerce\Internal\Admin\WcPayWelcomePage->get_active_payments_task_slug()
#12 wp-includes/class-wp-hook.php(324): Automattic\WooCommerce\Internal\Admin\WcPayWelcomePage->register_menu_and_page()
#13 wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters()
#14 wp-includes/plugin.php(517): WP_Hook->do_action()
#15 wp-admin/includes/menu.php(161): do_action()
#16 wp-admin/menu.php(412): require_once('...')
#17 wp-admin/admin.php(158): require('...')
#18 wp-admin/theme-editor.php(10): require_once('...')
#19 {main}
thrown
This is line 765:
$amount = floatval( preg_replace( '#[^\d.]#', '', $woocommerce->cart->get_cart_subtotal() ) );
I've used the 'cash on delivery/cod' payment method as a 'credit account' payment method. I've setup a custom user role for customers who will have a credit account. Those customers can then see the cod payment method if logged in.
But I'm having trouble setting a credit limit on these accounts.
I've added a custom meta field in the user editor to set a credit limit (e.g. $500). But I keep getting errors when I use the below code.
add_action('show_user_profile', 'custom_user_profile_fields');
add_action('edit_user_profile', 'custom_user_profile_fields');
function custom_user_profile_fields( $user ) {
?>
<table class="form-table">
<tr>
<th>
<label for="code"><?php _e( 'Credit Limit' ); ?></label>
</th>
<td>
<input type="text" name="code" id="credit_limit" value="<?php echo esc_attr( get_the_author_meta( 'credit_limit', $user->ID ) ); ?>" class="regular-text" />
</td>
</tr>
</table>
<?php
}
add_action( 'personal_options_update', 'update_extra_profile_fields' );
add_action( 'edit_user_profile_update', 'update_extra_profile_fields' );
function update_extra_profile_fields( $user_id ) {
if ( current_user_can( 'edit_user', $user_id ) )
update_user_meta( $user_id, 'credit_limit', $_POST['credit_limit'] );
}
function payment_gateway_disable_on_account( $available_gateways ) {
global $woocommerce;
$user = wp_get_current_user();
$user_id = $user->ID;
$credit_limit = get_user_meta( $user_id, 'credit_limit', true );
$amount = floatval( preg_replace( '#[^\d.]#', '', $woocommerce->cart->get_cart_subtotal() ) );
if ( empty( $credit_limit ) ) {
$credit_limit = 500;
}
$credit_remaining = $credit_limit - $amount;
if ( isset( $available_gateways['cod'] ) && !in_array( 'credit_account', $user->roles ) || $credit_remaining < 0 ) {
unset( $available_gateways['cod'] );
}
return $available_gateways;
}
add_filter( 'woocommerce_available_payment_gateways', 'payment_gateway_disable_on_account' );
Here is the error messages I'm getting:
Your PHP code changes were not applied due to an error on line 765 of file wp-content/themes/shoptimizer-child-theme/functions.php. Please fix and try saving again.
Uncaught Error: Call to a member function get_cart_subtotal() on null in wp-content/themes/shoptimizer-child-theme/functions.php:765
Stack trace:
#0 wp-includes/class-wp-hook.php(324): payment_gateway_disable_on_account()
#1 wp-includes/plugin.php(205): WP_Hook->apply_filters()
#2 wp-content/plugins/woocommerce/includes/class-wc-payment-gateways.php(336): apply_filters()
#3 wp-content/plugins/woocommerce/src/Admin/Features/OnboardingTasks/Tasks/AdditionalPayments.php(185): WC_Payment_Gateways->get_available_payment_gateways()
#4 wp-content/plugins/woocommerce/src/Admin/Features/OnboardingTasks/Tasks/AdditionalPayments.php(157): Automattic\WooCommerce\Admin\Features\OnboardingTasks\Tasks\AdditionalPayments::has_enabled_gateways()
#5 wp-content/plugins/woocommerce/src/Admin/Features/OnboardingTasks/Tasks/AdditionalPayments.php(115): Automattic\WooCommerce\Admin\Features\OnboardingTasks\Tasks\AdditionalPayments::has_enabled_other_category_gateways()
#6 wp-content/plugins/woocommerce/src/Admin/Features/OnboardingTasks/TaskList.php(305): Automattic\WooCommerce\Admin\Features\OnboardingTasks\Tasks\AdditionalPayments->can_view()
#7 [internal function]: Automattic\WooCommerce\Admin\Features\OnboardingTasks\TaskList->Automattic\WooCommerce\Admin\Features\OnboardingTasks\{closure}()
#8 wp-content/plugins/woocommerce/src/Admin/Features/OnboardingTasks/TaskList.php(306): array_filter()
#9 wp-content/plugins/woocommerce/src/Admin/Features/OnboardingTasks/TaskList.php(171): Automattic\WooCommerce\Admin\Features\OnboardingTasks\TaskList->get_viewable_tasks()
#10 wp-content/plugins/woocommerce/src/Internal/Admin/WcPayWelcomePage.php(364): Automattic\WooCommerce\Admin\Features\OnboardingTasks\TaskList->is_visible()
#11 wp-content/plugins/woocommerce/src/Internal/Admin/WcPayWelcomePage.php(151): Automattic\WooCommerce\Internal\Admin\WcPayWelcomePage->get_active_payments_task_slug()
#12 wp-includes/class-wp-hook.php(324): Automattic\WooCommerce\Internal\Admin\WcPayWelcomePage->register_menu_and_page()
#13 wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters()
#14 wp-includes/plugin.php(517): WP_Hook->do_action()
#15 wp-admin/includes/menu.php(161): do_action()
#16 wp-admin/menu.php(412): require_once('...')
#17 wp-admin/admin.php(158): require('...')
#18 wp-admin/theme-editor.php(10): require_once('...')
#19 {main}
thrown
This is line 765:
$amount = floatval( preg_replace( '#[^\d.]#', '', $woocommerce->cart->get_cart_subtotal() ) );
Share
edited Mar 7 at 14:07
adem007
asked Mar 7 at 13:49
adem007adem007
1214 bronze badges
3
|
2 Answers
Reset to default 1There are multiple mistakes in your last function, mainly:
1️⃣ You need to check that you are on checkout page, and that the WC_Cart
object is defined.
2️⃣ Note that WC_Cart
get_cart_subtotal()
method output the HTML formatted amout. To get the cart subtotal non formatted amount use one of the following:
WC()->cart->get_subtotal()
(subtotal excluding taxes),WC()->cart->subtotal
(subtotal including taxes).
Try the following revised code instead, to avoid the error:
function payment_gateway_disable_on_account( $available_gateways ) {
// Check that it's on checkout page and that the WC_Cart object is not null
if ( is_checkout() && isset(WC()->cart) && WC()->cart ) {
$credit_limit = get_user_meta( get_current_user_id(), 'credit_limit', true );
$amount = floatval( preg_replace( '#[^\d.]#', '', WC()->cart->subtotal ) );
if ( empty( $credit_limit ) ) {
$credit_limit = 500;
}
$credit_remaining = $credit_limit - $amount;
if ( isset($available_gateways['cod']) && ( !wc_current_user_has_role('credit_account') || $credit_remaining < 0 ) ) {
unset($available_gateways['cod']);
}
}
return $available_gateways;
}
add_filter( 'woocommerce_available_payment_gateways', 'payment_gateway_disable_on_account' );
It should work, without throwing an error.
You are getting that error because WooCommerce cart is not yet initialized. Use wc_load_cart()
function to initialize the cart.
Example:
function payment_gateway_disable_on_account( $available_gateways ) {
global $woocommerce;
if ( is_null( $woocommerce->cart ) ) {
// If cart is not initialized, call this function
wc_load_cart();
}
...
}
$woocommerce->cart
appears to be null at this point, so tryWC()->cart
instead. – C3roe Commented Mar 7 at 14:30