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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 00:45:04