[ Laravel 5.2 文檔 ] 服務 -- 訂閱支付實現:Laravel Cashier

來源:互聯網
上載者:User

1、簡介

LaravelCashier 為通過 Stripe實現訂閱支付服務提供了一個優雅平滑的介面。它封裝了幾乎所有你恐懼編寫的樣板化的訂閱支付代碼。除了基本的訂閱管理外,Cashier還支援處理優惠券、訂閱升級/替換、訂閱“數量”、取消寬限期,甚至產生PDF 發票。

1.1 安裝&配置

Composer

首先,添加 Cashier 包到 composer.json檔案並運行 composer update命令:

"laravel/cashier": "~6.0"

服務提供者

接下來,在 config/app.php設定檔中註冊服務提供者: Laravel\Cashier\CashierServiceProvider。

遷移

使用 Cashier 之前,我們需要準備好資料庫。我們需要添加一個欄位到 users表,還要建立新的 subscriptions表來處理所有使用者訂閱:

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();});

建立好遷移後,只需簡單運行 migrate命令,相應修改就會更新到資料庫。

設定模型

接下來,添加 Billabletrait 到 User模型類:

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

Stripe鍵

最後,在設定檔 config/services.php中設定 Stripe 鍵:

'stripe' => [    'model'  => 'User',    'secret' => env('STRIPE_API_SECRET'),],

2、訂閱實現

2.1 建立訂閱

要建立一個訂閱,首先要擷取一個賬單模型的執行個體,通常是 App\User的執行個體。擷取到該模型執行個體之後,你可以使用 newSubscription方法來建立該模型的訂閱:

$user = User::find(1);$user->newSubscription('main', 'monthly')->create($creditCardToken);

第一個傳遞給 newSubscription方法的參數是該訂閱的名字,如果應用只有一個訂閱,可以將其稱作 main或 primary,第二個參數用於指定使用者訂閱的 Stripe計劃,該值對應 Stripe 中相應計劃的 id。

create方法會自動建立這個 Stripe 訂閱,同時更新資料庫中 Stripe 的客戶 ID(即 users表中的 stripe_id)和其它相關的賬單資訊。如果你的訂用計畫有試用期,試用期結束時間也會自動被設定到資料庫相應欄位。

額外的使用者資訊

如果你想要指定額外的客戶資訊,你可以將其作為第二個參數傳遞給 create方法:

$user->newSubscription('main', 'monthly')->create($creditCardToken, [    'email' => $email,     'description' => 'Our First Customer']);

要瞭解更多 Stripe 支援的欄位,可以查看 Stripe 關於 建立消費者的文檔。

優惠券

如果你想要在建立訂閱的時候使用優惠券,可以使用 withCoupon方法:

$user->newSubscription('main', 'monthly')     ->withCoupon('code')     ->create($creditCardToken);

2.2 檢查訂閱狀態

使用者訂閱你的應用後,你可以使用各種便利的方法來簡單檢查訂閱狀態。首先,如果使用者有一個有效訂閱,則 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')) {    //}

已取消的訂閱狀態

要判斷使用者是否曾經是有效訂閱者,但現在取消了訂閱,可以使用 cancelled方法:

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

你還可以判斷使用者是否曾經取消過訂閱,但現在仍然在“寬限期”直到完全失效。例如,如果一個使用者在3月5號取消了一個實際有效期間到3月10號的訂閱,該使用者處於“寬限期”直到3月10號。注意 subscribed方法在此期間仍然返回 true。

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

2.3 修改訂閱

使用者訂閱應用後,偶爾想要改變到新的訂用計畫,要將使用者切換到新的訂閱,使用 swap方法。例如,我們可以輕鬆切換使用者到 premium訂閱:

$user = App\User::find(1);$user->subscription('main')->swap('stripe-plan-id');

如果使用者在試用,試用期將會被維護。還有,如果訂閱存在數量,數量也可以被維護。切換訂用計畫後,

可以使用 invoice方法立即給使用者開發票:

$user->subscription('main')->swap('stripe-plan-id');$user->invoice();

2.4 訂閱數量

有時候訂閱也會被數量影響,例如,應用中每個賬戶每月需要付費$10,要簡單增加或減少訂閱數量,使用 incrementQuantity和 decrementQuantity方法:

$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);

你也可以使用 updateQuantity方法指定數量:

$user->subscription('main')->updateQuantity(10);

想要瞭解更多訂閱數量資訊,查閱相關 Stripe文檔。

2.5 訂閱稅金

在 Cashier 中,提供 tax_percent值發送給 Stripe 很簡單。要指定使用者支付訂閱的稅率,實現賬單模型的 getTaxPercent方法,並返回一個在0到100之間的數值,不要超過兩位小數:

public function getTaxPercent() {    return 20;}

這將使你可以在模型基礎上使用稅率,對跨越不同國家的使用者很有用。

2.6 取消訂閱

要取消訂閱,可以調用使用者訂閱上的 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()) {    //}

2.7 恢複訂閱

如果使用者已經取消訂閱但想要恢複該訂閱,可以使用 resume方法,前提是該使用者必須在寬限期內:

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

如果該使用者取消了一個訂閱然後在訂閱失效之前恢複了這個訂閱,則不會立即支付該賬單,取而代之的,他們的訂閱只是被重新啟用,並回到正常的支付周期。

3、處理 StripeWebhook

3.1 訂閱失敗處理

如果客戶的信用卡失效怎麼辦?不用擔心—— Cashier 內建了 Webhook 控制器,該控制器可以很方便地為你取消客戶訂閱。只需要定義如下控制器路由:

Route::post('stripe/webhook', 'Laravel\Cashier\WebhookController@handleWebhook');

就是這樣!失敗的支付將會被該控制器捕獲和處理。當 Stripe 判斷訂閱失敗(正常情況下嘗試支付失敗三次後)時該控制器將會取消客戶的訂閱。不要忘了:你需要在 Stripe 控制台設定中配置相應的 webhook URI,否則不能正常工作。

由於 Stripe webhooks 需要通過 Laravel 的CSRF驗證,所以我們將該 URI 置於 VerifyCsrfToken中介軟體排除清單中:

protected $except = [    'stripe/*',];

3.2 其它Webhooks

如果你有額外想要處理的 Stripe webhook 事件,只需簡單繼承 Webhook 控制器, 你的方法名應該和 Cashier 期望的約定一致,尤其是方法應該以“handle”開頭並以駝峰命名法命名。例如,如果你想要處理 invoice.payment_succeededwebhook,你應該添加 handleInvoicePaymentSucceeded方法到控制器:

    

4、一次性付款

如果你想要使用訂閱客戶的信用卡一次性結清賬單,可以使用賬單模型執行個體上的 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 響應。

5、發票

你可以使用 invoices方法輕鬆擷取賬單模型的發票數組:

$invoices = $user->invoices();

當列出客戶發票時,你可以使用發票的輔助函數來顯示相關的發票資訊。例如,你可能想要在表格中列出每張發票,從而方便使用者下載它們:

  
       @foreach ($invoices as $invoice)        
    @endforeach
   
{{ $invoice->dateString() }} {{ $invoice->dollars() }} id }}">Download

產生PDF發票

在產生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',    ]);});
  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.