最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

php - Set credit limit for account customers - Stack Overflow

programmeradmin2浏览0评论

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
  • 1 What errors are you getting? – Raghavendra N Commented Mar 7 at 13:59
  • I've just updated the post with the errors – adem007 Commented Mar 7 at 14:07
  • $woocommerce->cart appears to be null at this point, so try WC()->cart instead. – C3roe Commented Mar 7 at 14:30
Add a comment  | 

2 Answers 2

Reset to default 1

There 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();
    }

    ...
}
发布评论

评论列表(0)

  1. 暂无评论