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

Laravel中用srmklive/paypal实现PayPal授权支付而非立即扣款

Laravel中配置PayPal授权支付(延迟收款)

要实现用户下单后仅授权扣款额度、卖家可手动审核收款或拒绝的需求,需基于srmklive/paypal包修改现有逻辑,核心是将「立即捕获付款」改为「仅授权额度」,再补充卖家手动操作的功能,具体步骤如下:

1. 修改订单创建逻辑(Checkout控制器)

将创建订单的intent从CAPTURE(立即捕获)改为AUTHORIZE(仅授权),这是实现延迟收款的核心修改:

if ($request->input('payment_option') === 'paypal'){
    $provider = new PayPalClient();
    $provider->setApiCredentials(config('paypal'));
    $paypalToken = $provider->getAccessToken();

    $response = $provider->createOrder([
        "intent" => "AUTHORIZE", // 关键修改:从CAPTURE改为AUTHORIZE
        "application_context" => [
            "return_url" => route('payment.success'),
            "cancel_url" => route('payment.cancel'),
        ],
        "purchase_units" => [
            [
                'description' => "Globus Transfers - " . strtoupper($vehicle) . " taxi transfer reservation from $departureLocationName to $destinationLocationName.",
                "amount" => [
                    "currency_code" => "EUR",
                    "value" => $price
                ],
                
            ]
        ]
    ]);

    if(isset($response['id']) && $response['id'] != 'null') {
        session(['paypal_order_id' => $response['id']]);

        foreach($response['links'] as $link){
            if($link['rel'] === 'approve'){
                return redirect()->away($link['href']);
            }
        }
    } else {
        return redirect()->route('payment.cancel');
    }
}

2. 修改支付成功回调逻辑(PaymentController)

回调中不再立即捕获款项,而是验证授权状态并更新订单为「已授权」,等待卖家后续操作:

if($routeAndReservationData['payment_option'] === 'paypal'){
    $provider = new PayPalClient();
    $provider->setApiCredentials(config('paypal'));
    $paypalToken = $provider->getAccessToken();
    $orderId = session('paypal_order_id');
    
    // 获取订单详情,确认授权状态
    $orderDetails = $provider->showOrderDetails($orderId);
    
    // 检查订单是否已成功授权
    if(isset($orderDetails['status']) && $orderDetails['status'] == 'AUTHORIZED'){
        // 更新预订记录为已授权状态,新增payment_status字段标记状态
        $reservation->update([
            'paypal_order_id' => $orderId,
            'payment_status' => 'authorized'
        ]);
        
        // 发送通知:告知用户订单已授权,等待商家审核
        Mail::to($routeAndReservationData['email'])->send(new UserReservationAuthorized($routeAndReservationData));
        Mail::to('example@gmail.com')->send(new CompanyReservationAwaitingReview($routeAndReservationData));
        
        session()->flush();
        return view('payment.authorized'); // 新增授权成功页面,提示用户等待审核
    } else {
        return view('payment.cancel');
    }
}

3. 实现卖家后台手动操作功能

需为卖家提供两个核心操作入口,对应两个API调用:

捕获授权金额(确认收款)

当卖家审核通过订单后,调用API捕获已授权的款项:

public function capturePayment($reservationId)
{
    $reservation = Reservation::findOrFail($reservationId);
    $orderId = $reservation->paypal_order_id;
    
    $provider = new PayPalClient();
    $provider->setApiCredentials(config('paypal'));
    $provider->getAccessToken();
    
    // 调用捕获API
    $captureResponse = $provider->capturePaymentOrder($orderId);
    
    if(isset($captureResponse['status']) && $captureResponse['status'] == 'COMPLETED'){
        // 更新预订状态为已付款
        $reservation->update(['payment_status' => 'paid']);
        
        // 发送付款成功通知给用户
        Mail::to($reservation->email)->send(new UserReservationPaid($reservation));
        return back()->with('success', '款项已成功捕获');
    } else {
        return back()->with('error', '捕获款项失败');
    }
}

取消授权(拒绝订单)

若卖家拒绝订单,调用API取消授权,释放用户的扣款额度:

public function cancelAuthorization($reservationId)
{
    $reservation = Reservation::findOrFail($reservationId);
    $orderId = $reservation->paypal_order_id;
    
    $provider = new PayPalClient();
    $provider->setApiCredentials(config('paypal'));
    $provider->getAccessToken();
    
    // 调用取消授权API
    $cancelResponse = $provider->cancelOrder($orderId);
    
    if(isset($cancelResponse['status']) && $cancelResponse['status'] == 'CANCELLED'){
        // 更新预订状态为已取消
        $reservation->update(['payment_status' => 'cancelled']);
        
        // 发送取消通知给用户
        Mail::to($reservation->email)->send(new UserReservationCancelled($reservation));
        return back()->with('success', '授权已取消');
    } else {
        return back()->with('error', '取消授权失败');
    }
}

关键注意事项

  • 授权有效期:PayPal授权的款项默认有效期为29天,需在此期间内完成捕获,否则授权自动失效
  • 状态管理:建议在预订表中新增payment_status字段,标记「未支付/已授权/已付款/已取消」等状态,便于订单管理
  • 商家界面:需在商家后台展示所有已授权的订单,提供「捕获」和「取消」按钮,关联上述两个操作方法

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 23:43:45