Updates to 7.9.0

This commit is contained in:
WooCommerce
2025-09-18 10:16:37 +00:00
parent 7d081fb691
commit 708a1fa4a4
53 changed files with 1174 additions and 401 deletions

View File

@@ -2028,30 +2028,49 @@ class WC_Subscription extends WC_Order {
}
/**
* When a payment fails, either for the original purchase or a renewal payment, this function processes it.
* When related order fails, update the status of the related order and the subscription.
* Related order can fail because of payment failure or because of other reasons.
*
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
* @param string $new_status The new status to set for the subscription.
* @param WC_Order|bool $related_order The related order that failed payment. False if no related order is found.
* @since 7.9.0 Replaces payment_failed() method.
*/
public function payment_failed( $new_status = 'on-hold' ) {
// Make sure the last order's status is set to failed
$last_order = $this->get_last_order( 'all', 'any' );
if ( false !== $last_order ) {
$last_order->update_meta_data( self::RENEWAL_FAILED_META_KEY, wc_bool_to_string( true ) );
if ( false === $last_order->has_status( 'failed' ) ) {
remove_filter( 'woocommerce_order_status_changed', 'WC_Subscriptions_Renewal_Order::maybe_record_subscription_payment' );
$last_order->update_status( 'failed' );
add_filter( 'woocommerce_order_status_changed', 'WC_Subscriptions_Renewal_Order::maybe_record_subscription_payment', 10, 3 );
} else {
// If we didn't update the status, save the order to make sure our self::RENEWAL_FAILED_META_KEY meta data is saved.
$last_order->save();
public function payment_failed_for_related_order( $new_status = 'on-hold', $related_order = false ) {
if ( is_a( $related_order, 'WC_Order' ) ) {
$related_order_was_modified = false;
if ( wcs_order_contains_renewal( $related_order ) ) {
$related_order->update_meta_data( self::RENEWAL_FAILED_META_KEY, wc_bool_to_string( true ) );
$related_order_was_modified = true;
}
}
// Log payment failure on order
$this->add_order_note( __( 'Payment failed.', 'woocommerce-subscriptions' ) );
if ( false === $related_order->has_status( 'failed' ) ) {
remove_filter( 'woocommerce_order_status_changed', 'WC_Subscriptions_Renewal_Order::maybe_record_subscription_payment' );
// No need to set $related_order_was_modified to true here because update status will save the changes.
$related_order->update_status( 'failed' );
add_filter( 'woocommerce_order_status_changed', 'WC_Subscriptions_Renewal_Order::maybe_record_subscription_payment', 10, 3 );
} elseif ( $related_order_was_modified ) {
// If we didn't update the status, save the order to make sure our self::RENEWAL_FAILED_META_KEY meta data is saved.
$related_order->save();
}
$this->add_order_note(
sprintf(
// translators: %d: related order ID
__( 'Related order #%d failed.', 'woocommerce-subscriptions' ),
$related_order->get_id()
)
);
} else {
wc_get_logger()->debug(
'WC_Subscription::payment_failed_for_related_order is called without a related order',
array(
'subscription_id' => $this->get_id(),
'new_status' => $new_status,
'related_order' => $related_order,
'backtrace' => true,
)
);
}
// Allow a short circuit for plugins & payment gateways to force max failed payments exceeded
// This also forces the new status to be 'cancelled' if the filter is applied or the subscription is pending-cancel
@@ -2068,11 +2087,23 @@ class WC_Subscription extends WC_Order {
do_action( 'woocommerce_subscription_payment_failed', $this, $new_status );
if ( false !== $last_order && wcs_order_contains_renewal( $last_order ) ) {
do_action( 'woocommerce_subscription_renewal_payment_failed', $this, $last_order );
if ( false !== $related_order && wcs_order_contains_renewal( $related_order ) ) {
do_action( 'woocommerce_subscription_renewal_payment_failed', $this, $related_order );
}
}
/**
* When a payment fails, either for the original purchase or a renewal payment, this function processes it.
*
* @since 1.0.0 - Migrated from WooCommerce Subscriptions v2.0
* @deprecated 7.9.0 - The method incorrectly assumes that the last order failed, and sometimes causes side effects.Use payment_failed_for_related_order instead.
*/
public function payment_failed( $new_status = 'on-hold' ) {
// Make sure the last order's status is set to failed
$last_order = $this->get_last_order( 'all', 'any' );
$this->payment_failed_for_related_order( $new_status, $last_order );
}
/*** Refund related functions are required for the Edit Order/Subscription screen, but they aren't used on a subscription ************/
/**