You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让WooCommerce为Simple类型产品生成并保存stripe_payment_token?

解决WooCommerce Simple产品试用场景下Stripe支付令牌缺失问题

核心原因

WooCommerce Subscriptions插件会自动处理订阅产品的支付令牌生成与存储逻辑,但Simple类型产品默认没有这套机制,因此需要手动实现支付令牌的捕获与保存。

解决方案步骤

1. 强制零金额订单生成Stripe支付令牌

默认情况下Stripe网关会跳过零金额订单的支付令牌生成,需要通过钩子强制启用该逻辑:

add_filter('wc_stripe_zero_amount_requires_payment_method', '__return_true');

2. 捕获并保存支付令牌到订单元数据

在订单创建时,从结账请求中提取Stripe令牌,将其保存到对应订单的元数据中:

function save_stripe_payment_token_to_order($order) {
    // 仅处理带试用天数的Simple产品订单
    $has_trial = false;
    foreach ($order->get_items() as $item) {
        $product = $item->get_product();
        if ($product->is_type('simple') && get_post_meta($product->get_id(), PRODUCUT_TRIAL_PERIOD, true)) {
            $has_trial = true;
            break;
        }
    }
    if (!$has_trial) return;

    // 获取并保存Stripe令牌
    $stripe_token = isset($_POST['stripe_token']) ? sanitize_text_field($_POST['stripe_token']) : '';
    if ($stripe_token) {
        $order->update_meta_data('stripe_payment_token', $stripe_token);
        $order->save();
    }
}
add_action('woocommerce_checkout_create_order', 'save_stripe_payment_token_to_order');

3. 试用到期后触发令牌扣费逻辑

通过定时任务定期检查到期的试用订单,调用Stripe API使用保存的令牌完成扣费:

function process_trial_charge($order_id) {
    $order = wc_get_order($order_id);
    if (!$order) return;

    // 校验订单是否符合扣费条件
    $stripe_token = $order->get_meta('stripe_payment_token');
    $trial_days = 0;
    foreach ($order->get_items() as $item) {
        $product = $item->get_product();
        $trial_days = get_post_meta($product->get_id(), PRODUCUT_TRIAL_PERIOD, true);
        if ($trial_days) break;
    }
    if (!$stripe_token || $order->is_paid() || $trial_days <= 0) return;

    // 检查试用是否到期
    $order_date = $order->get_date_created();
    $trial_end_date = $order_date->modify("+$trial_days days");
    if (current_time('timestamp') < $trial_end_date->getTimestamp()) return;

    // 调用Stripe API执行扣费
    try {
        \Stripe\Stripe::setApiKey(WC_Stripe_Helper::get_secret_key());
        
        $charge = \Stripe\Charge::create([
            'amount' => $order->get_total() * 100, // Stripe以分为单位计费
            'currency' => $order->get_currency(),
            'source' => $stripe_token,
            'description' => '试用到期扣费 - 订单#' . $order_id,
            'metadata' => ['order_id' => $order_id]
        ]);

        // 扣费成功后更新订单状态
        if ($charge->status === 'succeeded') {
            $order->payment_complete($charge->id);
            $order->add_order_note('试用到期,已通过Stripe完成扣费,Charge ID: ' . $charge->id);
        }
    } catch (\Stripe\Exception\CardException $e) {
        $order->add_order_note('试用扣费失败:' . $e->getError()->message);
    } catch (\Exception $e) {
        $order->add_order_note('试用扣费异常:' . $e->getMessage());
    }
}

4. 配置定时任务触发扣费

添加WordPress定时任务,每天执行一次到期订单检查:

function setup_trial_charge_cron() {
    if (!wp_next_scheduled('daily_trial_charge_process')) {
        wp_schedule_event(time(), 'daily', 'daily_trial_charge_process');
    }
}
add_action('wp', 'setup_trial_charge_cron');

// 遍历所有符合条件的订单执行扣费
function run_daily_trial_charges() {
    $orders = wc_get_orders([
        'status' => 'on-hold', // 假设试用订单状态为on-hold
        'type' => 'simple',
        'meta_key' => 'stripe_payment_token',
        'meta_compare' => 'EXISTS'
    ]);
    foreach ($orders as $order) {
        process_trial_charge($order->get_id());
    }
}
add_action('daily_trial_charge_process', 'run_daily_trial_charges');

注意事项

  • 确保Stripe插件版本为最新,API密钥配置正确
  • 测试阶段可缩短试用天数,快速验证流程
  • 需处理卡片过期、余额不足等异常场景,保证订单状态同步更新

内容的提问来源于stack exchange,提问作者mrabro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 18:32:10