当 WooCommerce 中的订阅处于“暂停”状态时,发送失败订单的发票通知

问题描述 投票:0回答:1

我正在尝试找到一种方法,即使客户订阅使用 WooCommerce 订阅处于暂停状态,也可以继续生成发票。

我遇到的问题是,一旦付款失败后订阅被“暂停”,WooCommerce 就会停止生成发票(相关订单获得失败状态)

有时,我们的团队没有注意到这些订阅,可能几个月都没有生成发票,而客户却继续收到我们的产品。

由于我们的订阅产品是实体产品,而不是数字产品,因此我们需要 WooCommerce 每月继续生成发票并发送电子邮件,即使订阅处于暂停状态也是如此。

我正在尝试使用此代码即使在订阅“暂停”时也能生成发票。

// Generate invoice even if the subscription is on-hold
add_action('woocommerce_scheduled_subscription_payment', 'generate_invoice_for_on_hold_subscription', 10, 2);
function generate_invoice_for_on_hold_subscription( $amount_to_charge, $subscription ) {
    // Check if the subscription is on-hold
    if ($subscription->has_status('on-hold')) {
        // Get the order related to the subscription
        $order = wc_create_order(array(
            'customer_id' => $subscription->get_customer_id()
        ));

        // Add subscription items to the order
        foreach ($subscription->get_items() as $item_id => $item) {
            $product_id = $item->get_product_id();
            $quantity = $item->get_quantity();
            $order->add_product(wc_get_product($product_id), $quantity);
        }

        // Set billing information
        $order->set_address($subscription->get_address('billing'), 'billing');

        // Create invoice by changing the order status to pending
        $order->update_status('pending');
        
        // Send the invoice email to the customer
        WC()->mailer()->get_emails()['WC_Email_Customer_Invoice']->trigger($order->get_id());
    }
}

我对代码的期望:

  • 检查订阅状态是否为“暂停”。
  • 创建从失败订单克隆的新“待处理”订单。
  • 向客户发送发票电子邮件通知。

即使账户被冻结,如何让发票继续生成?

php woocommerce orders invoice woocommerce-subscriptions
1个回答
0
投票

请注意,挂钩在

woocommerce_scheduled_subscription_payment
操作挂钩 中的函数仅具有
$subscription_id
作为唯一参数。
但不是
$amount_to_charge
$subscription

您的代码中有一些错误,请尝试以下操作:

// Generate invoice even if the subscription is on-hold
add_action('woocommerce_scheduled_subscription_payment', 'generate_invoice_for_on_hold_subscription', 10, 1);
function generate_invoice_for_on_hold_subscription( $subscription_id ) {
     // Get the WC_Subscription object
    $subscription = new WC_Subscription( $subscription_id );

    // Check if the subscription status is "on-hold"
    if ( $subscription->has_status( 'on-hold' ) ) {
        $orders_ids   = $subscription->get_related_orders(); // get related order
        $order_id     = absint( current( $orders_ids ) ); // Get current order ID
        $order        = wc_get_order( $order_id ); // Get the WC_Order object to

        if ( is_a( $order, 'WC_Order' ) && $order->has_status( 'failed' ) ) {
            // Tag the order with custom meta data
            $order->update_meta_data('_invoice_sent', '1');

            // Change back the order status to pending and save
            $order->update_status( 'pending', esc_html__('Status change from failed to pending', true );

            // Send the invoice email to the customer
            WC()->mailer()->get_emails()['WC_Email_Customer_Invoice']->trigger( $order->get_id() );
        }
    }
}

应该可以。


如果不起作用,您可以尝试以下钩子,为失败的订单触发:

add_action( 'woocommerce_order_status_failed', 'generate_invoice_for_on_hold_subscription', 10, 2 );
function generate_invoice_for_on_hold_subscription( $order_id, $order ){
    // Get subscriptions from order ID
    $subscriptions_ids = wcs_get_subscriptions_for_order( $order_id, array( 'order_type' => 'any' ) );
    
    // Exit if there are no subscriptions linked to the current failed order
    if ( ! $subscriptions_ids ) {
        return; 
    }
    // Get the WC_Subscription object
    $subscription = new WC_Subscription( current($subscriptions_ids) );

    // Check if the subscription status is "on-hold"
    if ( $subscription->has_status( 'on-hold' ) && $order->get_meta('_invoice_sent', '1')) {
        // Tag the order with custom meta data
        $order->update_meta_data('_invoice_sent', '1');

        // Change back the order status to pending and save
        $order->update_status( 'pending', esc_html__('Status change from failed to pending', true );

        // Send the invoice email to the customer
        WC()->mailer()->get_emails()['WC_Email_Customer_Invoice']->trigger( $order->get_id() );
    }
}

应该可以。

© www.soinside.com 2019 - 2024. All rights reserved.