パッケージ入れる
composer require laravel/cashier
php artisan migrate
上記マイグレーションにより、
usersテーブルに課金関連のカラムを追加 & subscriptionsテーブルなどが作成される
Userテーブルを課金対象にする
- app/Models/User.php
Billableトレイト (=サブスクにまつわる様々なメソッドが使える)をuseする
use Laravel\Cashier\Billable; // 追加
class User extends Authenticatable
{
use Billable; // 追加
}
Stripeキーの設定
- .env
STRIPE_KEY=your-stripe-key
STRIPE_SECRET=your-stripe-secret
CASHIER_CURRENCY=jpy
CASHIER_CURRENCY_LOCALE=ja_JP
CASHIER_LOGGER=daily
フォームの実装
- routes/web.php
use App\Http\Controllers\RegisterController;
Route::get('/register', [RegisterController::class, 'form'])->name('register');
Route::post('/register', [RegisterController::class, 'register']);
- resources/views/register.blade.php
@extends('layouts.app')
@section('title', '新規登録')
@section('content')
<form method="POST" action="{{ route('register') }}" id="registerForm">
@csrf
<input type="hidden" name="paymentMethodId" value="{{ old('paymentMethodId') }}"/>
<div>
<label for="name">お名前</label>
<input id="name" type="text" name="name" value="{{ old('name') }}" autofocus required>
@error('name')
<span>
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div>
<label for="email">メールアドレス</label>
<input id="email" type="text" name="email" value="{{ old('email') }}" required>
@error('email')
<span>
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div>
<label for="password">パスワード</label>
<input id="password" type="password" name="password" required>
@error('password')
<span>
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
<div>
<label>クレジットカード情報</label>
<input id="card-holder-name" type="text" placeholder="カード名義人">
<!-- Stripe要素のプレースホルダ -->
<div id="card-element"></div>
<span class="card-error-txt">
<strong></strong>
</span>
</div>
<button type="button" id="register-btn">
会員登録をする
</button>
</form>
<!-- Stripe JS読み込み -->
<script src="https://js.stripe.com/v3/"></script>
<script>
const stripe = Stripe('Stripeのpublicキーを入れる');
const elements = stripe.elements();
const cardElement = elements.create('card', {
// 郵便番号を非表示にする
hidePostalCode: true,
});
cardElement.mount('#card-element');
const cardHolderName = document.getElementById('card-holder-name');
const cardButton = document.getElementById('register-btn');
cardButton.addEventListener('click', async (e) => {
const {paymentMethod, error} = await stripe.createPaymentMethod(
'card', cardElement, {
billing_details: {name: cardHolderName.value}
}
);
// カードの検証に失敗した場合
if (error) {
$('.card-error-txt strong').html(error.message)
// カードの検証に成功した場合
} else {
// 支払いIDをセットする
$('[name=paymentMethodId]').val(paymentMethod.id)
// フォームを送信
$('#registerForm').submit()
}
});
</script>
@endsection
- 上記画面を開くとこんな感じのフォームが表示される
- デフォルトだと郵便番号が表示される
非表示にするためにJSで以下オプションを追加している
const cardElement = elements.create('card', {
hidePostalCode: true,
});
RegisterController
- app/Http/Controllers/RegisterController
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use App\Models\User;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
class RegisterController extends Controller
{
/**
* 登録フォーム
*
* @return \Illuminate\View\View
*/
public function form()
{
return view('register');
}
/**
* 登録処理
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\RedirectResponse|\Illuminate\Http\JsonResponse
*/
public function register(Request $request)
{
$data = $request->all();
// ユーザー登録
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
// サブスク登録
$user->newSubscription(
'default', 'price_monthly'
)->create($data['paymentMethodId']);
// 任意の場所にリダイレクト
return redirect(route('home'));
}
}
ダッシュボード確認
ダッシュボードのイベントにて確認ができる
テーブル確認
- usersテーブル
- subscriptionsテーブル
サブスクの最新の状態を取得したい場合
以下のように取得、チェックが可能。
サブスクが失敗して無効になっている場合は、Stripeポータルに誘導することで簡単に更新してもらえる
$user->subscription()->syncStripeStatus();
if ($user->subscription()->stripe_status !== 'active') {
$billingUrl = auth()->user()->billingPortalUrl();
abort(403, "サブスクリプションが無効です。下記よりお支払い方法を設定してください。<br><a href='$billingUrl' target='_blank'>お支払い方法の更新</a>");
}
LaravelでStripeと連携してサブスク決済を行う