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

Laravel中如何传递折扣价至任务实现Stripe延时扣款?

问题解决与实现修正

一、解决参数传递问题

Laravel 异步任务的参数传递需要通过任务类的构造函数实现,步骤如下:

1. 修改 LatePaymentCharge 任务类

添加构造函数接收所需参数,并将其声明为公共属性(确保能被序列化):

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class LatePaymentCharge implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    // 声明需要传递的参数
    public $slashPrice;
    public $productId;
    public $userEmail;

    // 构造函数接收参数并赋值
    public function __construct($slashPrice, $productId, $userEmail)
    {
        $this->slashPrice = $slashPrice;
        $this->productId = $productId;
        $this->userEmail = $userEmail;
    }

    public function handle()
    {
        // 后续逻辑写在这里
    }
}

2. 在控制器中传递参数并调度任务

替换原控制器中的调度代码,创建任务实例时传入参数:

// 控制器 secondHalf 方法中,替换原 dispatch 部分代码
$latePaymentJob = (new LatePaymentCharge($slashPrice, $id, 'thomsontochi@gmail.com'))
                    ->delay(Carbon::now()->addMinutes(5));
dispatch($latePaymentJob);

二、修正原实现的逻辑错误

你当前的任务代码存在核心逻辑问题:异步任务运行在后台 CLI 环境,没有 HTTP 请求上下文,调用 return redirect()->away($session->url); 完全无效,用户无法收到跳转响应。需根据实际业务需求调整实现方式:

场景1:自动延迟扣款(无需用户操作)

如果需要后台自动完成扣款,必须依赖用户已保存的支付方式(需提前通过 Stripe Setup Intent 收集),用 Payment Intent 实现:

public function handle()
{
    \Stripe\Stripe::setApiKey(config('stripe.sk'));

    // 从数据库获取用户关联的 Stripe 客户 ID(需提前存储)
    $stripeCustomerId = 'cus_xxxxxx'; // 替换为实际查询逻辑

    $paymentIntent = \Stripe\PaymentIntent::create([
        'amount' => $this->slashPrice * 100,
        'currency' => 'gbp',
        'customer' => $stripeCustomerId,
        'payment_method_types' => ['card'],
        'confirm' => true, // 自动尝试扣款
        'description' => "Half-price charge for product #{$this->productId}",
    ]);

    // 可选:将支付结果记录到数据库
    // Payment::create([...]);
}

场景2:延迟通知用户主动支付

如果需要用户手动完成支付,应在任务中创建 Checkout Session,然后通过邮件/消息通知用户支付链接:

use Illuminate\Support\Facades\Mail;
// 假设你已创建 LatePaymentNotification 邮件类
use App\Mail\LatePaymentNotification;

public function handle()
{
    \Stripe\Stripe::setApiKey(config('stripe.sk'));

    $session = \Stripe\Checkout\Session::create([
        'line_items' => [
            [
                'price_data' => [
                    'currency' => 'gbp',
                    'product_data' => [
                        'name' => 'Tax online payment (half price)',
                    ],
                    'unit_amount' => $this->slashPrice * 100,
                ],
                'quantity' => 1,
            ],
        ],
        'mode' => 'payment',
        'success_url' => route('success'),
        'cancel_url' => url('/single-product/'.$this->productId),
        'customer_email' => $this->userEmail, // 预填用户邮箱
    ]);

    // 发送邮件给用户,包含支付链接
    Mail::to($this->userEmail)->send(new LatePaymentNotification($session->url));
}

三、总结

  • 参数传递通过任务构造函数即可解决,需确保传递的参数可被序列化(模型类可直接传递,Laravel 会自动处理);
  • 异步任务无法直接返回 HTTP 响应,必须根据业务需求选择「自动扣款」或「通知用户支付」的实现方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 00:41:13