Closed mattallan closed 6 months ago
I was able to test these changes on the site with issues today and all of the subscriptions that previously reported differences between the post and order data were able to properly sync after applying the changeset. Thank you!
I was able to test these changes on the site with issues today and all of the subscriptions that previously reported differences between the post and order data were able to properly sync after applying the changeset. Thank you!
That's fantastic news, thanks for letting us know @prettyboymp. 😃
Thanks @james-allan for the additions to the docblock and @prettyboymp for confirming the fix on your end!! Merging this!
Fixes #547
Description
This PR is fixing an issue where trying to sync/migrate our
_scheduled_{date_type}
metadata from thewp_postmeta
table over to HPOSwc_orders_meta
table does not work and results in a continuously attempting to sync subscription data each time it's read into memory.This issue severely impacts stores that are using the
order.updated
webhook because when building the webhook payload, a subscription object is read into memory, attempts to sync data and fails, which then results in a new webhook payload being scheduled. Because the subscription remains out of the sync, the next webhook payload will repeat the same process resulting in an infinite loop of theorder.updated
webhook being sent.When WooCommerce attempts to sync/migrate postmeta over to the orders_meta table, it calls
migrate_post_record()
which uses two methods to sync the data:migrate_meta_data_from_post_order()
, andset_order_prop()
The first method calls
OrdersTableDataStore::get_diff_meta_data_between_orders( $order, $post_order )
which returns an array of meta keys/value that are different between the two objects. This function strictly ignores any meta that is listed in$internal_meta_keys
which means the following subscription meta won't be synced by this function:_billing_period
_billing_interval
_suspension_count
_cancelled_email_sent
_requires_manual_renewal
_trial_period
_schedule_trial_end
_schedule_next_payment
_schedule_cancelled
_schedule_end
_schedule_payment_retry
_schedule_start
_subscription_switch_data
The second method
set_order_prop()
attempts to call$subscription->set_{meta_key}()
and then triesWCS_Orders_Table_Subscription_Data_Store->set_{meta_key}()
to sync meta.Out of the above internal meta keys, the only meta keys that don't have setters are:
_schedule_trial_end
_schedule_next_payment
_schedule_cancelled
_schedule_end
_schedule_payment_retry
_schedule_start
Given this, the solution I've opted to go with in this PR is to add these setters.
How to test this PR
Get into the infinite loop
trunk
of this repo.https://public.requestbin.com/r
and spin up a fresh endpoint to send webhooks toorder.updated
webhookwc_orders_meta
table, search for the subscription ID and delete the value stored next to_schedule_next_payment
(can be any other date value)order.updated
event for the parent order for this subscription by running something like:woocommerce_deliver_webhook_async
action for the parent order.woocommerce_deliver_webhook_async
for the same parent order is scheduled.wc_orders_meta
table and confirm the_schedule_next_payment
is still empty.Confirm the fix
woocommerce_deliver_webhook_async
againwc_orders_meta
table and confirm the_schedule_next_payment
has been synced/migrated from the postmeta tableProduct impact