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

在React Next.js中结合LemonSqueezy动态处理订阅成败状态

实现订阅状态跟踪与支付类型识别

一、前端即时反馈:利用LemonSqueezy SDK回调

LemonSqueezy的Url.Open方法支持传入回调参数,可直接在前端监听结账的成功/失败状态,同时获取基础的支付类型信息:

export default function Home() {
  
  async function buyingNow(){
    try {
      await LemonSqueezy.Url.Open(process.env.NEXT_PUBLIC_LEMONSQUEEZY_SUBSCRIPTION_URL, {
        onSuccess: (data) => {
          console.log("支付成功", data);
          // 判断是否为 recurring 支付:从返回数据中读取订阅标识
          const isRecurring = data.meta?.is_subscription ?? false;
          console.log("是否为 recurring 支付:", isRecurring);
          // 这里可执行前端层面的体验优化逻辑,比如跳转用户中心
        },
        onError: (error) => {
          console.log("支付失败/取消", error);
          // 前端提示用户重试或查看错误原因
        }
      });
    } catch (err) {
      console.log("结账流程异常", err);
    }
  }

  return (
    <div className="">
      <button onClick={buyingNow}>Subscribe Now</button>
    </div>
  )
}

注意:前端回调仅作即时反馈,核心业务逻辑(如用户权限激活)不能依赖它,因为前端状态可被篡改,必须配合后端校验。

二、后端可靠校验:配置LemonSqueezy Webhooks

要安全准确地跟踪订阅状态和支付类型,必须通过LemonSqueezy Webhooks实现——它会在支付完成、订阅创建、支付失败等事件发生时,主动向你的后端发送请求。

步骤1:LemonSqueezy后台配置Webhook

  1. 登录LemonSqueezy后台,进入商店设置 → Webhooks
  2. 添加新Webhook,填写你的后端接收地址(如https://your-domain.com/api/lemonsqueezy-webhook)
  3. 勾选需要监听的事件:
    • order_created(订单创建,对应支付成功)
    • order_failed(订单失败)
    • subscription_created(订阅创建,针对recurring支付)

步骤2:Next.js后端编写Webhook处理接口

在pages/api/lemonsqueezy-webhook.js(App Router对应app/api/lemonsqueezy-webhook/route.js)中编写逻辑:

import crypto from 'crypto';

const SIGNING_SECRET = process.env.LEMONSQUEEZY_WEBHOOK_SECRET;

export default async function handler(req, res) {
  if (req.method !== 'POST') {
    return res.status(405).send('Method Not Allowed');
  }

  // 验证Webhook签名,确保请求来自LemonSqueezy
  const signature = req.headers['x-signature'];
  const hmac = crypto.createHmac('sha256', SIGNING_SECRET);
  const digest = Buffer.from(hmac.update(JSON.stringify(req.body)).digest('hex'), 'utf8');
  const signatureBuffer = Buffer.from(signature, 'utf8');

  if (!crypto.timingSafeEqual(digest, signatureBuffer)) {
    return res.status(403).send('Invalid signature');
  }

  const event = req.body;

  // 根据事件类型处理业务逻辑
  switch(event.meta.event_name) {
    case 'order_created':
      console.log('支付成功,订单详情:', event.data);
      // 判断是否为 recurring 支付:检查订单是否关联订阅
      const isRecurring = !!event.data.relationships.subscription.data;
      console.log('是否为 recurring 支付:', isRecurring);
      // 执行核心SaaS逻辑:更新用户订阅状态、发送激活邮件等
      break;
    case 'order_failed':
      console.log('支付失败,订单详情:', event.data);
      // 处理失败逻辑:通知用户、记录失败原因等
      break;
    case 'subscription_created':
      console.log('订阅已创建,详情:', event.data);
      // 可进一步处理订阅周期、到期时间等信息
      break;
    default:
      console.log('未处理的事件类型:', event.meta.event_name);
  }

  res.status(200).send('OK');
}

步骤3:配置环境变量

在.env.local中添加Webhook签名密钥:

LEMONSQUEEZY_WEBHOOK_SECRET=你的LemonSqueezy Webhook签名密钥

三、测试模式验证方法

在LemonSqueezy测试模式下,使用测试信用卡(如4242 4242 4242 4242,任意过期日期和CVV)模拟支付:

  • 支付成功时,会同时触发前端onSuccess回调和后端order_created/subscription_created事件
  • 支付失败(如输入错误CVV)时,会触发前端onError和后端order_failed事件
  • 测试recurring支付时,order_created事件中会包含subscription关联数据,isRecurring返回true

关键注意事项

  • 前端回调仅用于用户体验优化,核心业务逻辑必须依赖后端Webhook,避免前端篡改风险
  • 必须验证Webhook签名,防止恶意请求
  • 测试模式与生产模式的Webhook配置相互独立,需在对应环境中设置正确的密钥和事件

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 07:40:19