如何在Laravel的Stripe Session中添加产品ID和名称实现支付成功后删除对应产品
实现方案
1. 创建Stripe Checkout Session时注入本地产品ID
Stripe的所有核心对象都支持metadata字段存储自定义的键值对数据,你可以在创建Session时直接把本地产品ID存入该字段,修改你的blade.php中的Session创建代码如下:
<?php require_once(__DIR__.'/../../../vendor/autoload.php'); \Stripe\Stripe::setApiKey('sk_test_51xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'); $session = \Stripe\Checkout\Session::create([ 'payment_method_types' => ['card'], // 新增metadata字段,存入自定义数据 'metadata' => [ 'local_product_id' => $product->id, // 可选:存入你需要的其他业务数据,例如下单用户ID 'local_user_id' => auth()->id() ], 'line_items' => [[ 'price_data' => [ 'currency' => 'usd', 'product_data' => [ 'name' => $product->name ?? 'T-shirt', // 替换为实际产品名称 ], 'unit_amount' => 2000, // 替换为实际产品价格,单位为美分 ], 'quantity' => 1, ]], 'mode' => 'payment', 'success_url' => 'https://example.com/success', 'cancel_url' => 'https://example.com/cancel', ]); ?>
2. 调整Webhook逻辑,获取本地产品ID执行删除操作
你原代码监听的charge.succeeded事件返回的是Charge对象,无法直接获取Session的metadata,更推荐监听checkout.session.completed事件,该事件会在用户完成支付后触发,返回的对象中直接包含你存入的metadata。修改后的路由代码如下:
use Stripe\Webhook; use Stripe\Exception\SignatureVerificationException; Route::post('webhook/payment/succeeded', function (Request $request){ // 替换为你在Stripe后台获取的Webhook签名密钥 $webhookSecret = 'whsec_xxxxxxxxxxxxxxxxxxxxxxxx'; $sigHeader = $request->header('Stripe-Signature'); // 签名验证,防止伪造请求,生产环境必须开启 try { $event = Webhook::constructEvent( $request->getContent(), $sigHeader, $webhookSecret ); } catch (SignatureVerificationException $e) { return response()->json(['error' => 'Invalid signature'], 400); } // 监听Checkout Session完成事件 if($event->type === "checkout.session.completed"){ $session = $event->data['object']; // 取出存入的本地产品ID $localProductId = $session['metadata']['local_product_id'] ?? null; try{ // 产品存在则执行删除操作 if ($localProductId) { \App\Models\Product::find($localProductId)?->delete(); } // 保留原有支付记录创建逻辑,可补充存储产品ID Payment::create([ 'stripe_id' => $session['payment_intent'], 'product_id' => $localProductId, 'amount' => $session['amount_total'], 'email' => $session['customer_details']['email'], 'name' => $session['customer_details']['name'], ]); } catch (\Exception $e) { return $e->getMessage(); } return response('ok', 200); } return response('ok', 200); });
注意事项
- 请先到Stripe后台的Webhook配置页面,给你的Webhook地址开启
checkout.session.completed事件的监听权限,否则无法接收到该事件。 - metadata单字段最多支持500字符,完全满足ID类数据的存储需求。
内容的提问来源于stack exchange,提问作者Swimo Omix
相关产品推荐
相关产品推荐

