Skip to content

Conversation

@iamdharmesh
Copy link
Contributor

Summary

We recently received a report from a customer that a subscription renewal fails with a fatal error when using PayPal Braintree. Due to the conflict between WooCommerce Subscriptions, PayPal Braintree, and AvaTax.

Error Logs:

failed-scheduled-actions-2025-04-07(2).log 2025-04-07T20:00:08+00:00 ERROR scheduled action 2012663 (subscription payment) failed to finish processing due to the following exception: Call to a member function get_billing_country() on null in /public_html/wp-content/plugins/woocommerce-gateway-paypal-powered-by-braintree/vendor/skyverge/wc-plugin-framework/woocommerce/payment-gateway/External_Checkout/apple-pay/class-sv-wc-payment-gateway-apple-pay.php:707 CONTEXT: {"action_args":"subscription_id: 33736","error_trace":"#0 /public_html/wp-includes/class-wp-hook.php(324): SkyVerge\WooCommerce\PluginFramework\v5_12_7\SV_WC_Payment_Gateway_Apple_Pay->set_customer_taxable_address()n#1 /public_html/wp-includes/plugin.php(205): WP_Hook->apply_filters()n#2 /public_html/wp-content/plugins/woocommerce-avatax/src/class-wc-avatax-order-handler.php(1433): apply_filters()n#3 /public_html/wp-content/plugins/woocommerce-avatax/src/class-wc-avatax-order-handler.php(1382): WC_AvaTax_Order_Handler->get_taxable_address()n#4 /public_html/wp-content/plugins/woocommerce-avatax/src/integrations/class-wc-avatax-integrations.php(148): WC_AvaTax_Order_Handler->is_order_taxable()n#5 /public_html/wp-includes/class-wp-hook.php(324): WC_AvaTax_Integrations->recalculate_renewal_taxes()n#6 /public_html/wp-includes/plugin.php(205): WP_Hook->apply_filters()n#7 /public_html/wp-content/plugins/woocommerce-subscriptions/vendor/woocommerce/subscriptions-core/includes/wcs-renewal-functions.php(45): apply_filters()n#8 /public_html/wp-content/plugins/woocommerce-subscriptions/vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php(143): wcs_create_renewal_order()n#9 /public_html/wp-content/plugins/woocommerce-subscriptions/vendor/woocommerce/subscriptions-core/includes/class-wc-subscriptions-manager.php(116): WC_Subscriptions_Manager::process_renewal()n#10 /public_html/wp-includes/class-wp-hook.php(324): WC_Subscriptions_Manager::prepare_renewal()n#11 /public_html/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters()n#12 /public_html/wp-includes/plugin.php(565): WP_Hook->do_action()n#13 /public_html/wp-content/plugins/woocommerce/packages/action-scheduler/classes/actions/ActionScheduler_Action.php(86): do_action_ref_array()n#14 /public_html/wp-content/plugins/woocommerce/packages/action-scheduler/classes/abstracts/ActionScheduler_Abstract_QueueRunner.php(102): ActionScheduler_Action->execute()n#15 /public_html/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_QueueRunner.php(188): ActionScheduler_Abstract_QueueRunner->process_action()n#16 /public_html/wp-content/plugins/woocommerce/packages/action-scheduler/classes/ActionScheduler_QueueRunner.php(158): ActionScheduler_QueueRunner->do_batch()n#17 /public_html/wp-includes/class-wp-hook.php(324): ActionScheduler_QueueRunner->run()n#18 /public_html/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters()n#19 /public_html/wp-includes/plugin.php(565): WP_Hook->do_action()n#20 phar:///usr/local/bin/wp/vendor/wp-cli/cron-command/src/Cron_Event_Command.php(358): do_action_ref_array()n#21 phar:///usr/local/bin/wp/vendor/wp-cli/cron-command/src/Cron_Event_Command.php(238): Cron_Event_Command::run_event()n#22 [internal function]: Cron_Event_Command->run()n#23 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Dispatcher/CommandFactory.php(100): call_user_func()n#24 [internal function]: WP_CLI\Dispatcher\CommandFactory::WP_CLI\Dispatcher\{closure}()n#25 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Dispatcher/Subcommand.php(497): call_user_func()n#26 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(441): WP_CLI\Dispatcher\Subcommand->invoke()n#27 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(464): WP_CLI\Runner->run_command()n#28 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Runner.php(1296): WP_CLI\Runner->run_command_and_exit()n#29 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/WP_CLI/Bootstrap/LaunchRunner.php(28): WP_CLI\Runner->start()n#30 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/bootstrap.php(83): WP_CLI\Bootstrap\LaunchRunner->process()n#31 phar:///usr/local/bin/wp/vendor/wp-cli/wp-cli/php/wp-cli.php(32): WP_CLI\bootstrap()n#32 phar:///usr/local/bin/wp/php/boot-phar.php(20): include('phar:///usr/loc...')n#33 /usr/local/bin/wp(4): include('phar:///usr/loc...')n#34 {main}"}

The log seems to show a conflict with WooCommerce Subscriptions, PayPal Braintree (It uses this framework), and AvaTax.

Avatax is triggering a core WooCommerce hook:

/* this filter is documented in woocommerce/includes/class-wc-customer.php */
return apply_filters( 'woocommerce_customer_taxable_address', array( $country, $state, $postcode, $city ) );

And the this plugin framework is hooked into that, and runs this code:
$billing_country = WC()->customer->get_billing_country();

However, when this error occurs, WC()->customer is not set or is null. While there may be some debate about where the responsibility lies, I believe it’s always best to use defensive programming when accessing any top-level WC() properties like WC()->customer, and to ensure they exist.

Therefore, this PR adds a defensive check to prevent a potential fatal error during subscription renewal.

UI Changes

N/A

QA

Setup

  • Install and Activate WooCommerce Subscriptions and Avatax extension
  • Install WooCommerce Braintree plugin (with wc-plugin-framework from this PR branch)

Steps

  1. Purchase a subscription product with Braintree payment gateway.
  2. Go to edit subscription and process renewal from the order actions.
  3. Verify that subscription renewed without any issue.

Before merge

  • I have confirmed these changes in each supported minor WooCommerce version

Copy link
Contributor

@agibson-godaddy agibson-godaddy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great change -- thank you!

@agibson-godaddy agibson-godaddy merged commit ef77035 into godaddy-wordpress:master Apr 30, 2025
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants