wordpress Woocommerce简单类型产品试用功能

uujelgoq  于 2023-03-22  发布在  WordPress
关注(0)|答案(1)|浏览(145)

我在WordPress网站上工作,我有多个订阅和一个简单的类型的产品。订阅,如每周,每月,每年等。。使用woocommerce subscription插件,这是工作完美的罚款。和一个简单的类型的产品作为终身访问。(一次性购买)。
现在,我有另一个着陆页,其中提供的审判,如7天的审判,与订阅,该woocommerce subscription插件是提供选项的审判和工作完全正常.它允许用户以零价格结帐,但采取CC的详细信息,以便收取他们试用后自动过期.现在的问题来了,当我试图申请相同的报价(试用报价)在我的简单类型的产品(终身).
我已经做了一些研究,并添加了一些代码,使其工作到某个点。让我解释。
首先,我使用woocommerce_product_options_pricing action将 meta字段添加到产品中进行试用,即

function add_trial_period_field() {
    woocommerce_wp_text_input( array(
        'id' => PRODUCUT_TRIAL_PERIOD,
        'label' => __( 'Trial Period (in days)', 'woocommerce' ),
        'desc_tip' => 'true',
        'description' => __( 'Enter the number of days for the trial period. (Field will work for only Simple Type product)', 'woocommerce' ),
        'type' => 'number',
    ) );
}

然后使用woocommerce_process_product_meta_simple来保存数据。然后通过使用woocommerce_add_cart_item_datawoocommerce_before_calculate_totals操作,我为我刚刚创建的自定义字段添加了购物车 meta,并将项目价格设置为零,以便用户能够以零价格结账。到目前为止效果不错,但支付字段没有出现,所以我使用woocommerce_cart_needs_payment操作通过检查购物车中的产品来启用它们。
现在的主要问题是,它保存了简单类型产品的支付令牌,它确实保存了订单 meta中的customer_source_idstripe_source_id,但我无法向用户收取费用,因为它需要实际保存的stripe_payment_token
我只是想知道我如何才能迫使woocommerce创建和保存用户的stripe_payment_token为我的简单类型的产品也沿着订阅类型的产品。
很抱歉这篇文章很长,但我认为在这种情况下细节是必要的。如果你仍然在我的问题中找到遗漏的细节,我很抱歉,但你可以问我,我会分享任何需要的东西。
谢谢。

zwghvu4y

zwghvu4y1#

经过大量的斗争,我设法处理它,所以我在这里张贴的解决方案,以防其他人需要同样的解决方案:)
首先,我在过滤器woocommerce_payment_successful_result中捕获了stripe客户ID和支付令牌。

public function woo_payment_success_filter($result, $order_id){
    if ( ! $order_id )
        return;
    $order = wc_get_order( $order_id );
    $order_data = $order->get_data();
    $order_email = $order->get_billing_email();
    $userInfo = get_user_by("email", $order_email);
    $userid = $userInfo->data->ID;
    $display_name = $userInfo->data->display_name;
    // Iterating through each "line" items in the order
    foreach ($order->get_items() as $item_id => $item ) {
        $product_name = $item['name'];
        $product_id = $item['product_id'];
        $product = wc_get_product( $product_id );
        if ( $product->is_type( 'simple' ) ) {
            $trial_period = get_post_meta( $product_id, PRODUCUT_TRIAL_PERIOD, true );
            if ( ! empty( $trial_period ) ) {
                $order->update_meta_data(PRODUCUT_TRIAL_PERIOD, $trial_period);
                $customFound = $order->get_meta("_customer_user", true); //In simple product Trial case mostly setting as 0 default;
                if(!$customFound){
                    update_post_meta($order_id, "_customer_user", $userid);
                }
                $order->add_order_note( "Payment event scheduled after ${trial_period} days" );
                $order->save();
                update_user_meta($userid, "lifetime_trial_purchase", "yes");
                // SETTING PAYMENT TOKEN
                if(isset($_REQUEST['stripe_source'])){
                    $customer_id = get_post_meta($order_id, "_stripe_customer_id", true);
                    $source_id = $_REQUEST['stripe_source'];
                    update_user_meta($userid, "_stripe_customer_id", $customer_id);
                    update_user_meta($userid, "_stripe_source_id", $source_id);
                    $stripe_customer = new WC_Stripe_Customer( $userid );
                    $stripe_customer_args = array(
                        "email" => $order_email,
                        "description" => "Name: ".$display_name,
                        "name" => $display_name,
                        "metadata" => array()
                    );
                    if(!$stripe_customer->get_user_id()){
                        try {
                            $stripe_customer->create_customer($stripe_customer_args);
                        } catch (Exception $e) {
                            // DELETE ORDER AND REDIRECT TO ERROR PAGE (Homepage)
                            // you are order can not be processed at the time, please try again later.
                            wp_delete_post($order_id, true);
                            wp_redirect(get_site_url().'/#trialError');
                            exit;
                        }
                    } else {
                        $stripe_customer->set_id($customer_id);
                        $stripe_customer->update_customer($stripe_customer_args);
                    }
                    $stripe_sources  = $stripe_customer->get_sources();
                    if($stripe_sources && is_array($stripe_sources) && count($stripe_sources) > 0){
                        $payment_token = WC_Payment_Tokens::get_customer_tokens( $userid, "stripe" );
                        if(!($payment_token && count($payment_token))){
                            try {
                                foreach ($stripe_sources as $key => $source) {
                                    if($source->status == "chargeable"){
                                        $wc_token = new WC_Payment_Token_CC();
                                        $wc_token->set_token( $source->id );
                                        $wc_token->set_gateway_id( 'stripe' );
                                        $wc_token->set_card_type( strtolower( $source->card->brand ) );
                                        $wc_token->set_last4( $source->card->last4 );
                                        $wc_token->set_expiry_month( $source->card->exp_month );
                                        $wc_token->set_expiry_year( $source->card->exp_year );
                                        $wc_token->set_user_id( $userid );
                                        $wc_token->save();
                                        break;
                                    }
                                }
                            } catch (Exception $e) {
                                wp_delete_post($order_id, true);
                                wp_redirect(get_site_url().'/#trialError');
                                exit;
                            }
                        }
                    } else {
                        try {
                            $stripe_customer->add_source($source_id);
                        } catch (Exception $e) {
                            wp_delete_post($order_id, true);
                            wp_redirect(get_site_url().'/#trialError');
                            exit;
                        }
                    }
                    $timestamp = strtotime( "+$trial_period days" );
                    $args = array( $order_id, 1, $userid, $product_id );
                    wp_schedule_single_event( $timestamp, 'process_payment_after_trial_ends', $args );
                }
            }
        }
    }
    return $result;
}

在上面的过滤器中,我试图在Stripe上创建/更新客户,并将其支付令牌与CC/源卡详细信息一起保存
在最后wp_schedule_single_event是设置后,试用时间将收取用户.代码是下面的收费客户.

function process_payment_after_trial_end_simple_type_product( $order_id, $counter, $user_id, $product_id ) {
    global $woocommerce;
    $order = wc_get_order( $order_id );
    $product = wc_get_product( $product_id );
    $checkIfPaymentDoneAlready = update_post_meta($order_id, "payment_cleared_for_trial", true);
    if($checkIfPaymentDoneAlready == "yes"){
        return;
    }
    $product_price = $product->get_regular_price();
    if($order && $product){
        // This is the method to get existing Stripe Sources from users older orders (we have saved the source in previous function)
        $stripeData = $this->get_user_stripe_data($product_id,$user_id);
        if(isset($stripeData) && count($stripeData) > 1){
            $_GET['source'] = isset($stripeData['_stripe_source_id']['value']) ? $stripeData['_stripe_source_id']['value'] : '';
        }
        // Updating the order price as initial it was set to zero for trial checkout
        foreach ($order->get_items('line_item') as $key => $item) {
            $item->set_subtotal($product_price);
            $item->set_quantity( 1 );
            $item->set_total($product_price);
        }
        $order->calculate_totals();
        $order->save();
        $payment_token = WC_Payment_Tokens::get_customer_default_token( $user_id );
        $payment_method = "stripe"; //Right now defualt and configured method is only stripe.
        $_POST['wc-'.$payment_method.'-payment-token'] = $payment_token->get_id(); // setting post var as it will be required in process the payment
        $available_gateways = WC()->payment_gateways->get_available_payment_gateways();
        $stripe_response = $available_gateways[ $payment_method ]->process_payment( $order->get_id(), true, false, false, true  );
        if(isset($stripe_response['result']) && $stripe_response['result'] == "success"){
            $note = __( 'Payment processed after trial period ended.', 'textdomain' );
            $order->update_status( 'completed', $note, true );
            $order->payment_complete();
            update_post_meta($order_id, "payment_cleared_for_trial", "yes");
            $args = array( $order_id, $counter, $user_id, $product_id );
            wp_clear_scheduled_hook("process_payment_after_trial_ends", $args);
            $user = get_user_by("id", $user_id);
        } else {
            if ($counter == 6) {                    
                // UPDATE ORDER STATUS FAILED
                $order->update_status( 'failed', "Failed payment after retrying 5 times", true );
                $order->save();
                return;
            }
            $note = __( "Payment failed: Try {$counter}", 'textdomain' );
            $order->update_status( 'on-hold', $note, true );
            $retryTime = strtotime( "+{$counter} days" );
            $newCounter = $counter + 1;
            $args = array( $order_id, $newCounter, $user_id, $product_id );
            $timestamp = strtotime( "+1 days" );
            // Retrials if incase card is declined or insufficient balance
            // Sending Admin/Customer emails to notify them
            if ($counter == 1){
                // Customer Email
                $customerEmailOne = WC()->mailer()->get_emails()['QA_WCS_Email_Customer_Payment_Retry_One'];
                $customerEmailOne->trigger( $order_id, wc_get_order($order_id) );
                // Admin Email
                $adminEmailOne = WC()->mailer()->get_emails()['QA_WCS_Email_Admin_Payment_Retry_One'];
                $adminEmailOne->trigger( $order_id, wc_get_order($order_id) );

                $timestamp = strtotime( "+2 days" );
            }
            if ($counter == 2){
                // Customer Email
                $customerEmailOne = WC()->mailer()->get_emails()['QA_WCS_Email_Customer_Payment_Retry_Two'];
                $customerEmailOne->trigger( $order_id, wc_get_order($order_id) );
                // Admin Email
                $adminEmailOne = WC()->mailer()->get_emails()['QA_WCS_Email_Admin_Payment_Retry_Two'];
                $adminEmailOne->trigger( $order_id, wc_get_order($order_id) );

                $timestamp = strtotime( "+2 days" );
            }
            if ($counter == 3){
                // Customer Email
                $customerEmailOne = WC()->mailer()->get_emails()['QA_WCS_Email_Customer_Payment_Retry_Three'];
                $customerEmailOne->trigger( $order_id, wc_get_order($order_id) );
                // Admin Email
                $adminEmailOne = WC()->mailer()->get_emails()['QA_WCS_Email_Admin_Payment_Retry_Three'];
                $adminEmailOne->trigger( $order_id, wc_get_order($order_id) );

                $timestamp = strtotime( "+3 days" );
            }
            if ($counter == 4){
                // Customer Email
                $customerEmailOne = WC()->mailer()->get_emails()['QA_WCS_Email_Customer_Payment_Retry_Four'];
                $customerEmailOne->trigger( $order_id, wc_get_order($order_id) );
                // Admin Email
                $adminEmailOne = WC()->mailer()->get_emails()['QA_WCS_Email_Admin_Payment_Retry_Four'];
                $adminEmailOne->trigger( $order_id, wc_get_order($order_id) );

                $timestamp = strtotime( "+5 days" );
            }
            if ($counter == 5){
                // Customer Email
                $customerEmailOne = WC()->mailer()->get_emails()['QA_WCS_Email_Customer_Payment_Retry_Five'];
                $customerEmailOne->trigger( $order_id, wc_get_order($order_id) );
                // Admin Email
                $adminEmailOne = WC()->mailer()->get_emails()['QA_WCS_Email_Admin_Payment_Retry_Five'];
                $adminEmailOne->trigger( $order_id, wc_get_order($order_id) );

                $timestamp = strtotime( "+4 days" );
            }
            wp_schedule_single_event( $timestamp, 'process_payment_after_trial_ends', $args );
        }
        $order->save();
    }
}

就是这样:)希望这能有所帮助......如果任何人需要更多的解释或对这个问题有任何疑问......随时问:)

相关问题