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

