Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WC_Stripe_API::detach_payment_method_from_customer() must be of the type string, null given #2615

Open
glagonikas opened this issue May 10, 2023 · 15 comments · May be fixed by #2624
Open

WC_Stripe_API::detach_payment_method_from_customer() must be of the type string, null given #2615

glagonikas opened this issue May 10, 2023 · 15 comments · May be fixed by #2624
Labels
priority: medium The issue/PR is medium priority—it affects lots of customers substantially, but not critically. type: bug The issue is a confirmed bug.

Comments

@glagonikas
Copy link

glagonikas commented May 10, 2023

Describe the bug
We're coming across a number of errors in our logs stating the following

[10-May-2023 06:51:31 UTC] PHP Notice:  Undefined property: stdClass::$source in /home/site/public_html/wp-content/plugins/woocommerce-gateway-stripe/includes/class-wc-stripe-intent-controller.php on line 137
[10-May-2023 06:51:31 UTC] PHP Notice:  Trying to get property 'id' of non-object in /home/site/public_html/wp-content/plugins/woocommerce-gateway-stripe/includes/class-wc-stripe-intent-controller.php on line 137
[10-May-2023 06:51:31 UTC] PHP Fatal error:  Uncaught TypeError: Argument 2 passed to WC_Stripe_API::detach_payment_method_from_customer() must be of the type string, null given, called in /home/site/public_html/wp-content/plugins/woocommerce-gateway-stripe/includes/class-wc-stripe-customer.php on line 472 and defined in /home/site/public_html/wp-content/plugins/woocommerce-gateway-stripe/includes/class-wc-stripe-api.php:327
Stack trace:
#0 /home/site/public_html/wp-content/plugins/woocommerce-gateway-stripe/includes/class-wc-stripe-customer.php(472): WC_Stripe_API::detach_payment_method_from_customer()
#1 /home/site/public_html/wp-content/plugins/woocommerce-gateway-stripe/includes/class-wc-stripe-intent-controller.php(137): WC_Stripe_Customer->delete_source()
#2 /home/site/public_html/wp-includes/class-wp-hook.php(308): WC_Stripe_Intent_Controller->verify_intent()
#3 /home/site/public_html/wp-includes/class-wp-hook.php(332): WP_Hook->apply_filters()
#4 /home/site/public_html/wp-includes/plugin.php(517): WP_Hook->do_action()
#5 /home/site/publi in /home/site/public_html/wp-content/plugins/woocommerce-gateway-stripe/includes/class-wc-stripe-api.php on line 327
[10-May-2023 06:51:31 UTC] PHP error triggered at: https://www.site.com/?wc-ajax=wc_stripe_verify_intent&order=3710233&nonce=XXXXX&redirect_to=https%3A%2F%2Fwww.site.com%2Fcheckout%2Forder-received%2FXXXXX%2F%3Fkey%3Dwc_order_XXXXX%26utm_nooverride%3D1&save_payment_method=1&is_ajax
[10-May-2023 06:51:31 UTC] PHP error message: Array
(
    [type] => 1
    [message] => Uncaught TypeError: Argument 2 passed to WC_Stripe_API::detach_payment_method_from_customer() must be of the type string, null given, called in /home/site/public_html/wp-content/plugins/woocommerce-gateway-stripe/includes/class-wc-stripe-customer.php on line 472 and defined in /home/site/public_html/wp-content/plugins/woocommerce-gateway-stripe/includes/class-wc-stripe-api.php:327
Stack trace:
#0 /home/site/public_html/wp-content/plugins/woocommerce-gateway-stripe/includes/class-wc-stripe-customer.php(472): WC_Stripe_API::detach_payment_method_from_customer()
#1 /home/site/public_html/wp-content/plugins/woocommerce-gateway-stripe/includes/class-wc-stripe-intent-controller.php(137): WC_Stripe_Customer->delete_source()
#2 /home/site/public_html/wp-includes/class-wp-hook.php(308): WC_Stripe_Intent_Controller->verify_intent()
#3 /home/site/public_html/wp-includes/class-wp-hook.php(332): WP_Hook->apply_filters()
#4 /home/site/public_html/wp-includes/plugin.php(517): WP_Hook->do_action()
#5 /home/site/publi
    [file] => /home/site/public_html/wp-content/plugins/woocommerce-gateway-stripe/includes/class-wc-stripe-api.php
    [line] => 327
)

Steps to reproduce
While in test mode use cards 4000000000003220 or 4000000000003063, and when the 3ds modal comes up fail the validation. That will result in a payment intent response from the API with an last_payment_error object that does not contain the source.
This can be reproduced on vanilla installation.

Additional Context
In the comment found here

// Currently, Stripe saves the payment method even if the authentication fails for 3DS cards.
// Although, the card is not stored in DB we need to remove the source from the customer on Stripe
// in order to keep the sources in sync with the data in DB.
you state that Stripe "Stripe saves the payment method even if the authentication fails for 3DS cards.". This has probably changed and it's what's causing this fatal?

Environment (please complete the following information):

  • WordPress Version 6.2
  • WooCommerce Version 7.7.0
  • Stripe Plugin Version 7.4.0
@nicomollet
Copy link
Contributor

nicomollet commented Jun 20, 2023

Exactly the same problem for me.

  • WordPress Version 6.1.1
  • WooCommerce Version 7.8.0
  • Stripe Plugin Version 7.4.1

@duotive
Copy link

duotive commented Jun 26, 2023

This happens for us too.

@andreDane
Copy link

Same for us:

Uncaught TypeError: WC_Stripe_API::detach_payment_method_from_customer(): Argument #2 ($payment_method_id) must be of type string, null given, called in /woocommerce-gateway-stripe/includes/class-wc-stripe-customer.php on line 472 and defined in /woocommerce-gateway-stripe/includes/class-wc-stripe-api.php:327 Stack trace: #0 /woocommerce-gateway-stripe/includes/class-wc-stripe-customer.php(472): WC_Stripe_API::detach_payment_method_from_customer() #1 /woocommerce-gateway-stripe/includes/class-wc-stripe-intent-controller.php(132): WC_Stripe_Customer->delete_source() #2 /wp-includes/class-wp-hook.php(308): WC_Stripe_Intent_Controller->verify_intent() #3 /wp-includes/class-wp-hook.php(332): WP_Hook->apply_filters() #4 /wp-includes/plugin.php(517): WP_Hook->do_action() #5 /woocommerce/includes/class-wc-ajax.php(96): do_action() #6 /wp-includes/class-wp-hook.php(308): WC_AJAX::do_wc_ajax() #7 /wp-includes/class-wp-hook.php(332): WP_Hook->apply_filters() #8 /wp-includes/plugin.php(517): WP_Hook->do_action() #9 /wp-includes/template-loader.php(13): do_action() #10 /wp-blog-header.php(19): require_once('...') #11 /index.php(17): require('...') #12 {main} thrown in /woocommerce-gateway-stripe/includes/class-wc-stripe-api.php at row 327

@glagonikas
Copy link
Author

@nicomollet @duotive @andreDane do you also see paid orders going into pending / failed?

My PR seems to be resolving the issue and we've not seen any unexpected behaviour so far.

Also, you have more than one gateways? Like Braintree etc?

I'm trying to debug another (possibly related) bug...

@kaushikasomaiya
Copy link
Contributor

Spotted in 6523490-zen while investigating a different issue.

@kaushikasomaiya
Copy link
Contributor

6585471-zen

@sybrew
Copy link

sybrew commented Aug 14, 2023

This happens when the customer tries to delete their old payment method after a payment has failed.

In WC_Stripe_Intent_Controller::verify_intent(), NULL is passed to WC_Stripe_Customer::delete_source() at code:

$customer = new WC_Stripe_Customer( wp_get_current_user()->ID );
$customer->delete_source( $intent->last_payment_error->source->id )

I'm not sure why an error would be used to fetch the ID, but in any case, a few lines prior, isset( $intent->last_payment_error ) is tested, while $intent->last_payment_error->source->id is used. I recommend extending the test to verify the children-objects' properties or otherwise always falling back to the actual metadata instead of the error.

--

Edit: looking more closely... what does that code even do when we already rely on woocommerce_payment_token_deleted?

@shaunkuschel
Copy link

[Internal] We received another report of this on 6712627-zen

@shaunkuschel shaunkuschel added the type: bug The issue is a confirmed bug. label Sep 27, 2023
@kaushikasomaiya
Copy link
Contributor

7238549-zen

@grig-23
Copy link

grig-23 commented Nov 29, 2023

7360317-zen - on this site, when a payment fails, a duplicate card entry is created under "payment methods" which is quite odd:

Screenshot 2023-12-04 at 11 23 50

The duplicate payment method does not work, but the original one often does if the customer retries a payment.

This is the error:

Argument 2 passed to WC_Stripe_API::detach_payment_method_from_customer() must be of the type string, null given, called in /home/sportin1/public_html/wp-content/plugins/woocommerce-gateway-stripe/includes/class-wc-stripe-customer.php on line 489 and defined in /home/sportin1/public_html/wp-content/plugins/woocommerce-gateway-stripe/includes/class-wc-stripe-api.php:327

@diegocurbelo diegocurbelo added the priority: medium The issue/PR is medium priority—it affects lots of customers substantially, but not critically. label Dec 11, 2023
@OmarFPG
Copy link

OmarFPG commented Apr 6, 2024

7950081-zd

@carolframen
Copy link

8062147-zen

@Snaacks
Copy link

Snaacks commented May 28, 2024

8219514-Zen appears to be experiencing this issue as well, may also be a secondary issue involved.

@dcx15
Copy link

dcx15 commented Jun 17, 2024

I am seeing the same error in my site's logs too

@csnlima1
Copy link

zen - 8311446

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
priority: medium The issue/PR is medium priority—it affects lots of customers substantially, but not critically. type: bug The issue is a confirmed bug.
Projects
None yet
Development

Successfully merging a pull request may close this issue.