woocommerce / woocommerce-gateway-stripe

The official Stripe Payment Gateway for WooCommerce
https://wordpress.org/plugins/woocommerce-gateway-stripe/
232 stars 204 forks source link

Call to a member function get_token() on null #3509

Open dekefake opened 1 week ago

dekefake commented 1 week ago

https://wordpress.org/support/topic/call-to-a-member-function-get_token-on-null/

It seems the plugin is sometimes causing issues with shoppers trying to pay for an order using a saved payment method. Here is the full stack trace. We’d appreciate if someone from the team could have a look, in order to get this part more stable.

Thanks in advance

[27-Sep-2024 17:05:20 UTC] PHP Fatal error:  Uncaught Error: Call to a member function get_token() on null in /opt/horrifiq/public_html/wp-content/plugins/woocommerce-gateway-stripe/includes/payment-methods/class-wc-stripe-upe-payment-gateway.php:969
Stack trace:
#0 /opt/horrifiq/public_html/wp-content/plugins/woocommerce-gateway-stripe/includes/payment-methods/class-wc-stripe-upe-payment-gateway.php(1449): WC_Stripe_UPE_Payment_Gateway->process_payment_with_saved_payment_method()
#1 /opt/horrifiq/public_html/wp-content/plugins/woocommerce-gateway-stripe/includes/class-wc-gateway-stripe.php(459): WC_Stripe_UPE_Payment_Gateway->retry_after_error()
#2 /opt/horrifiq/public_html/wp-content/plugins/woocommerce-gateway-stripe/includes/payment-methods/class-wc-stripe-upe-payment-gateway.php(733): WC_Gateway_Stripe->process_payment()
#3 /opt/horrifiq/public_html/wp-content/plugins/woocommerce/includes/class-wc-checkout.php(1062): WC_Stripe_UPE_Payment_Gateway->process_payment()
#4 /opt/horrifiq/public_html/wp-content/plugins/woocommerce/includes/class-wc-checkout.php(1293): WC_Checkout->process_order_payment()
#5 /opt/horrifiq/public_html/wp-content/plugins/woocommerce-gateway-stripe/includes/payment-methods/class-wc-stripe-payment-request.php(1702): WC_Checkout->process_checkout()
#6 /opt/horrifiq/public_html/wp-includes/class-wp-hook.php(324): WC_Stripe_Payment_Request->ajax_create_order()
#7 /opt/horrifiq/public_html/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters()
#8 /opt/horrifiq/public_html/wp-includes/plugin.php(517): WP_Hook->do_action()
#9 /opt/horrifiq/public_html/wp-content/plugins/woocommerce/includes/class-wc-ajax.php(96): do_action()
#10 /opt/horrifiq/public_html/wp-includes/class-wp-hook.php(324): WC_AJAX::do_wc_ajax()
#11 /opt/horrifiq/public_html/wp-includes/class-wp-hook.php(348): WP_Hook->apply_filters()
#12 /opt/horrifiq/public_html/wp-includes/plugin.php(517): WP_Hook->do_action()
#13 /opt/horrifiq/public_html/wp-includes/template-loader.php(13): do_action()
#14 /opt/horrifiq/public_html/wp-blog-header.php(19): require_once('/opt/horrifiq/p...')
#15 /opt/horrifiq/public_html/index.php(17): require('/home/816423.cl...')
#16 {main}
  thrown in /opt/horrifiq/public_html/wp-content/plugins/woocommerce-gateway-stripe/includes/payment-methods/class-wc-stripe-upe-payment-gateway.php on line 969

This bug caused shoppers to do chargebacks for "Duplicate" and it lead to my account acct_1H4UDbA4E9tWwRaZ being closed for "high risk". This isn't fair, I'd appreciate if you guys could push for reactivation.

james-allan commented 6 days ago

Hi @dekefake, thanks for filing the detailed issue description.

Following the stacktrace you provided, it appears this error occurs for customers using express payment buttons (Google Pay / Apple Pay), the payment intent object returned from Stripe has a "retryable" error and that's causing the Stripe Plugin to reattempt the payment request.

The code responsible for retrying the payment has a bug when called in this express payment request context, as it attempts to locate a saved payment method token, however there is no saved token at that point yet. We'll get that fixed up.

[!NOTE] 📓 For the dev that works on this, it looks like our retry_after_error() function in the UPE gateway class uses process_payment_with_saved_payment_method() to process the retry attempts. That function assumes that there is a saved WC token ID in the $_POST. The base gateway's retry_after_error() function uses the baseline process_payment() function instead. I'm not sure yet on the reason why the UPE version calls process_payment_with_saved_payment_method() and assumes there's a saved token.


This bug caused shoppers to do chargebacks for "Duplicate"

@dekefake, can you confirm if this error caused duplicate charges? As I mentioned above, the stack trace indicates that we would only reattempt the payment if Stripe responded with a retryable error. Retryable errors are invalid_request_error, idempotency_error, rate_limit_error, api_connection_error or api_error and so should only occur if the original charge request was unsuccessful. If you can provide more details on that, I'd be happy to look into that further. You should be able to find the reason for the failures in your Stripe dashboard on the individual Transaction pages (https://dashboard.stripe.com/test/payments). See example below.

Image
Example of a insufficient funds error in the Stripe Dashboard

Image
Payment intent (transaction) event logs

dekefake commented 6 days ago

Hi @james-allan , thank you for your quick feedback,

The bug itself does not appear to have caused duplicate charges, but it seems to make shoppers try multiple times and ultimately create duplicate orders. I am currently starting to doubt if this is directly related to this bug mentioned earlier

mattallan commented 5 days ago

This is a duplicate of https://github.com/woocommerce/woocommerce-gateway-stripe/issues/3503, I'll close that other issue and continue the conversation here.