lemonsqueezy/laravel

一个用于轻松将您的 Laravel 应用程序与 Lemon Squeezy 集成的包。

1.6.2 2024-07-23 16:07 UTC

README

Readme header

Lemon Squeezy for Laravel

Tests Coding Standards Latest Stable Version Total Downloads

一个用于轻松将您的 Laravel 应用程序与 Lemon Squeezy 集成的包。它简化了设置结账体验的过程。轻松设置产品的支付或让您的客户订阅您的产品计划。处理宽限期、暂停订阅或提供免费试用。

此包受到了由 Cashier 启发,该包是由 Taylor Otwell 创建的。

Lemon Squeezy for Laravel 由 Dries Vints 维护。我在业余时间维护这个包,因此任何赞助以 资助开发 都将非常感激 ❤️

我们还建议阅读 Lemon Squeezy 的 文档开发者指南

路线图

以下功能尚未包含在此包中,但计划在未来添加

要求

  • PHP 8.1 或更高版本
  • Laravel 10.0 或更高版本

安装

您需要执行一些步骤来安装此包

  1. 通过 Composer 需求包
  2. 创建 API 密钥
  3. 连接您的商店
  4. 配置可收费模型
  5. 运行迁移
  6. 连接到 Lemon JS
  7. 设置 webhook

以下将详细介绍这些步骤。

Composer

使用 Composer 安装包

composer require lemonsqueezy/laravel

API 密钥

接下来,配置您的 API 密钥。在 Lemon Squeezy 控制面板 中创建一个测试模式的全新密钥,并将其粘贴到下面的 .env 文件中,如下所示

LEMON_SQUEEZY_API_KEY=your-lemon-squeezy-api-key

当您将应用程序部署到生产环境时,您需要创建一个生产模式的全新密钥以处理实时数据。

商店标识符

您的商店标识符将在创建产品结账时使用。前往 您的 Lemon Squeezy 商店设置,并将商店 ID(# 符号后的部分)复制到下面的 env 值中

LEMON_SQUEEZY_STORE=your-lemon-squeezy-store-id

可收费模型

为了确保我们能够为我们的客户创建结账,我们需要配置一个模型作为我们的 "可收费" 模型。这通常是应用程序的 User 模型。为此,导入并使用模型上的 Billable 特性

use LemonSqueezy\Laravel\Billable;
 
class User extends Authenticatable
{
    use Billable;
}

现在,您的用户模型将能够访问我们包中的方法,以在 Lemon Squeezy 中为您的产品创建结账。请注意,您可以根据需要将任何模型类型设置为可收费的。不要求使用特定的模型类。

运行迁移

该软件包包含一些迁移,用于存储通过webhook从Lemon Squeezy接收到的数据。它将添加一个lemon_squeezy_customers表,用于存储有关客户的所有信息。此表可以连接到您希望使用的任何类型的计费模型。它还将添加一个lemon_squeezy_subscriptions表,用于存储有关订阅的信息。只需运行artisan migrate即可安装这些迁移。

php artisan migrate

如果您想自定义这些迁移,可以覆盖它们

Lemon JS

Lemon Squeezy使用自己的JavaScript库来初始化其结账小部件。我们可以通过在应用程序的head部分的</head>标签之前加载Blade指令来使用它。

<head>
    ...
 
    @lemonJS
</head>

Webhooks

最后,请确保设置入站webhook。这在开发和生产环境中都是必需的。

开发中的Webhooks

在开发应用程序时设置此功能的最佳方法是使用此软件包提供的php artisan lmsqueezy:listen命令。此命令将通过Lemon Squeezy API设置webhook,开始监听任何事件,并在退出命令时删除webhook。

php artisan lmsqueezy:listen

尽管此命令应该在自身之后始终清理webhook,但您可能希望使用--cleanup标志清理任何挂起的webhook。

php artisan lmsqueezy:listen --cleanup

目前,此命令支持NgrokExpose

警告

由于缺乏信号处理,当前不支持在Windows上使用lmsqueezy:listen命令。相反,您可以从下面的生产中的webhook文档中手动操作。您仍然需要使用像Ngrok或Expose这样的服务来公开可访问的URL。

生产中的Webhooks

对于生产,我们需要手动设置。该软件包已经包含了路由,所以您只需要转到您的Lemon Squeezy webhook设置,将URL指向您的应用程序域名。默认情况下,您应该将路径指向/lemon-squeezy/webhook。请确保选择所有事件类型。

注意

我们强烈建议在生产环境中验证webhook签名

Webhooks & CSRF保护

入站webhook不应受CSRF保护的影响。为了避免这种情况,请将您的webhook路径添加到App\Http\Middleware\VerifyCsrfToken中间件的except列表中。

protected $except = [
    'lemon-squeezy/*',
];

或者如果您正在使用Laravel v11及以上版本,应在您的应用程序的bootstrap/app.php文件中排除lemon-squeezy/*

->withMiddleware(function (Middleware $middleware) {
    $middleware->validateCsrfTokens(except: [
        'lemon-squeezy/*',
    ]);
})

升级

在升级到新版本时,请查阅我们的升级指南

配置

该软件包提供各种方式来配置您与Lemon Squeezy集成的体验。

默认情况下,我们不推荐发布配置文件,因为大多数内容都可以通过环境变量进行配置。如果您仍然想调整配置文件,可以使用以下命令发布它

php artisan vendor:publish --tag="lemon-squeezy-config"

验证Webhook签名

为了确保传入的webhook实际上来自Lemon Squeezy,我们可以为它们配置一个签名密钥。转到Lemon Squeezy仪表板的webhook设置,点击您的应用程序的webhook,并将签名密钥复制到下面的环境变量中

LEMON_SQUEEZY_SIGNING_SECRET=your-webhook-signing-secret

现在,任何传入的webhook在执行之前都会先进行验证。

覆盖迁移

Lemon Squeezy for Laravel 伴随一些迁移来存储发送的数据。如果您使用类似于字符串标识符的账单模型,如UUID,或想要调整迁移,可以覆盖它们。首先,使用以下命令发布它们

php artisan vendor:publish --tag="lemon-squeezy-migrations"

然后,在 AppServiceProviderregister 方法中忽略该包的迁移

use LemonSqueezy\Laravel\LemonSqueezy;

public function register(): void
{
    LemonSqueezy::ignoreMigrations();
}

现在您将依赖于自己的迁移而不是包的迁移。请注意,现在您还需要负责在升级包时手动保持这些迁移与包迁移同步。

命令

以下是可以运行以从 Lemon Squeezy 获取信息的命令列表

结账

使用此包,您可以轻松地为您的客户创建结账。

单次付款

例如,要为单次付款创建结账,使用您想要销售的产品变体的变体ID,并使用以下片段创建结账

use Illuminate\Http\Request;
 
Route::get('/buy', function (Request $request) {
    return $request->user()->checkout('variant-id');
});

这将自动将您的客户重定向到 Lemon Squeezy 结账页面,客户可以在那里购买您的产品。

注意

创建结账时,每次您重定向结账对象或调用结账对象的 url 方法时,都会对 Lemon Squeezy 进行 API 调用。这些调用成本高昂,可能会占用您应用的时间和资源。如果您反复创建相同的会话,您可能希望缓存这些 URL。

自定义定价费用

您还可以通过在客户上调用 charge 方法来覆盖产品变体的金额

use Illuminate\Http\Request;
 
Route::get('/buy', function (Request $request) {
    return $request->user()->charge(2500, 'variant-id');
});

金额应为正整数(以分为单位)。

您仍然需要提供变体ID,但可以按需要覆盖价格。您可以做的事情之一是创建一个具有特定货币的“通用”产品,您可以对它进行动态收费。

覆盖小部件

除了将客户重定向到结账屏幕外,您还可以创建一个结账按钮,它将在您的页面上渲染结账覆盖层。为此,将 $checkout 对象传递给视图

use Illuminate\Http\Request;
 
Route::get('/buy', function (Request $request) {
    $checkout = $request->user()->checkout('variant-id');

    return view('billing', ['checkout' => $checkout]);
});

现在,使用该包提供的 Laravel Blade 组件创建按钮

<x-lemon-button :href="$checkout" class="px-8 py-4">
    Buy Product
</x-lemon-button>

当用户点击此按钮时,它将触发 Lemon Squeezy 结账覆盖层。您还可以可选地请求以暗色模式渲染

<x-lemon-button :href="$checkout" class="px-8 py-4" dark>
    Buy Product
</x-lemon-button>

如果您正在结账订阅,并且不想显示“您将被收费...”文本,您可以通过在结账对象上调用 withoutSubscriptionPreview 方法来禁用此功能

$request->user()->subscribe('variant-id')
    ->withoutSubscriptionPreview();

如果您想为结账按钮设置不同的颜色,您可以通过 withButtonColor 传递十六进制颜色代码(带有前导 # 符号)

$request->user()->checkout('variant-id')
    ->withButtonColor('#FF2E1F');

预填用户数据

您可以通过覆盖您的账单模型上的以下方法轻松地为结账预填用户数据

public function lemonSqueezyName(): ?string; // name
public function lemonSqueezyEmail(): ?string; // email
public function lemonSqueezyCountry(): ?string; // country
public function lemonSqueezyZip(): ?string; // zip
public function lemonSqueezyTaxNumber(): ?string; // tax_number

默认情况下,将使用方法右侧注释中显示的属性。

此外,您还可以通过以下方法动态传递此数据

use Illuminate\Http\Request;
 
Route::get('/buy', function (Request $request) {
    return $request->user()->checkout('variant-id')
        ->withName('John Doe')
        ->withEmail('john@example.com')
        ->withBillingAddress('US', '10038') // Country & Zip Code
        ->withTaxNumber('123456679')
        ->withDiscountCode('PROMO');
});

产品详情

您可以使用 withProductNamewithDescription 方法覆盖产品结账的附加数据

$request->user()->checkout('variant-id')
    ->withProductName('Ebook')
    ->withDescription('A thrilling novel!');

收据感谢

此外,您还可以自定义订单收据电子邮件的感谢信息。

$request->user()->checkout('variant-id')
    ->withThankYouNote('Thanks for your purchase!');

购买后重定向

要使客户在购买后返回您的应用,您可以使用 redirectTo 方法

$request->user()->checkout('variant-id')
    ->redirectTo(url('/'));

您也可以通过在配置文件中配置 lemon-squeezy.redirect_url 来设置此默认 URL

'redirect_url' => 'https://my-app.com/dashboard',

为此,您需要 发布您的配置文件

过期结账

您可以通过在结账上调用 expiresAt 方法来指示结账会话应该保持多长时间活跃

$request->user()->checkout('variant-id')
    ->expiresAt(now()->addDays(3));

自定义数据

您还可以通过结账过程传递自定义数据。[传递自定义数据的详细说明]。为此,请使用结账方法发送键/值对

use Illuminate\Http\Request;
 
Route::get('/buy', function (Request $request) {
    return $request->user()->checkout('variant-id', custom: ['foo' => 'bar']);
});

这些数据稍后将在相关的webhook中可供您使用。

保留关键字

在处理自定义数据时,此库有一些保留关键字

  • billable_id
  • billable_type
  • subscription_type

尝试使用这些关键字中的任何一个都将引发异常。

客户

客户门户

客户可以通过访问他们的客户门户轻松管理其个人信息,如姓名、电子邮件地址等。Lemon Squeezy for Laravel通过在可计费对象上调用redirectToCustomerPortal使其轻松地将客户重定向到该门户。

use Illuminate\Http\Request;
 
Route::get('/customer-portal', function (Request $request) {
    return $request->user()->redirectToCustomerPortal();
});

要调用此方法,您的可计费对象已需要拥有订阅或通过Lemon Squeezy进行购买。此外,此方法将执行底层API调用,因此请确保将此重定向放在您可以在应用程序中链接到的路由后面。

可选地,您还可以直接获得签名后的客户门户URL

$url = $user->customerPortalUrl();

我的订单

除了用于管理订阅的客户门户外,Lemon Squeezy还有一个“我的订单”门户,用于管理客户账户的所有购买。这涉及到多个供应商的购买组合。如果您希望客户能够找到此信息,您可以链接到https://app.lemonsqueezy.com/my-orders并告诉他们使用他们进行购买时使用的电子邮件地址登录。

订单

Lemon Squeezy允许您检索您商店制作的订单列表。然后,您可以使用此列表向客户展示所有订单。

检索订单

要检索特定客户的订单列表,只需调用数据库中保存的模型即可

<table>
    @foreach ($user->orders as $order)
        <td>{{ $order->ordered_at->toFormattedDateString() }}</td>
        <td>{{ $order->order_number }}</td>
        <td>{{ $order->subtotal() }}</td>
        <td>{{ $order->discount() }}</td>
        <td>{{ $order->tax() }}</td>
        <td>{{ $order->total() }}</td>
        <td>{{ $order->receipt_url }}</td>
    @endforeach
</table>

检查订单状态

要检查单个订单是否已付款,您可以使用paid方法

if ($order->paid()) {
    // ...
}

除此之外,您还可以进行三项其他检查:pendingfailedrefunded。如果订单是refunded,您还可以使用refunded_at时间戳

@if ($order->refunded())
    Order {{ $order->order_number }} was refunded on {{ $order->refunded_at->toFormattedDateString() }}
@endif

您还可以检查订单是否为特定产品

if ($order->hasProduct('your-product-id')) {
    // ...
}

或特定变体

if ($order->hasVariant('your-variant-id')) {
    // ...
}

此外,您还可以检查客户是否购买了特定产品

if ($user->hasPurchasedProduct('your-product-id')) {
    // ...
}

或特定变体

if ($user->hasPurchasedVariant('your-variant-id')) {
    // ...
}

这两个检查都将确保正确的产品或变体已被购买并付款。如果您在应用程序中提供类似终身访问等特性,这也很有用。

订阅

设置订阅产品

设置具有不同计划和间隔的订阅产品需要以特定的方式进行。Lemon Squeezy提供了一份[设置订阅计划的指南]。

虽然您可以选择如何设置产品和计划,但选择第二种方法为每个计划类型创建一个产品会更简单。例如,当您有一个“基本”和“专业”计划,并且两者都有月度和年度价格时,创建两个单独的产品并分别为它们的月度和年度价格添加两个变体会更明智。

这使您可以在稍后利用订阅上的hasProduct方法,这允许您只需检查订阅是否在特定计划类型上,而无需担心它是按月还是按年安排。

创建订阅

开始订阅很容易。为此,我们需要产品的变体ID。复制变体ID,然后从可计费模型中启动新的订阅结账

use Illuminate\Http\Request;
 
Route::get('/subscribe', function (Request $request) {
    return $request->user()->subscribe('variant-id');
});

当客户完成结账后,传入的SubscriptionCreated webhook将将其与数据库中的可计费模型相关联。然后,您可以从可计费模型中检索订阅。

$subscription = $user->subscription();

检查订阅状态

一旦客户订阅了您的服务,您可以使用各种方法来检查订阅的各种状态。最基本的一个例子,是检查客户是否订阅了有效的订阅

if ($user->subscribed()) {
    // ...
}

您可以在应用程序的各个地方使用此功能,如中间件、策略等,以提供您的服务。要检查单个订阅是否有效,您可以使用 valid 方法

if ($user->subscription()->valid()) {
    // ...
}

此方法以及 subscribed 方法,如果您的订阅处于活动状态、试用状态、过期、免费暂停或处于取消的宽限期,将返回 true。

您还可以检查订阅是否属于特定产品

if ($user->subscription()->hasProduct('your-product-id')) {
    // ...
}

或特定变体

if ($user->subscription()->hasVariant('your-variant-id')) {
    // ...
}

如果您想检查订阅是否属于特定变体,同时保持其有效性,可以使用

if ($user->subscribedToVariant('your-variant-id')) {
    // ...
}

或者如果您使用 多种订阅类型,您可以在额外参数中传递一个类型

if ($user->subscribed('swimming')) {
    // ...
}

if ($user->subscribedToVariant('your-variant-id', 'swimming')) {
    // ...
}

已取消状态

要检查用户是否已取消其订阅,您可以使用 cancelled 方法

if ($user->subscription()->cancelled()) {
    // ...
}

当他们在宽限期时,您可以使用 onGracePeriod 检查

if ($user->subscription()->onGracePeriod()) {
    // ...
}

如果订阅已被完全取消且不再处于宽限期,您可以使用 expired 检查

if ($user->subscription()->expired()) {
    // ...
}

过期状态

如果订阅的定期付款失败,订阅将进入过期状态。这意味着它仍然是一个有效的订阅,但您的客户将在两周内有一个支付重试期。

if ($user->subscription()->pastDue()) {
    // ...
}

在此状态下,您应指导您的客户 更新他们的付款信息。在 Lemon Squeezy 中,失败的付款将尝试几次。有关更多信息以及催款流程,请参阅 Lemon Squeezy 文档

订阅作用域

各种订阅作用域可用于查询特定状态的订阅

// Get all active subscriptions...
$subscriptions = Subscription::query()->active()->get();
 
// Get all of the cancelled subscriptions for a specific user...
$subscriptions = $user->subscriptions()->cancelled()->get();

以下是所有可用的作用域

Subscription::query()->onTrial();
Subscription::query()->active();
Subscription::query()->paused();
Subscription::query()->pastDue();
Subscription::query()->unpaid();
Subscription::query()->cancelled();
Subscription::query()->expired();

更新付款信息

要允许您的客户 更新他们的付款详情,如他们的信用卡信息,您可以使用以下方法将他们重定向

use Illuminate\Http\Request;
 
Route::get('/update-payment-info', function (Request $request) {
    $subscription = $request->user()->subscription();

    return view('billing', [
        'paymentMethodUrl' => $subscription->updatePaymentMethodUrl(),
    ]);
});

或者,如果您想以更无缝的方式在您的应用程序上打开 URL(类似于结账覆盖层),您可以使用 Lemon.js 使用 LemonSqueezy.Url.Open() 方法打开 URL。首先,将 URL 传递给视图

use Illuminate\Http\Request;
 
Route::get('/update-payment-info', function (Request $request) {
    $subscription = $request->user()->subscription();

    return view('billing', [
        'paymentMethodUrl' => $subscription->updatePaymentMethodUrl(),
    ]);
});

然后通过按钮触发它

<script defer>
    function updatePM() {
        LemonSqueezy.Url.Open('{!! $paymentMethodUrl !!}');
    }
</script>

<button onclick="updatePM()">
    Update payment method
</button>

这需要您已设置 Lemon.js

更改计划

当客户订阅了月度计划时,他们可能希望升级到更好的计划、将付款更改为年计划或降级到更便宜的计划。在这些情况下,您可以通过传递不同的变体 ID 和其产品 ID 到 swap 方法允许他们交换计划

use App\Models\User;

$user = User::find(1);

$user->subscription()->swap('product-id', 'variant-id');

这将使客户切换到新的订阅计划,但账单将在下一个账单周期进行。如果您想立即向客户开票,您可以使用 swapAndInvoice 方法代替

$user = User::find(1);

$user->subscription()->swapAndInvoice('product-id', 'variant-id');

注意

您会在上述方法中注意到,您需要提供产品 ID 和变体 ID,并可能想知道为什么。您不能从变体 ID 中推导出产品 ID 吗?不幸的是,这只有在交换相同产品的变体时才可行。当切换到完全不同的产品时,您需要在 Lemon Squeezy API 中也提供产品 ID。因此,我们决定使此操作一致,并且始终要求提供产品 ID。

预付

默认情况下,Lemon Squeezy 将在更改计划时按比例分配金额。如果您想防止这种情况,您可以在执行交换之前使用 noProrate 方法

$user = User::find(1);

$user->subscription()->noProrate()->swap('product-id', 'variant-id');

更改账单日期

要更改客户订阅账单的月份,您可以使用anchorBillingCycleOn方法

$user = User::find(1);

$user->subscription()->anchorBillingCycleOn(21);

在上面的例子中,客户现在将每月21日账单。更多信息,请参阅Lemon Squeezy文档

多个订阅

在某些情况下,您可能希望允许客户订阅多个订阅类型。例如,健身房可能提供游泳和举重订阅。您可以允许客户订阅其中一种或两种。

要处理不同的订阅,您可以在启动新的订阅时将type作为subscribe方法的第二个参数提供

$user = User::find(1);

$checkout = $user->subscribe('variant-id', 'swimming');

现在,您可以通过在检索时提供type参数来始终引用此特定的订阅类型

$user = User::find(1);

// Retrieve the swimming subscription type...
$subscription = $user->subscription('swimming');

// Swap plans for the gym subscription type...
$user->subscription('gym')->swap('product-id', 'variant-id');

// Cancel the swimming subscription...
$user->subscription('swimming')->cancel();

暂停订阅

暂停订阅,请在订阅上调用pause方法

$user = User::find(1);

$user->subscription()->pause();

可选地,提供订阅可以恢复的日期

$user = User::find(1);

$user->subscription()->pause(
    now()->addDays(5)
);

这将填充客户上的resumes_at时间戳。要了解您的订阅是否处于暂停期间,您可以使用onPausedPeriod方法

if ($user->subscription()->onPausedPeriod()) {
    // ...
}

要恢复,只需在订阅上调用该方法

$user->subscription()->unpause();

暂停状态

默认情况下,暂停订阅将在暂停期间剩余时间内取消其使用。如果您希望客户免费使用您的服务,则可以使用pauseForFree方法

$user->subscription()->pauseForFree();

取消订阅

取消订阅,请在订阅上调用cancel方法

$user = User::find(1);

$user->subscription()->cancel();

这将使您的订阅设置为取消。如果您的订阅在周期中途取消,它将进入宽限期,并设置ends_at列。客户仍然可以访问该期间提供的所有服务。您可以通过调用onGracePeriod方法来检查其宽限期

if ($user->subscription()->onGracePeriod()) {
    // ...
}

Lemon Squeezy无法立即取消订阅。要在宽限期仍在进行时恢复订阅,请调用resume方法

$user->subscription()->resume();

当取消的订阅达到宽限期结束时,它将过渡到过期状态,并且无法再恢复。

订阅试用期

有关Lemon Squeezy试用期的详细说明,请查看他们的指南

无需付款

要允许人们在不填写付款详情的情况下注册您的产品,您可以在创建客户时设置trial_ends_at

use App\Models\User;
 
$user = User::create([
    // ...
]);
 
$user->createAsCustomer([
    'trial_ends_at' => now()->addDays(10)
]);

这被称为“通用试用期”,因为它没有附加到任何订阅。您可以使用onTrial方法来检查客户是否正在试用您的应用程序

if ($user->onTrial()) {
    // User is within their trial period...
}

或者,如果您还希望确保它是通用试用期,您可以使用onGenericTrial方法

if ($user->onGenericTrial()) {
    // User is within their "generic" trial period...
}

您还可以通过调用trialEndsAt方法来检索试用期的结束日期

if ($user->onTrial()) {
    $trialEndsAt = $user->trialEndsAt();
}

一旦您的客户准备好,或者他们的试用期已过期,他们就可以开始他们的订阅

use Illuminate\Http\Request;

Route::get('/buy', function (Request $request) {
    return $request->user()->subscribe('variant-id');
});

请注意,当客户在通用试用期开始订阅时,他们的试用期将被取消,因为他们已经开始支付您的产品。

需要付款

另一种选择是在人们试用您的产品时要求提供支付详情。这意味着在试用期结束后,他们将立即订阅您的产品。要开始设置,您需要在产品设置中配置一个试用期。然后,让客户开始订阅

use Illuminate\Http\Request;

Route::get('/buy', function (Request $request) {
    return $request->user()->subscribe('variant-id');
});

您的客户订阅后,他们将进入您配置的试用期,在此日期之前不会收费。如果他们想取消订阅,您需要给他们这个选项。

要检查您的客户是否目前正在进行免费试用,您可以使用账单或单个订阅上的onTrial方法

if ($user->onTrial()) {
    // ...
}
 
if ($user->subscription()->onTrial()) {
    // ...
}

要确定试用是否已过期,您可以使用hasExpiredTrial方法

if ($user->hasExpiredTrial()) {
    // ...
}
 
if ($user->subscription()->hasExpiredTrial()) {
    // ...
}
提前结束试用

要提前结束带预付费的试用,您可以在订阅上使用endTrial方法

$user = User::find(1);

$user->subscription()->endTrial();

此方法将计费锚点移动到当前日期,从而结束客户拥有的任何试用期。

处理Webhooks

Lemon Squeezy可以发送您的应用Webhooks,您可以对其进行响应。默认情况下,此包已经为您做了大部分工作。如果您已正确设置Webhooks,它将监听任何传入的事件并相应地更新数据库。我们建议启用所有事件类型,这样在将来升级时会更方便。

要监听传入的Webhooks,我们有两个将在其中触发的事件

  • LemonSqueezy\Laravel\Events\WebhookReceived
  • LemonSqueezy\Laravel\Events\WebhookHandled

WebhookReceived将在Webhook到达时触发,但尚未被包的WebhookController处理。当Webhook被包处理时,将触发WebhookHandled事件。这两个事件都将包含传入Webhook的完整负载。

如果您想对这些事件做出响应,您必须为它们创建监听器。例如,您可能希望对订阅更新做出响应

<?php
 
namespace App\Listeners;
 
use LemonSqueezy\Laravel\Events\WebhookHandled;
 
class LemonSqueezyEventListener
{
    /**
     * Handle received Lemon Squeezy webhooks.
     */
    public function handle(WebhookHandled $event): void
    {
        if ($event->payload['meta']['event_name'] === 'subscription_updated') {
            // Handle the incoming event...
        }
    }
}

有关示例负载,请参阅Lemon Squeezy API文档

Laravel v11及更高版本将自动检测监听器。如果您使用的是Laravel v10或更低版本,应在应用程序的EventServiceProvider中设置它

<?php
 
namespace App\Providers;
 
use App\Listeners\LemonSqueezyEventListener;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use LemonSqueezy\Laravel\Events\WebhookHandled;
 
class EventServiceProvider extends ServiceProvider
{
    protected $listen = [
        WebhookHandled::class => [
            LemonSqueezyEventListener::class,
        ],
    ];
}

Webhook事件

除了监听WebhookHandled事件之外,您还可以订阅以下专用包事件之一,这些事件在处理Webhook后触发

  • LemonSqueezy\Laravel\Events\OrderCreated
  • LemonSqueezy\Laravel\Events\OrderRefunded
  • LemonSqueezy\Laravel\Events\SubscriptionCreated
  • LemonSqueezy\Laravel\Events\SubscriptionUpdated
  • LemonSqueezy\Laravel\Events\SubscriptionCancelled
  • LemonSqueezy\Laravel\Events\SubscriptionResumed
  • LemonSqueezy\Laravel\Events\SubscriptionExpired
  • LemonSqueezy\Laravel\Events\SubscriptionPaused
  • LemonSqueezy\Laravel\Events\SubscriptionUnpaused
  • LemonSqueezy\Laravel\Events\SubscriptionPaymentSuccess
  • LemonSqueezy\Laravel\Events\SubscriptionPaymentFailed
  • LemonSqueezy\Laravel\Events\SubscriptionPaymentRecovered
  • LemonSqueezy\Laravel\Events\LicenseKeyCreated
  • LemonSqueezy\Laravel\Events\LicenseKeyUpdated

所有这些事件都包含一个可计费的$model实例和事件$payload。订阅事件还包含$subscription对象。这些可以通过它们的公共属性访问。

变更日志

请查看此存储库中的所有最近更改的变更日志

许可证

Laravel的Lemon Squeezy是开源软件,根据MIT许可证许可。