Infinite order.updated webhooks being sent caused by `OrdersTableDataStore::migrate_post_record()` not able to sync subscription dates from `postmeta` to `orders_meta` #547
We discovered a problem with HPOS + data syncing where subscription date fields are not being synced properly from WP Posts -> Orders tables, and for stores with active order.updated webhooks, this causes an infinite loop of webhooks being sent.
A lot of investigation has been done internally (pelri8-lc-p2) but I'll give a quick run-down of the problem here as well.
When the subscription metadata stored in postmeta becomes out of sync with the data in wc_orders_meta and the modified date on the post is equal or most recent, WooCommerce attempts to sync the post data over to the orders table by calling migrate_post_record( $order, $post_order ).
Because our subscription date fields (i.e. start, trial_end, next payment etc) are set up as internal meta keys, these are skipped over by the migrate_meta_data_from_post_order() function and instead, WooCommerce then calls the set_order_prop() function to set these values:
Here's where the problem lies... we do not have any public setters for our date props therefore these internal meta keys remain out of sync.
From here on out, every time the subscription is read into memory, it continuously tries to sync the data and is always unsuccessful. When you have an order.updated webhook active, this results in a new order.updated webhook payload being scheduled each time the sync is attempted.
To Reproduce
Install the latest Woo & Subscriptions with HPOS as the data source & syncing/compatibility mode enabled.
Create/activate an order.updated webhook
Purchase a subscription product
Inside the wc_orders_meta table, search for the subscription ID and delete the value stored next to _schedule_next_payment (can be any other date value)
Trigger the order.updated event for the parent order for this subscription by running something like:
Describe the bug
We discovered a problem with HPOS + data syncing where subscription date fields are not being synced properly from WP Posts -> Orders tables, and for stores with active
order.updated
webhooks, this causes an infinite loop of webhooks being sent.A lot of investigation has been done internally (pelri8-lc-p2) but I'll give a quick run-down of the problem here as well.
When the subscription metadata stored in
postmeta
becomes out of sync with the data inwc_orders_meta
and the modified date on the post is equal or most recent, WooCommerce attempts to sync the post data over to the orders table by callingmigrate_post_record( $order, $post_order )
.Because our subscription date fields (i.e. start, trial_end, next payment etc) are set up as internal meta keys, these are skipped over by the
migrate_meta_data_from_post_order()
function and instead, WooCommerce then calls theset_order_prop()
function to set these values:Here's where the problem lies... we do not have any public setters for our date props therefore these internal meta keys remain out of sync.
From here on out, every time the subscription is read into memory, it continuously tries to sync the data and is always unsuccessful. When you have an
order.updated
webhook active, this results in a new order.updated webhook payload being scheduled each time the sync is attempted.To Reproduce
wc_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: