LaravelCashier は、Stripe を介してサブスクリプション支払いサービスを実装するためのエレガントでスムーズなインターフェイスを提供します。これには、作成するのを恐れている定型的なサブスクリプション支払いコードのほぼすべてがカプセル化されています。基本的なサブスクリプション管理に加えて、Cashier はクーポンの処理、サブスクリプションのアップグレード/交換、サブスクリプションの「数量」、キャンセル猶予期間、さらには PDF 請求書の生成もサポートしています。
Composer
まず、Cashier パッケージをcomposer.json ファイルに追加し、composer update コマンドを実行します:
"laravel/cashier": "~6.0"
サービスプロバイダー
次に、サービスプロバイダーを config/app.php 設定ファイルに登録します: LaravelCashierCashierServiceProvider。
移行
Cashier を使用する前に、データベースを準備する必要があります。ユーザー テーブルにフィールドを追加し、すべてのユーザー サブスクリプションを処理するための新しいサブスクリプション テーブルを作成する必要があります。
Schema::table('users', function ($table) { $table->string('stripe_id')->nullable(); $table->string('card_brand')->nullable(); $table->string('card_last_four')->nullable();});Schema::create('subscriptions', function ($table) { $table->increments('id'); $table->integer('user_id'); $table->string('name'); $table->string('stripe_id'); $table->string('stripe_plan'); $table->integer('quantity'); $table->timestamp('trial_ends_at')->nullable(); $table->timestamp('ends_at')->nullable(); $table->timestamps();});
移行を作成した後、単に移行コマンドを実行すると、対応する変更が更新されます。データベース。
モデルをセットアップします
次に、Billabletrait を User モデル クラスに追加します。
use Laravel\Cashier\Billable;class User extends Authenticatable{ use Billable;}
ストライプ キー
最後に、設定ファイルに追加します。 config/services.php でストライプ キーを設定します:
'stripe' => [ 'model' => 'User', 'secret' => env('STRIPE_API_SECRET'),],
サブスクリプションを作成するには、まず、次のインスタンスを取得する必要があります。課金モデル。通常は AppUser のインスタンスです。モデル インスタンスを取得した後、newSubscription メソッドを使用してモデルのサブスクリプションを作成できます。
$user = User::find(1);$user->newSubscription('main', 'monthly')->create($creditCardToken);
アプリケーションにサブスクリプションが 1 つしかない場合、newSubscription メソッドに渡される最初のパラメーターは名前です。 2 番目のパラメータは、ユーザーが購読する Stripe プランの ID に対応します。
create メソッドは、この Stripe サブスクリプションを自動的に作成し、データベース内の Stripe 顧客 ID (users テーブルの ストライプ ID) およびその他の関連する請求情報を更新します。サブスクリプション プランに試用期間がある場合、試用期間の終了時刻もデータベース内の対応するフィールドに自動的に設定されます。
追加のユーザー情報
追加の顧客情報を指定する場合は、create メソッドの 2 番目のパラメーターとして渡すことができます:
$user->newSubscription('main', 'monthly')->create($creditCardToken, [ 'email' => $email, 'description' => 'Our First Customer']);
To 詳細Stripe でサポートされているフィールドについては、コンシューマの作成に関する Stripe のドキュメントを参照してください。
クーポン
サブスクリプションの作成時にクーポンを使用したい場合は、withCoupon メソッドを使用できます:
$user->newSubscription('main', 'monthly') ->withCoupon('code') ->create($creditCardToken);
ユーザーがアプリを購読した後、さまざまな便利な方法を使用して購読ステータスを簡単に確認できます。まず、ユーザーが有効なサブスクリプションを持っている場合、サブスクリプションが試用期間中であっても、subscribed メソッドは true を返します。
if ($user->subscribed('main')) { //}
subscribed メソッドはルーティング ミドルウェアでも使用でき、次の設定が可能です。ユーザーのサブスクリプション ステータスに基づいてルーティングします。ルートとコントローラーへのアクセスをフィルターします。
public function handle($request, Closure $next){ if ($request->user() && ! $request->user()->subscribed('main')) { // This user is not a paying customer... return redirect('billing'); } return $next($request);}
ユーザーがまだ試用期間中かどうかを確認したい場合は、非常に便利な onTrial メソッドを使用できます。まだ試用期間中のユーザーに警告メッセージを表示する場合に役立ちます:
if ($user->->subscription('main')->onTrial()) { //}
onPlan メソッドを使用すると、Stripe ID に基づいてユーザーが特定のプランに加入しているかどうかを判断できます:
if ($user->onPlan('monthly')) { //}
キャンセルされたサブスクリプションのステータス
ユーザーがかつては有効なサブスクライバーであったが、現在サブスクリプションをキャンセルしたかどうかを確認するには、キャンセルされたメソッドを使用できます:
if ($user->subscription('main')->cancelled()) { //}
また、ユーザーがサブスクリプションをキャンセルしたことがあるが、完全に無効になるまでまだ「猶予期間」に入っているかどうかも判断します。たとえば、実際には 3 月 10 日まで有効なサブスクリプションをユーザーが 3 月 5 日にキャンセルした場合、そのユーザーは 3 月 10 日まで「猶予期間」に入ります。この間、サブスクライブされたメソッドは依然として true を返すことに注意してください。
if ($user->subscription('main')->onGracePeriod()) { //}
ユーザーがアプリケーションをサブスクライブした後、新しいサブスクリプション プランに変更したい場合があります。ユーザーを新しいサブスクリプションに切り替えるには、swap メソッドを使用します。 。たとえば、ユーザーをプレミアム サブスクリプションに簡単に切り替えることができます:
$user = App\User::find(1);$user->subscription('main')->swap('stripe-plan-id');
ユーザーが試用中の場合、試用期間は維持されます。また、サブスクリプションに数量が存在する場合、その数量を維持することもできます。サブスクリプション プランを切り替えた後、
は、請求書メソッドを使用してユーザーにすぐに請求書を発行できます。
$user->subscription('main')->swap('stripe-plan-id');$user->invoice();
また、数量にも影響されます。たとえば、アプリケーションの各アカウントには月額料金 10 ドルが必要です。サブスクリプション数量を単純に増減するには、incrementQuantity メソッドと decrementQuantity メソッドを使用します。 updateQuantity メソッドを使用して数量を指定します。
$user = User::find(1);$user->subscription('main')->incrementQuantity();// Add five to the subscription's current quantity...$user->subscription('main')->incrementQuantity(5);$user->subscription('main')->decrementQuantity();// Subtract five to the subscription's current quantity...$user->subscription('main')->decrementQuantity(5);
サブスクリプションの数の詳細については、関連する Stripe ドキュメントを確認してください。
$user->subscription('main')->updateQuantity(10);2.5 サブスクリプション税
Cashier では、Stripe に送信する Tax_percent 値を指定するのは簡単です。ユーザーがサブスクリプションに対して支払う税率を指定するには、請求モデルの getTaxPercent メソッドを実装し、小数点以下 2 桁以内で 0 から 100 までの数値を返します。
これにより、次のことが可能になります。使用税率に基づいてモデルを作成するため、さまざまな国のユーザーにとって役立ちます。
要取消订阅,可以调用用户订阅上的 cancel方法:
$user->subscription('main')->cancel();
当订阅被取消时,Cashier 将会自动设置数据库中的 subscription_ends_at字段。该字段用于了解 subscribed方法什么时候开始返回 false。例如,如果客户3月1号份取消订阅,但订阅直到3月5号才会结束,那么 subscribed方法继续返回 true直到3月5号。
你可以使用 onGracePeriod方法判断用户是否已经取消订阅但仍然在“宽限期”:
if ($user->subscription('main')->onGracePeriod()) { //}
如果用户已经取消订阅但想要恢复该订阅,可以使用 resume方法,前提是该用户必须在宽限期内:
$user->subscription('main')->resume();
如果该用户取消了一个订阅然后在订阅失效之前恢复了这个订阅,则不会立即支付该账单,取而代之的,他们的订阅只是被重新激活,并回到正常的支付周期。
如果客户的信用卡失效怎么办?不用担心—— Cashier 自带了 Webhook 控制器,该控制器可以很方便地为你取消客户订阅。只需要定义如下控制器路由:
Route::post('stripe/webhook', 'Laravel\Cashier\WebhookController@handleWebhook');
就是这样!失败的支付将会被该控制器捕获和处理。当 Stripe 判断订阅失败(正常情况下尝试支付失败三次后)时该控制器将会取消客户的订阅。不要忘了:你需要在 Stripe 控制面板设置中配置相应的 webhook URI,否则不能正常工作。
由于 Stripe webhooks 需要通过 Laravel 的CSRF验证,所以我们将该 URI 置于 VerifyCsrfToken中间件排除列表中:
protected $except = [ 'stripe/*',];
如果你有额外想要处理的 Stripe webhook 事件,只需简单继承 Webhook 控制器, 你的方法名应该和 Cashier 期望的约定一致,尤其是方法应该以“handle”开头并以驼峰命名法命名。例如,如果你想要处理 invoice.payment_succeededwebhook,你应该添加 handleInvoicePaymentSucceeded方法到控制器:
<?phpnamespace App\Http\Controller;use Laravel\Cashier\WebhookController as BaseController;class WebhookController extends BaseController{ /** * 处理 stripe webhook. * * @param array $payload * @return Response */ public function handleInvoicePaymentSucceeded($payload) { // 处理该事件 }}
如果你想要使用订阅客户的信用卡一次性结清账单,可以使用账单模型实例上的 charge方法,该方法接收付款金额(应用使用的货币的最小单位对应的金额数值)作为参数,例如,下面的例子使用信用卡支付100美分,或1美元:
$user->charge(100);
charge方法接收一个数组作为第二个参数,允许你传递任何你想要传递的底层 Stripe 账单创建参数:
$user->charge(100, [ 'source' => $token, 'receipt_email' => $user->email,]);
如果支付失败 charge方法将返回 false,这通常表明付款被拒绝:
if ( ! $user->charge(100)) { // The charge was denied...}
如果支付成功,该方法将会返回一个完整的 Stripe 响应。
你可以使用 invoices方法轻松获取账单模型的发票数组:
$invoices = $user->invoices();
当列出客户发票时,你可以使用发票的辅助函数来显示相关的发票信息。例如,你可能想要在表格中列出每张发票,从而方便用户下载它们:
<table> @foreach ($invoices as $invoice) <tr> <td>{{ $invoice->dateString() }}</td> <td>{{ $invoice->dollars() }}</td> <td><a href="/user/invoice/{{ $invoice->id }}">Download</a></td> </tr> @endforeach</table>
在生成PDF分票之前,需要安装 PHP 库 dompdf:
composer require dompdf/dompdf
在路由或控制器中,使用 downloadInvoice方法生成发票的 PDF 下载,该方法将会自动生成相应的 HTTP 响应发送下载到浏览器:
Route::get('user/invoice/{invoice}', function ($invoiceId) { return Auth::user()->downloadInvoice($invoiceId, [ 'vendor' => 'Your Company', 'product' => 'Your Product', ]);});