Laravel Cashier(Paddle)未存储交易与订阅问题修复咨询
适配 Laravel 12 + Inertia + React + Cashier(Paddle) 的订阅实现方案
你的核心问题是结账流程未正确关联 Laravel 用户与 Paddle 交易,导致 Webhook 无法同步订阅数据到数据库。以下是针对性的修复步骤:
1. 重构服务器端结账会话生成
替换手动调用 createAsCustomer() 的方式,使用 Cashier 内置的 checkout() 方法生成绑定用户的结账会话,确保 Paddle 能识别交易归属的 Laravel 用户。
修改 SubscriptionController.php:
class SubscriptionController extends Controller { public function store(Request $request) { try { $user = $request->user(); $priceId = config('subscription.paddle_price_id'); // 自动创建Paddle客户(如果不存在)并生成关联用户的结账会话 $checkout = $user->checkout([ $priceId => 1, ], [ 'redirect_url' => route('dashboard'), 'customer' => [ 'name' => $user->name, 'email' => $user->email, ], ]); // 返回会话ID给前端,而非直接返回价格ID return response()->json([ 'sessionId' => $checkout->id, 'redirectUrl' => route('dashboard'), ]); } catch (\Exception $e) { Log::error('CHECKOUT - Subscription error: ' . $e->getMessage()); Log::error($e->getTraceAsString()); return response()->json(['error' => $e->getMessage()], 500); } } }
2. 更新前端结账逻辑
使用服务器返回的会话 ID 打开 Paddle 结账弹窗,确保交易与用户绑定。
修改 useHandleCheckoutOpen.tsx:
import axios from 'axios'; import { type User } from '@/types'; export function useHandleCheckoutOpen(user: User) { return async () => { try { const response = await axios.post('/subscribe'); if (response.data.error) { console.error('Server returned an error:', response.data.error); return; } const { sessionId } = response.data; if (window.Paddle && window.Paddle.Checkout) { window.Paddle.Checkout.open({ sessionId, // 使用绑定用户的会话ID settings: { displayMode: 'overlay', allowLogout: false, }, }); } else { console.error('Paddle script not loaded or window.Paddle not defined.'); } } catch (error: any) { console.error('Error starting subscription:', error); if (error.response) { console.error('Server response:', error.response.data); } } }; }
3. 确保 Webhook 正确同步订阅数据
验证 Webhook 控制器是否继承 Cashier 的内置处理逻辑,自动同步 Paddle 交易到 Laravel 数据库。
修改 WebhookController.php:
use Laravel\Cashier\WebhookController as CashierWebhookController; class WebhookController extends CashierWebhookController { // 可自定义扩展事件处理逻辑,比如发送订阅通知 protected function handleSubscriptionCreated($payload) { // 调用父类方法自动创建订阅记录 parent::handleSubscriptionCreated($payload); // 自定义逻辑示例:$user = User::where('paddle_id', $payload['data']['customer_id'])->first(); } }
配套配置检查
- 在
.env中配置正确的 Paddle Webhook 密钥:PADDLE_WEBHOOK_SECRET=你的Paddle后台Webhook密钥 - 在 Paddle 后台的 Webhook 设置中,将 URL 指向
https://你的域名/paddle/webhook,并勾选以下事件:subscription.createdsubscription.updatedpayment.succeeded
4. 验证订阅状态
完成上述修改后,即可使用 Cashier 内置方法检查用户订阅:
// 检查用户是否有活跃订阅 if ($request->user()->subscribed()) { // 订阅生效逻辑 } // 获取用户订阅详情 $subscription = $request->user()->subscription();
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

