enkeli / conekta-cashier
Conekta Cashier 为 Laravel 提供了一个收取订阅费用的接口。从 dinkbit/conekta-cashier 分支而来,并更新为与 Laravel 5.1+ 和最新的 Conekta SDK 兼容。
Requires
- php: >=7.2.0
- conekta/conekta-php: 4.0.*
- laravel/framework: 5.7.*
Requires (Dev)
- illuminate/routing: ~5.0
- illuminate/view: ~5.0
- mockery/mockery: 0.9.*
- phpunit/phpunit: 4.0.*
README
将 Stripe Laravel Cashier 移植到 Conekta。
从 dinkbit/conekta-cashier 分支出来,以与最新的 Laravel 和 Conekta 的 PHP SDK 兼容。
注意: 这仍然是一个正在进行的分支/更新。在 PHP 7.2、Laravel 5.7 和 Conekta PHP v.4.0.4 上进行了测试。
目前的工作内容
- 单次收费
- Webhooks
更新
- 新的事件驱动 Webhooks 系统
- 添加 Oxxo 支付
Laravel Cashier
简介
Laravel Cashier 提供了一个表达性强、流畅的接口来访问 Conekta 的订阅计费服务。它处理了几乎所有您不希望编写的样板订阅计费代码。除了基本的订阅管理外,Cashier 还可以处理优惠券、交换订阅、订阅“数量”、取消宽限期,甚至生成发票 PDF。
配置
Composer
首先,将 Cashier 包添加到您的 composer.json
文件中
"dinkbit/conekta-cashier": "~2.0" (For Conekta 1.0.0 PHP-SDK 2.0)
服务提供者
接下来,在您的 app
配置文件中注册 Dinkbit\ConektaCashier\CashierServiceProvider
。
迁移
在使用 Cashier 之前,我们需要在您的数据库中添加几个列。不用担心,您可以使用 conekta-cashier:table
Artisan 命令来创建一个迁移来添加所需的列。例如,要将列添加到用户表中,请使用 php artisan conekta-cashier:table users
。一旦创建了迁移,只需运行 migrate
命令即可。
模型设置
接下来,在您的模型定义中添加 Billable
特性和适当的日期修改器
use Dinkbit\ConektaCashier\Billable;
use Dinkbit\ConektaCashier\Contracts\Billable as BillableContract;
class User extends Eloquent implements BillableContract {
use Billable;
protected $dates = ['trial_ends_at', 'subscription_ends_at'];
}
Conekta 密钥
最后,在您的 services.php
配置文件中设置您的 Conekta 密钥
'conekta' => [
'model' => 'User',
'secret' => env('CONEKTA_API_SECRET'),
],
或者您也可以将其存储在您的启动文件或服务提供者中,例如 AppServiceProvider
User::setConektaKey('conekta-key');
订阅计划
一旦您有了模型实例,您就可以轻松地将该用户订阅给一个特定的 Conekta 计划
$user = User::find(1);
$user->subscription('monthly')->create($creditCardToken);
您还可以扩展订阅试用期。
$subscription = $user->subscription('monthly')->create($creditCardToken);
$user->extendTrial(Carbon::now()->addMonth());
使用 subscription
方法将自动创建 Conekta 订阅,并更新您的数据库以包含 Conekta 客户 ID 和其他相关计费信息。如果您的计划在 Conekta 中配置了试用期,试用期结束日期也将自动设置在用户记录上。
如果您的计划在 Conekta 中没有配置试用期,您必须在订阅后手动设置试用期结束日期
$user->trial_ends_at = Carbon::now()->addDays(14);
$user->save();
指定额外的用户详细信息
如果您想指定额外的客户详细信息,您可以通过将它们作为 create
方法的第二个参数传递来这样做
$user->subscription('monthly')->create($creditCardToken, [
'email' => $email, 'name' => 'Joe Doe'
]);
要了解更多关于 Conekta 支持的附加字段的信息,请参阅 Conekta 的 客户创建文档。
单次收费
如果您想对订阅客户的信用卡进行一次性收费,可以使用charge
方法
$user->charge(100);
charge
方法接受您想要收费的金额,以货币的最小单位进行计算。例如,上面的示例将向用户的信用卡收取100美分,即1.00美元。
charge
方法接受一个数组作为第二个参数,允许您将任何选项传递给底层的Conekta收费创建。
$user->charge(100, [
'card' => $token,
]);
如果收费失败,charge
方法将返回false
。这通常表明收费被拒绝。
if ( ! $user->charge(100))
{
// The charge was denied...
}
如果收费成功,方法将返回完整的Conekta响应。
交换订阅
要更换用户到新的订阅,请使用swap
方法
$user->subscription('premium')->swap();
如果用户处于试用期,试用期将正常保留。此外,如果订阅中存在“数量”,该数量也将保留。
取消订阅
取消订阅非常简单
$user->subscription()->cancel();
当订阅被取消时,Cashier会自动将数据库中的subscription_ends_at
列设置为。该列用于知道何时subscribed
方法应开始返回false
。例如,如果客户在3月1日取消了订阅,但订阅原定于3月5日结束,则subscribed
方法将继续返回true
,直到3月5日。
恢复订阅
如果用户取消了他们的订阅,并且您希望恢复,请使用resume
方法
$user->subscription('monthly')->resume($creditCardToken);
如果用户取消了一个订阅,然后在订阅完全过期之前恢复了该订阅,他们将不会立即被收费。他们的订阅将简单地重新激活,并在原始计费周期中收费。
检查订阅状态
要验证用户是否已订阅您的应用程序,请使用subscribed
命令
if ($user->subscribed())
{
//
}
subscribed
方法非常适合作为路由中间件
public function handle($request, Closure $next)
{
if ($request->user() && ! $request->user()->subscribed())
{
return redirect('billing');
}
return $next($request);
}
您还可以使用onTrial
方法确定用户是否仍在试用期(如果适用)
if ($user->onTrial())
{
//
}
要确定用户是否曾是活跃的订阅者但已取消订阅,请使用cancelled
方法
if ($user->cancelled())
{
//
}
您还可以确定用户是否已取消订阅,但仍在直到订阅完全过期为止的“宽限期”内。例如,如果用户在3月5日取消了一个原定于3月10日结束的订阅,则用户在3月10日之前处于“宽限期”。请注意,在此期间,subscribed
方法仍然返回true
。
if ($user->onGracePeriod())
{
//
}
可以使用everSubscribed
方法确定用户是否曾订阅过您应用程序中的任何计划
if ($user->everSubscribed())
{
//
}
可以使用onPlan
方法确定用户是否已根据其ID订阅了特定的计划
if ($user->onPlan('monthly'))
{
//
}
处理失败的支付
如果客户的信用卡过期了怎么办?不用担心 - Cashier包括一个可以轻松为您取消客户订阅的Webhook控制器。只需将路由指向该控制器
Route::post('conekta/webhook', 'Dinkbit\ConektaCashier\WebhookController@handleWebhook');
就这样!失败的支付将由控制器捕获和处理。在三次失败的支付尝试之后,控制器将取消客户的订阅。此示例中的conekta/webhook
URI仅用于示例。您需要根据Conekta设置配置该URI。
处理其他 Conekta Webhooks
如果您想处理额外的Conekta webhook事件,只需扩展Webhook控制器。您的方法名称应与Cashier的预期约定相对应,具体来说,方法应以前缀handle
和您希望处理的Conekta webhook的名称开头。例如,如果您想处理invoice.payment_succeeded
webhook,您应向控制器添加一个handleInvoicePaymentSucceeded
方法。
class WebhookController extends Dinkbit\ConektaCashier\WebhookController {
public function handleInvoicePaymentSucceeded($payload)
{
// Handle The Event
}
}
注意:除了在数据库中更新订阅信息外,Webhook控制器还将通过Conekta API取消订阅。
待办事项
- 当Conekta提供时,添加发票支持。