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
相关产品推荐
相关产品推荐

