morenorafael/subscription

Laravel 的 SaaS 风格的持续订阅计划。

1.0.2 2024-04-01 04:23 UTC

This package is auto-updated.

Last update: 2024-10-01 00:23:07 UTC


README

安装

composer require morenorafael/subscription

服务提供者

'providers' => [
    /**
    * Third Party Service Providers...
    */
    Morenorafael\Subscription\SubscriptionServiceProvider::class,
...

配置文件和迁移

使用以下命令发布包配置文件和迁移

php artisan vendor:publish --provider="Morenorafael\Subscription\SubscriptionServiceProvider"
php artisan migrate

特质和合约

Morenorafael\Subscription\Traits\PlanSubscriber 特质和 Morenorafael\Subscription\Contracts\PlanSubscriberInterface 合约添加到您的 User 模型中。

查看以下示例

namespace  App\Models;

use Illuminate\Foundation\Auth\User  as  Authenticatable;
use Morenorafael\Subscription\Contracts\PlanSubscriberInterface;
use Morenorafael\Subscription\Traits\PlanSubscriber;

class  User  extends  Authenticatable  implements  PlanSubscriberInterface
{
	use PlanSubscriber;

	...

用法

创建计划

use Morenorafael\Subscription\Models\Plan;
use Morenorafael\Subscription\Models\PlanFeature;

$plan = Plan::create([
	'name' => 'Pro',
	'description' => 'Pro plan',
	'price' => 9.99,
	'interval' => 'month',
	'interval_count' => 1,
	'trial_period_days' => 15,
	'sort_order' => 1,
]);

$plan->features()->saveMany([
	new PlanFeature(['code' => 'listings', 'value' => 50, 'sort_order' => 1]),
	new PlanFeature(['code' => 'pictures_per_listing', 'value' => 10, 'sort_order' => 5]),
	new PlanFeature(['code' => 'listing_duration_days', 'value' => 30, 'sort_order' => 10]),
	new PlanFeature(['code' => 'listing_title_bold', 'value' => 'Y', 'sort_order' => 15])
]);

...

访问计划功能

在某些情况下,您需要访问特定计划中的特定功能,您可以通过使用在 Plan 模型中可用的 getFeatureByCode 方法来实现这一点。

示例

$feature = $plan->getFeatureByCode('pictures_per_listing');
$feature->value  // Get the feature's value

创建订阅

首先,检索您的订阅者模型实例,这通常是您的用户模型和用户订阅的计划实例。检索模型实例后,您可以使用 newSubscription 方法(在 PlanSubscriber 特质中可用)来创建模型的订阅。

use Auth;
use Morenorafael\Subscription\Models\Plan;

$user = Auth::user();
$plan = Plan::find(1);

$user->newSubscription('main', $plan)->create();

newSubscription 方法传递的第一个参数是订阅的名称。如果您的应用程序提供单个订阅,您可能会将其称为 mainprimary。订阅的名称不是计划的名称,而是一个唯一的订阅标识符。第二个参数是用户订阅的计划实例。

订阅解析

当您在可订阅模型中使用 subscription() 方法(例如,$user->subscription('main'))来检索订阅时,您将收到可订阅的最新订阅和订阅名称。例如,如果您将 Jane Doe 订阅到免费计划,然后订阅到专业计划,Laraplans 将返回包含专业计划的订阅,因为它是可用的最新订阅。如果您有其他要求,您可以使用自己的订阅解析器,通过将 Morenorafael\Subscription\Contracts\SubscriptionResolverInterface 的实现绑定到 服务容器 来实现,如下所示

/**
 * Register the application services.
 *
 * @return void
 */
public function register()
{
    $this->app->bind(SubscriptionResolverInterface::class, CustomSubscriptionResolver::class);
}

订阅能力

有多种方法可以确定用户订阅中特定功能的用法和能力,最常见的方法是 canUse

canUse 方法根据多个因素返回 truefalse

  • 功能 已启用
  • 功能的值不是 0
  • 或者功能有剩余的使用次数
$user->subscription('main')->ability()->canUse('listings');

还有其他方法可以确定订阅的能力

  • enabled:当功能的值在配置文件中列出为 正词 时返回 true
  • consumed:返回用户使用特定功能的次数。
  • remainings:返回特定功能的可用使用次数。
  • value:返回功能值。

所有方法都具有相同的签名:$user->subscription('main')->ability()->consumed('listings');

记录功能使用

为了有效地使用能力方法,您需要跟踪基于使用的功能的每次使用。您可以通过用户 subscriptionUsage() 方法使用 record 方法。

record 方法接受 3 个参数:第一个是功能的代码,第二个是添加的使用次数(默认为 1),第三个参数指示是否应递增使用次数(true:默认行为)或覆盖(false)。

查看以下示例

// Increment by 2
$user->subscriptionUsage('main')->record('listings', 2);

// Override with 9
$user->subscriptionUsage('main')->record('listings', 9, false);

减少功能使用

减少功能使用与增加功能使用几乎相同。在这种情况下,我们只需从实际使用中减去一个给定的数量(默认为 1)。

// Reduce by 1
$user->subscriptionUsage('main')->reduce('listings');

// Reduce by 2
$user->subscriptionUsage('main')->reduce('listings', 2);

清除订阅使用数据

在某些情况下,您可能需要清除特定用户订阅中的所有使用情况,您可以通过使用 clear 方法来完成此操作。

$user->subscriptionUsage('main')->clear();

检查订阅状态

要使订阅被视为 活动状态,订阅必须有一个活动试用或订阅的 ends_at 在未来。

$user->subscribed('main');
$user->subscribed('main', $planId); // Check if subscription is active AND using a particular plan

或者,您可以使用以下在订阅模型中可用的方法

$user->subscription('main')->isActive();
$user->subscription('main')->isCanceled();
$user->subscription('main')->isCanceledImmediately();
$user->subscription('main')->isEnded();
$user->subscription('main')->onTrial();

注意:具有活动试用或 ends_at 在未来的已取消订阅被视为活动状态。

续订订阅

要续订订阅,您可以使用订阅模型中可用的 renew 方法。这将根据所选计划设置一个新的 ends_at 日期,并将清除订阅的使用数据。

$user->subscription('main')->renew();

注意:已结束周期的已取消订阅不能续订。

Morenorafael\Subscription\Events\SubscriptionRenewed 事件在使用 renew 方法续订订阅时触发。

取消订阅

要取消订阅,只需在用户的订阅上使用 cancel 方法。

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

默认情况下,订阅将在周期结束前保持活动状态。传递 true 可立即取消订阅。

$user->subscription('main')->cancel(true);

事件

以下是由包触发的事件

  • Morenorafael\Subscription\Events\SubscriptionCreated:在创建订阅时触发。
  • Morenorafael\Subscription\Events\SubscriptionRenewed:在通过 renew() 方法续订订阅时触发。
  • Morenorafael\Subscription\Events\SubscriptionCanceled:在通过 cancel() 方法取消订阅时触发。
  • Morenorafael\Subscription\Events\SubscriptionPlanChanged:在更改订阅的计划时触发;将在 PlanSubscription 模型保存后触发。计划更改是通过比较 plan_id 的原始值和当前值来确定的。

Eloquent 范围

use Morenorafael\Subscription\Models\PlanSubscription;

// Get subscriptions by plan:
$subscriptions = PlanSubscription::byPlan($plan_id)->get();

// Get subscription by user:
$subscription = PlanSubscription::byUser($user_id)->first();

// Get subscriptions with trial ending in 3 days:
$subscriptions = PlanSubscription::findEndingTrial(3)->get();

// Get subscriptions with ended trial:
$subscriptions = PlanSubscription::findEndedTrial()->get();

// Get subscriptions with period ending in 3 days:
$subscriptions = PlanSubscription::findEndingPeriod(3)->get();

// Get subscriptions with ended period:
$subscriptions = PlanSubscription::findEndedPeriod()->get();

// Exclude subscriptions which are canceled:
$subscriptions = PlanSubscription::excludeCanceled()->get();

// Exclude subscriptions which are immediately canceled:
$subscriptions = PlanSubscription::scopeExcludeImmediatelyCanceled()->get();