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

Laravel中用srmklive/laravel-paypal实现带学生ID的PayPal支付管理

使用srmklive/laravel-paypal实现学生关联支付的解决方案

针对你提出的三个技术需求,结合srmklive/laravel-paypal包的特性,解决方案如下:


1. 将学生ID加入支付请求,取消时获取并入库

PayPal支持通过自定义字段传递业务关联数据,你可以在创建订阅时将学生ID存入custom字段或结构化的metadata中,后续从回调或API中提取。

修改创建订阅的代码:

$studentId = 123; // 替换为实际学生ID
$provider = \PayPal::setProvider();
$provider->setApiCredentials(config('paypal'));
$token = $provider->getAccessToken();
$provider->setAccessToken($token);

$response = $provider->addProduct('Demo Product', 'Demo Product', 'SERVICE', 'SOFTWARE')
    ->addDailyPlan('Demo Plan', 'Demo Plan', 10.50)
    ->setReturnAndCancelUrl('https://example.com/paypal-success', 'https://example.com/paypal-cancel')
    ->setCustom($studentId) // 存入学生ID到自定义字段
    // 可选:用metadata存储结构化数据(推荐复杂场景)
    // ->addMetadata('student_id', $studentId)
    ->setupSubscription('John Doe', 'john@example.com', '2023-02-21T15:47:00+00:00');

// 保存订阅ID与学生ID的关联到数据库
DB::table('student_subscriptions')->insert([
    'student_id' => $studentId,
    'subscription_id' => $response['id'],
    'status' => 'pending'
]);

处理取消回调:

在paypal-cancel对应的控制器方法中,提取学生ID并更新数据库:

public function paypalCancel(Request $request)
{
    // 直接从请求参数获取custom字段
    $studentId = $request->get('custom');
    
    // 若使用metadata,需通过订阅ID查询详情
    // $subscriptionId = $request->get('subscription_id');
    // $subscription = $provider->showSubscriptionDetails($subscriptionId);
    // $studentId = $subscription['metadata']['student_id'];
    
    DB::table('student_subscriptions')
        ->where('student_id', $studentId)
        ->update(['status' => 'cancelled']);
    
    return redirect()->route('student.dashboard')->with('message', '支付已取消');
}

2. 通过Webhook接收预付款通知时识别学生

配置PayPal Webhook接收PAYMENT.SALE.COMPLETED或BILLING.SUBSCRIPTION.CREATED等事件,在处理时从订阅资源中提取之前存入的学生ID。

Webhook处理控制器示例:

public function handleWebhook(Request $request)
{
    $provider = \PayPal::setProvider();
    $provider->setApiCredentials(config('paypal'));
    $provider->getAccessToken();
    
    // 必须验证Webhook签名,防止伪造请求
    $verification = $provider->verifyWebhookSignature($request->all());
    if ($verification['status'] !== 'SUCCESS') {
        abort(403, '无效的Webhook签名');
    }
    
    $eventType = $request->input('event_type');
    $resource = $request->input('resource');
    
    // 处理预付款完成事件
    if ($eventType === 'PAYMENT.SALE.COMPLETED') {
        $subscriptionId = $resource['billing_agreement_id'];
        $subscription = $provider->showSubscriptionDetails($subscriptionId);
        
        // 提取学生ID(根据存储方式选择)
        $studentId = $subscription['custom'];
        // $studentId = $subscription['metadata']['student_id'];
        
        // 更新学生支付状态
        DB::table('student_subscriptions')
            ->where('subscription_id', $subscriptionId)
            ->update([
                'status' => 'paid',
                'last_paid_at' => now()
            ]);
    }
    
    return response()->json(['status' => 'success']);
}

3. 主动取消学生的支付订阅

从数据库中获取学生对应的订阅ID,调用包的cancelSubscription方法完成取消,并同步更新本地状态。

主动取消的控制器方法:

public function cancelStudentSubscription($studentId)
{
    $subscription = DB::table('student_subscriptions')
        ->where('student_id', $studentId)
        ->where('status', '!=', 'cancelled')
        ->first();
    
    if (!$subscription) {
        return redirect()->back()->with('error', '无有效订阅可取消');
    }
    
    $provider = \PayPal::setProvider();
    $provider->setApiCredentials(config('paypal'));
    $provider->getAccessToken();
    
    // 调用PayPal API取消订阅
    $response = $provider->cancelSubscription($subscription->subscription_id);
    
    if ($response['status'] === 'CANCELLED') {
        DB::table('student_subscriptions')
            ->where('id', $subscription->id)
            ->update([
                'status' => 'cancelled',
                'cancelled_at' => now()
            ]);
        return redirect()->back()->with('message', '订阅已成功取消');
    }
    
    return redirect()->back()->with('error', '取消订阅失败');
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 17:18:21