-
Notifications
You must be signed in to change notification settings - Fork 206
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
Find existing refunds by refund ID when processing webhook #2581
Find existing refunds by refund ID when processing webhook #2581
Conversation
@reykjalin PR as discussed on the Woo Marketplace Slack |
public static function get_order_by_refund_id( $refund_id ) { | ||
global $wpdb; | ||
|
||
if ( class_exists( 'Automattic\WooCommerce\Utilities\OrderUtil' ) && OrderUtil::custom_orders_table_usage_is_enabled() ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. I haven't tested with Split Orders. I just checked the changes don't break our extension.
Tested the following scenarios:
- Full refund.
- Multiple refunds.
- Disputes.
- Full refund with HPOS enabled.
- Multiple refunds with HPOS enabled.
- Disputes with HPOS enabled.
I only left a non-blocking comment. Please update the PR with the latest develop
.
); | ||
$order_id = current( $orders ) ? current( $orders )->get_id() : false; | ||
} else { | ||
$order_id = $wpdb->get_var( $wpdb->prepare( "SELECT DISTINCT ID FROM $wpdb->posts as posts LEFT JOIN $wpdb->postmeta as meta ON posts.ID = meta.post_id WHERE meta.meta_value = %s AND meta.meta_key = %s", $refund_id, '_stripe_refund_id' ) ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
wc_get_orders()
seems to work here even with HPOS enabled. I assume you reused it from get_order_by_charge_id()
. It might be better to use wc_get_orders()
only if it works in both cases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you want to test yourself, to enable HPOS you can go to WooCommerce -> Settings -> Advanced -> "Enable the high performance order storage feature"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With HPOS disabled, unfortunately the meta_query is just ignored by wc_get_orders()
.
I did check this and I thought you were right for a moment, because it seems to return the correct order. But, if you test with the limit removed you can see actually all orders are being returned in date order, and naturally in testing it was normally the most recent order being tested with.
This implementation is consistent with get_order_by_intent_id()
and get_order_by_setup_intent_id()
, which would presumably have the same problem without the custom queries. get_order_by_charge_id()
is a little different because it doesn't need a meta query.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, it's always returning the last order (refund). Which is a coincidence because the last refund is not necessarily the one we are handling on the incoming Webhook.
@@ -1,6 +1,7 @@ | |||
*** Changelog *** | |||
|
|||
= x.x.x - 2023-xx-xx = | |||
* Fix - Lookup existing refunds by refund ID when processing webhooks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please update your branch with develop, this will likely go in 7.5.0
ca3866c
to
78500ac
Compare
Sorry @asumaran for the hold-up. When testing with HPOS I was seeing some odd behaviour. I've now realised that the As an aside, I can confirm this PR resolves the issue in Split Orders. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Thanks for your contribution @tc33!
I've now realised that the _stripe_refund_id meta data is not getting saved at all when HPOS is enabled. That looks like a bug, so I'll raise it as a separate issue
Great! Please add more details to replicate the issue.
As I'm looking through this code (to add these changes to an old version of this plugin) I am wondering if the whole |
Fixes #2580
Changes proposed in this Pull Request:
When handling a refund webhook, this attempts to lookup any existing refund by the refund ID first, before falling back to the current approach using the charge ID. As described in #2580, this will allow other extensions to decouple refunds from the original order the charge is against. The current approach leads to duplicate refunds on the WooCommerce side in these situations.
In general it seems to be more intuitive and more reliable to lookup the refund directly by the refund ID like this, rather than going via the order with the same charge ID.
Testing instructions
The basic behaviour to be tested:
In addition, to test the scenario I'm hoping to support:
The basic behaviour should not be changed so existing e2e tests for refunds should continue to be relevant. As far as I can tell there's nothing to specifically test for duplicate refunds though.
changelog.txt
andreadme.txt
(or does not apply)Post merge