22digital / laravel-cashier-fastspring
Cashier Fastspring 是一个类似收银台的 Laravel 扩展包,它为 Fastspring 订阅和支付服务提供接口。
Requires
- php: >=7.1.3
- guzzlehttp/guzzle: ^6.0
- illuminate/database: ~5.6
- illuminate/support: ~5.6
- nesbot/carbon: ^2.0
- symfony/http-kernel: ~2.7|~3.0|~4.0
Requires (Dev)
- illuminate/http: ~5.6
- illuminate/routing: ~5.6
- mockery/mockery: ~1.0
- orchestra/testbench: ~3.6
- phpunit/phpunit: ~7.0
- vlucas/phpdotenv: ^3.3
README
目录
介绍
Cashier Fastspring 是一个类似收银台的 Laravel 扩展包,它为 Fastspring 订阅和支付服务提供接口。此包处理 Webhooks 并提供简单的 Fastspring API。在使用此包之前,强烈建议查看 Fastspring 文档。
安装
将 22digital/laravel-cashier-fastspring
包添加到依赖项中。
composer require "22digital/laravel-cashier-fastspring"
在需要包后,将其服务提供者添加到 config/app.php
中的提供者。
'providers' => array( // ... TwentyTwoDigital\CashierFastspring\CashierServiceProvider::class, )
配置
迁移
Cashier Fastspring 包自带数据库迁移。在需要包后,可以使用以下命令发布它。
php artisan vendor:publish
发布后,您可以在您的 database/migrations
文件夹中找到迁移文件。请记住,您可以根据需要修改它们。
可计费模型
接下来,将 Billable 特性添加到您的模型定义中。此特性提供了各种方法,允许您执行常见的计费任务,例如创建和检查订阅、获取订单等。
use Laravel\Cashier\Billable; class User extends Authenticatable { use Billable; }
API 密钥
您应在 config/services.php
文件中添加 Fastspring 配置。
'fastspring' => [ 'model' => App\User::class, 'username' => env('FASTSPRING_USERNAME'), 'password' => env('FASTSPRING_PASSWORD'), 'store_id' => env('FASTSPRING_STORE_ID'), // strongly recommend to set hmac secret in webhook configuration // to prevent webhook spoofing 'hmac_secret' => env('FASTSPRING_HMAC_SECRET') ],
Webhook 路由
Fastspring 可以通过 Webhooks 通知您的应用程序各种事件。为了处理 Webhooks,请定义一个路由,并在 Fastspring 设置中设置它。
Route::post( 'fastspring/webhook', '\TwentyTwoDigital\CashierFastspring\Http\Controllers\WebhookController@handleWebhook' )->name('fastspringWebhook');
Webhooks & CSRF 保护
Fastspring Webhook 请求需要绕过 CSRF 保护。因此,请确保将您的 Webhook URI 列为 VerifyCsrfToken
中间件的例外。
protected $except = [ 'fastspring/*', ];
创建计划
此包不涵盖在 Fastspring 端创建计划或将创建的计划存储。您应在 Fastspring 仪表板 上创建您的订阅计划。
快速入门
Cashier Fastspring 包含内置的监听器,您可以在 src/Events
中找到这些监听器以进行快速入门。这些监听器可以帮助您将订阅和发票与您的数据库同步。
请记住,您可以根据需要创建和使用您的监听器和数据库结构。要自定义,您可以查看 用法。
在 Cashier Fastspring 中,每个 Webhook 请求都会触发相关的事件。您可以在 app/providers/EventServiceProvider.php
中注册 Webhook 事件监听器。更多内容请参阅 Webhooks。
protected $listen = [ // some others 'TwentyTwoDigital\CashierFastspring\Events\SubscriptionCanceled' => [ 'TwentyTwoDigital\CashierFastspring\Listeners\SubscriptionStateChanged' ], 'TwentyTwoDigital\CashierFastspring\Events\SubscriptionDeactivated' => [ 'TwentyTwoDigital\CashierFastspring\Listeners\SubscriptionDeactivated' ], 'TwentyTwoDigital\CashierFastspring\Events\SubscriptionPaymentOverdue' => [ 'TwentyTwoDigital\CashierFastspring\Listeners\SubscriptionStateChanged' ], 'TwentyTwoDigital\CashierFastspring\Events\OrderCompleted' => [ 'TwentyTwoDigital\CashierFastspring\Listeners\OrderCompleted' ], 'TwentyTwoDigital\CashierFastspring\Events\SubscriptionActivated' => [ 'TwentyTwoDigital\CashierFastspring\Listeners\SubscriptionActivated' ], 'TwentyTwoDigital\CashierFastspring\Events\SubscriptionChargeCompleted' => [ 'TwentyTwoDigital\CashierFastspring\Listeners\SubscriptionChargeCompleted' ] ];
您应为目标订阅支付页面创建一个会话。您可以使用以下 newSubscription
方法完成此操作。
// we create session and return it to frontend to care $builder = Auth::user()->newSubscription('default', $selectedPlan); $session = $builder->create();
您可以将会话ID $session->id
提供给 Fastspring 的 弹出式店面 或 网页店面。
注意:newSubscription
方法不会创建订阅模型。在支付成功后,您可以使用 webhooks 或 浏览器脚本 来通知您的应用程序并创建相关模型。
用法
Cashier Fastspring 提供了可立即使用的 Subscription
、Subscription Period
、Invoice
模型和 webhook 处理程序。下面有详细的解释。请记住,您可以用自己的模型和逻辑轻松替换这些模型。
订阅
Cashier Fastspring 提供了 local
类型的订阅,允许您在不与 Fastspring 交互的情况下创建订阅。这可能有助于您创建无需支付信息的计划。如果一个订阅没有 fastspring_id
,则被视为本地类型。您可以使用 type()
、isLocal()
、isFastspring()
方法来检查类型。
创建订阅
要创建订阅,您可以使用 Billable
模型的 newSubscription
方法。在创建会话后,您可以将会话ID $session->id
提供给 Fastspring 的 弹出式店面 或 网页店面。
// we create session and return it to frontend to care $builder = Auth::user()->newSubscription('default', $selectedPlan); $session = $builder->create();
您还可以提供优惠券或数量。提示:优惠券也可以在 Fastspring 的支付页面上设置。
$builder = Auth::user()->newSubscription('default', $selectedPlan) ->withCoupon('free-ticket-to-Mars') ->quantity(1); // yeap no ticket for returning $session = $builder->create();
如果 Billable
模型尚未作为 Fastspring 客户创建,则 newSubscription
模型会自动创建并保存 fastspring_id
。如果您想手动完成此操作,可以使用 createAsFastspringCustomer
方法。
$apiResponse = Auth::user()->createAsFastspringCustomer();
如果更新了 Billable
模型的详细信息,您也可以使用 updateAsFastspringCustomer
方法在 Fastspring 端更新它们。
$apiResponse = Auth::user()->updateAsFastspringCustomer();
检查订阅状态
在 Fastspring 端,订阅有 5 种状态:active
(活动)、overdue
(逾期)、canceled
(已取消)、deactivated
(已停用)、trial
(试用)。您应该放弃为您的客户服务的唯一状态是 deactivated
状态。其他状态只是信息状态。Cashier Fastspring 包通过 webhooks 保持订阅状态的一致性。
您可以使用 subscribed
方法检查是否应该继续为 Billable
模型提供服务。
if ($user->subscribed('default')) { // }
您可以使用 subscription
方法检索相关订阅模型,并使用 Subscription
方法的其他方法来检查其状态。
$subscription = $user->subscription('default'); // check if you should serve or not $subscription->valid(); // check if its state is active $subscription->active(); // check if its state is deactived $subscription->deactivated(); // check if its state is overdue $subscription->overdue(); // alias: onTrial(). check if its state is trial $subscription->trial(); // alias: canceled(), onGracePeriod(). check if its state is canceled $subscription->cancelled();
您可以使用 subscribedToPlan
方法检查用户是否订阅了给定的计划。
if ($user->subscribedToPlan('monthly', 'default')) { // }
更改计划
您可以使用 swap
方法更改 Billable
模型的当前计划,如下所示。在这样做之前,建议您查看 在升级或降级订阅计划时的分摊计算。
$user = App\User::find(1); $user->subscription('default')->swap('provider-plan-id', $prorate, $quantity, $coupons);
swap
方法与 Fastspring 通信并根据响应更新订阅模型。如果您打算在不进行分摊的情况下交换计划,则计划不会立即更改。在这种情况下,未来的计划和交换日期将保存到 swap_to
和 swap_at
列。当前订阅期结束时,Fastspring 会向您发送有关订阅更改的 webhook 请求。这就是为什么如果您认为要使用分摊计算,请记住正确设置 webhooks。
订阅试用期
您可以在 Fastspring 控制台 上处理您计划的试用天数。
取消订阅
要取消订阅,请在订阅模型上调用 cancel
方法。
$user->subscription('default')->cancel();
如果您想立即取消订阅,可以使用 cancelNow
方法。
$user->subscription('default')->cancelNow();
两种方法都根据Fastspring的响应更新订阅模型。cancel
方法将取消时间保存到swap_at
列。
恢复订阅
要恢复订阅,您可以在订阅模型上使用resume
方法。用户必须仍在宽限期。否则,此方法会抛出LogicException
。
$user->subscription('default')->resume();
此方法根据响应更新订阅模型的state
,并将swap_to
、swap_at
列设置为null
。
订阅周期
Cashier Fastspring包还内置了订阅周期模型和相关方法,以帮助您管理订阅的支付周期。这可能有助于您在支付周期之间保持用户对特定资源的使用。
您可以通过调用Subscription
模型的activePeriodOrCreate
方法来检索当前SubscriptionPeriod
模型,该模型包含id
、start_date
、end_date
信息。如果当前活动周期尚未创建,此方法将从Fastspring API获取它并创建。如果订阅是本地订阅,它也将根据最后一个订阅周期创建一个新周期(如果没有,它假设今天是订阅周期的开始日)。
$activePeriod = $user->subscription('default')->activePeriodOrCreate(); // if you don't want to create an active subscription period immediately when no exist // you can use activePeriod method as below // you can set a cron job for creation of new periods // or do it in your way $activePeriod = $user->subscription('default')->activePeriod();
更新信用卡信息
Fastspring不提供任何API直接更新信用卡或其他支付信息。您应将客户重定向到Fastspring侧的账户管理面板。您可以使用Billable
模型的accountManagementURI
方法生成账户管理面板URL。
$redirectURI = $user->accountManagementURI();
Webhooks
Cashier Fastspring包提供了一个轻松处理webhooks的方法。它为每个webhook请求触发相关事件,并作为参数提供请求负载数据。如果您设置了FASTSPRING_HMAC_SECRET
,它还处理消息安全性。您可以在src/Listeners
文件夹中找到示例监听器。
除了特定的webhook事件之外,还有类别和任何事件。例如,如果您想监听所有webhook请求,可以将您的监听器注册到TwentyTwoDigital\CashierFastspring\Events\Any
事件。同样,如果您想监听所有与订阅相关的webhook请求,可以使用TwentyTwoDigital\CashierFastspring\Events\SubscriptionAny
事件。
您可以在下表中看到包事件与webhook请求之间的关系。
要监听事件,您可以在app/providers/EventServiceProvider.php
中注册监听器。
protected $listen = [ // some others 'TwentyTwoDigital\CashierFastspring\Events\SubscriptionCanceled' => [ 'Your\Lovely\Listener' ] ];
单次收费
尚未实现。如果需要,您可以为此包做出贡献。请检查贡献。
发票
在Fastspring中,发票由Fastspring生成。您不需要生成官方或非官方的发票。如果您使用默认的webhook监听器,您的发票将同步到您的数据库。您可以使用Invoice
模型或通过Billable
特质获取发票URL。
贡献
感谢您考虑为Cashier Fastspring做出贡献。您可以在此处阅读贡献指南。您还可以检查问题以改进此包。
鸣谢
Cashier Fastspring包是由Bilal Gultekin在Taylor Otwell的Cashier包的基础上开发的。您可以在此处查看所有贡献者。
许可
Cashier Fastspring是开源软件,根据MIT许可授权。