Subscription module: add gateway capability flow and UX fixes
This commit is contained in:
@@ -38,8 +38,15 @@ class SubscriptionModule
|
||||
add_action('woocommerce_order_status_completed', [__CLASS__, 'maybe_create_subscription'], 10, 1);
|
||||
add_action('woocommerce_order_status_processing', [__CLASS__, 'maybe_create_subscription'], 10, 1);
|
||||
|
||||
// Hook into order status change to handle manual renewal payments
|
||||
// Hook into order status change to handle manual renewal payments and status sync
|
||||
add_action('woocommerce_order_status_changed', [__CLASS__, 'on_order_status_changed'], 10, 3);
|
||||
|
||||
// Hook into entity deletions for cleanup and state sync
|
||||
add_action('woocommerce_trash_order', [__CLASS__, 'on_order_deleted']);
|
||||
add_action('woocommerce_delete_order', [__CLASS__, 'on_order_deleted']);
|
||||
add_action('trashed_post', [__CLASS__, 'on_post_deleted']);
|
||||
add_action('deleted_post', [__CLASS__, 'on_post_deleted']);
|
||||
add_action('delete_user', [__CLASS__, 'on_user_deleted']);
|
||||
|
||||
// Modify add to cart button text for subscription products
|
||||
add_filter('woocommerce_product_single_add_to_cart_text', [__CLASS__, 'subscription_add_to_cart_text'], 10, 2);
|
||||
@@ -275,6 +282,14 @@ class SubscriptionModule
|
||||
|
||||
$product_id = $product->get_id();
|
||||
if (get_post_meta($product_id, '_woonoow_subscription_enabled', true) === 'yes') {
|
||||
// Guests cannot have subscriptions — create_from_order() rejects guest orders silently
|
||||
// (H6). Show the standard add-to-cart text and let the regular checkout flow handle
|
||||
// guest sign-up. The subscription will only be created if/when the customer converts
|
||||
// to a user. We do NOT advertise a subscription capability the system cannot honor.
|
||||
if (!is_user_logged_in()) {
|
||||
return $text;
|
||||
}
|
||||
|
||||
$settings = ModuleRegistry::get_settings('subscription');
|
||||
return $settings['button_text_subscribe'] ?? __('Subscribe Now', 'woonoow');
|
||||
}
|
||||
@@ -532,7 +547,7 @@ class SubscriptionModule
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle manual renewal payment completion
|
||||
* Handle order status changes for both parent and renewal orders
|
||||
*/
|
||||
public static function on_order_status_changed($order_id, $old_status, $new_status)
|
||||
{
|
||||
@@ -540,24 +555,108 @@ class SubscriptionModule
|
||||
return;
|
||||
}
|
||||
|
||||
if (!in_array($new_status, ['processing', 'completed'])) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if this is a subscription renewal order
|
||||
global $wpdb;
|
||||
$table_orders = $wpdb->prefix . 'woonoow_subscription_orders';
|
||||
|
||||
$link = $wpdb->get_row($wpdb->prepare(
|
||||
// Find if this order is linked to any subscription
|
||||
$links = $wpdb->get_results($wpdb->prepare(
|
||||
"SELECT subscription_id, order_type FROM $table_orders WHERE order_id = %d",
|
||||
$order_id
|
||||
));
|
||||
|
||||
if ($link && $link->order_type === 'renewal') {
|
||||
$order = wc_get_order($order_id);
|
||||
if ($order) {
|
||||
SubscriptionManager::handle_renewal_success($link->subscription_id, $order);
|
||||
if (empty($links)) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($links as $link) {
|
||||
$subscription = SubscriptionManager::get($link->subscription_id);
|
||||
if (!$subscription) continue;
|
||||
|
||||
if ($link->order_type === 'renewal') {
|
||||
if (in_array($new_status, ['processing', 'completed'])) {
|
||||
$order = wc_get_order($order_id);
|
||||
if ($order) {
|
||||
SubscriptionManager::handle_renewal_success($link->subscription_id, $order);
|
||||
}
|
||||
} elseif ($new_status === 'failed') {
|
||||
SubscriptionManager::handle_renewal_failure($link->subscription_id);
|
||||
} elseif ($new_status === 'cancelled') {
|
||||
SubscriptionManager::update_status($link->subscription_id, 'cancelled', 'renewal_order_cancelled');
|
||||
} elseif ($new_status === 'refunded') {
|
||||
SubscriptionManager::update_status($link->subscription_id, 'on-hold', 'renewal_order_refunded');
|
||||
}
|
||||
} elseif ($link->order_type === 'parent') {
|
||||
if (in_array($new_status, ['refunded', 'cancelled'])) {
|
||||
SubscriptionManager::update_status($link->subscription_id, 'cancelled', 'parent_order_' . $new_status);
|
||||
} elseif ($new_status === 'on-hold') {
|
||||
SubscriptionManager::update_status($link->subscription_id, 'on-hold', 'parent_order_on_hold');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle order trashing/deletion
|
||||
*/
|
||||
public static function on_order_deleted($order_id)
|
||||
{
|
||||
global $wpdb;
|
||||
$table_orders = $wpdb->prefix . 'woonoow_subscription_orders';
|
||||
|
||||
$links = $wpdb->get_results($wpdb->prepare(
|
||||
"SELECT subscription_id, order_type FROM $table_orders WHERE order_id = %d",
|
||||
$order_id
|
||||
));
|
||||
|
||||
foreach ($links as $link) {
|
||||
if ($link->order_type === 'parent') {
|
||||
SubscriptionManager::update_status($link->subscription_id, 'cancelled', 'parent_order_deleted');
|
||||
} elseif ($link->order_type === 'renewal') {
|
||||
SubscriptionManager::update_status($link->subscription_id, 'on-hold', 'renewal_order_deleted');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle product trashing/deletion
|
||||
*/
|
||||
public static function on_post_deleted($post_id)
|
||||
{
|
||||
if (get_post_type($post_id) !== 'product') {
|
||||
return;
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
$table_subs = $wpdb->prefix . 'woonoow_subscriptions';
|
||||
|
||||
// Find active/on-hold subscriptions for this product
|
||||
$affected = $wpdb->get_col($wpdb->prepare(
|
||||
"SELECT id FROM $table_subs WHERE product_id = %d AND status IN ('active', 'on-hold', 'pending')",
|
||||
$post_id
|
||||
));
|
||||
|
||||
foreach ($affected as $sub_id) {
|
||||
SubscriptionManager::update_status($sub_id, 'on-hold', 'product_deleted');
|
||||
// Fire an action so merchants can hook in and get alerted
|
||||
do_action('woonoow/subscription/product_deleted_alert', $sub_id, $post_id);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle user deletion
|
||||
*/
|
||||
public static function on_user_deleted($user_id)
|
||||
{
|
||||
global $wpdb;
|
||||
$table_subs = $wpdb->prefix . 'woonoow_subscriptions';
|
||||
|
||||
$affected = $wpdb->get_col($wpdb->prepare(
|
||||
"SELECT id FROM $table_subs WHERE user_id = %d AND status != 'cancelled'",
|
||||
$user_id
|
||||
));
|
||||
|
||||
foreach ($affected as $sub_id) {
|
||||
SubscriptionManager::update_status($sub_id, 'cancelled', 'user_deleted');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user