Stripe Checkout × Laravelで簡単に決済機能を作る方法

Laravel

「Stripe Checkoutで簡単に決済機能を作れるらしいけど、具体的にどう実装していいかわからない…」

「コードをあまり書かなくてもStripeで手早く決済機能を作りたい…」

「決済機能を作りたいけど、コードを書くのが面倒…」

このような方に向けて記事を作っています。

今回はStripe CheckoutというStripeに用意されているローコードで簡単に決済機能を実装できる機能を使って決済機能を作っていきます。

Stripe Checkoutは、自分で決済フォームを用意しなくても、Stripe側が用意している決済フォームを利用することで簡単に決済機能を実装できる仕組みになっています。

この記事を最後まで見ていただければ、以下がわかると思います。

  • ほとんどコードを書かなくても、決済機能を実装できる
  • Stripe Checkoutの実装方法がわかる

ぜひ、最後まで読んでください。

筆者の経験
✔️プログラミング歴3年ほど
✔️現役のWebエンジニア
✔️実務でStripeによる決済機能の実装を担当していた

それでは、早速見ていきましょう!

Stripe準備

Stripeアカウントを作成する

Stripeを利用するには、Stripeアカウントがないと始まりません。

まずは、以下のURLからStripeアカウントを作成しましょう。

Stripeアカウント新規作成

必要な情報を入力し、Stripeアカウントが作成できたら、以下のURLからStripeにログインできます。

Stripeログイン画面

ビジネス詳細情報の入力を求められることがありますが、テスト用としてStripeを利用するだけなら入力の必要はありません。

ダッシュボードに行くと、以下のような画面になります。

Stripeの商品を作成する

次にStripeで販売したい商品を作成していきます。

Stripeダッシュボード画面から、メニューの[その他] > [商品カタログ]をクリックします。

以下のような商品カタログページに移動します。

この画面で「商品の追加」ボタンをクリックします。

以下のような入力画面が出てくるので、適当な商品を入力しておきます。

入力が終わったら、「次へ」ボタンをクリックし、商品の詳細情報を入力していきます。

今回はサブスクリプションではないので、商品を作成する場合は、最初に「1回限り」を選択してください。

全て入力が終わったら、「次へ」ボタンをクリックして、「商品を追加」ボタンをクリックします。

これで、商品が一つできました!

サブスクリプションの作り方が気になる方は以下の記事を見ていただければ分かります。

Laravel × Stripeでサブスクリプションを作成する方法

Laravel

Laravelプロジェクト作成

ここまででStripe上に商品を作るところまで完了しました。

それでは、実際にLaravelからどうStripeと連携させるのかについて解説していきます。

まずは、Laravelプロジェクトを作成していきます。

今回はバージョン9.x系です。

composer create-project laravel/laravel=9.x stripe_checkout_test --prefer-dist

これで「stripe_checkout_test」というLaravelプロジェクトのフォルダーが出来上がりました。

Laravel Cashierインストール

LaravelにはStripe専用のライブラリである、Laravel Cashierというライブラリがあります。

こちらを利用することで、

  • 面倒な処理を省ける
  • 自動的にWebhookのセキュリティ機能が備わっている
  • ドキュメントが用意されている

などの利点があります。

そこで、今回はこちらのライブラリを使っていきます。

公式ドキュメントは以下です。

Laravel 9.x Laravel Cashier (Stripe)

詰まった時などは目を通しておくと良いでしょう。

まずはインストールしましょう。

composer require laravel/cashier

次に、マイグレーションをかけておきます。

php artisan migrate

すると、Stripe用のテーブル、カラムとして以下が作成されます。

  • subscriptionsテーブル
  • subscription_itemsテーブル
  • usersテーブル
    • stripe_id
    • pm_type
    • pm_last_four
    • trial_ends_at

データベースの詳しい内容はまた別記事でご紹介します。

今は、Stripeを使う上で必要なテーブルやカラムだと思っておけば大丈夫です。

次に、UseモデルにBillableトレイトを追加しておきます。

use Laravel\Cashier\Billable;

class User extends Authenticatable
{
    use Billable;
}

これをなぜ追加するかというと、Billableトレイトを追加することでサブスクリプションの作成やクーポン適用、支払い方法の更新などのLaravel Cashierで用意されているメソッドをUserモデルから使えるようになります。

.envにAPIキーを設定

次に、テスト用のAPIキーを環境変数に設定していきます。

Stripeダッシュボードに戻って、上のメニューにある「開発者」を開きましょう。

開発者用画面のタブの中に「APIキー」があるはずです。

これをクリックして、APIキーとシークレットキーを確認します。

確認ができたら、Laravelに戻り、.envファイルに以下の環境変数を設定しておきます。

STRIPE_KEY=your-stripe-key
STRIPE_SECRET=your-stripe-secret

ビュー作成

今回、ビューは必要最低限しか実装しません。

また、Stripe Checkoutでは決済成功時の画面と決済キャンセル時の画面を用意することができるようになっています。

そのため、今回は

  1. Stripeフォーム遷移のための画面
  2. 決済成功時の画面
  3. 決済キャンセル時の画面

の3つを用意しておきます。

まずはStripeフォームへ遷移するための画面です。

resources/views/checkout.blade.php

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Stripe Checkout</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
</head>
<body>
    <div class="container">
        <form action="{{ route('checkout.session') }}" method="GET" id="stripe-form">
            @csrf
            <button type="submit" id="card-button" class="btn btn-primary mt-5">
                購入画面へ
            </button>
        </form>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script>
</body>
</html>

次に、決済成功画面です。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Stripe Checkout</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
</head>
<body>
    <div class="container">
        決済成功です!
    </div>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script>
</body>
</html>

最後に、決済キャンセル時の画面です。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Stripe Checkout</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
</head>
<body>
    <div class="container">
        決済がキャンセルされました
    </div>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script>
</body>
</html>

ルーティング作成

ルーティングは、3つのビューのルートとStripe Checkoutのセッションを開始するためのルートを設定していきます。

<?php

use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});
Route::get('/checkout', function () {
    return view('checkout');
});
Route::get('success', function () {
    return view('success');
})->name('success');
Route::get('cancel', function () {
    return view('cancel');
})->name('cancel');
Route::get('/checkout-payment', 'App\Http\Controllers\StripeController@checkout')->name('checkout.session'); // Stripeフォームへ遷移する処理

コントローラ作成

それでは最後に、コントローラでStripe側フォームに遷移するための処理を書いていきます。

まずはファイルを作成します。

php artisan make:controller StripeController

次に、メソッドを追加します。

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\User;

class StripeController extends Controller
{
    public function checkout()
    {
        $user = User::find(1);
        return $user->checkout(config('stripe.price_id'), [
            'success_url' => route('success'),
            'cancel_url' => route('cancel')
        ]);
    }
}

なんと、これだけで決済機能完成です。

今回はデモなので、ユーザーID:1で固定しています。

データベースにはユーザーID:1でユーザーを作成しておいてください。

UserモデルにBillableトレイトを追加したことによって、checkoutメソッドを実行することができるようになりました。

このcheckoutメソッドは、Stripe側フォームに遷移するためのメソッドです。

第一引数にはStripe上で作成した商品の価格IDが入り、第二引数には決済成功時の画面遷移と決済キャンセル時の画面遷移を設定しておきます。

たったこれだけで、決済の機能ができています。

テスト

最後に、決済機能がきちんと動くかテストしてみます。

まずは、/checkoutページにいきます。

購入ボタンを押してみます。

すると、チェックアウトセッションが開始され、Stripeで提供されているフォームに遷移します。

ここから必要情報を入力し、支払いを行います。

なお、Stripeではテストカードが用意されているので、デモで試す場合はこちらを利用しましょう。

Stripeのテスト

支払いが完了すると、決済成功画面に遷移しました。

次に、Stripe上で支払いが行われたか確認してみます。

確認するには、[顧客] > [顧客詳細] > [支払い]で確認できます。

しっかりと支払いが発生していますね。

それでは、Stripeフォーム画面で戻ってみましょう。

戻るボタンを押して戻ってみると、事前に用意しておいたキャンセル画面に遷移するようになっています。

これで、全て確認することができました。

お疲れ様でした!

最後に

いかがでしたでしょうか?

Stripe Checkoutを利用することによってかなりコードを省略して決済機能を実装することができました。

フォーム画面もStripe側で事前に用意されているので、UIも整っており、ユーザーにとっても違和感なく決済ができるかと思います。

また、自作でフォームを作成する方法もあり、以前に紹介しているので気になる方は下記をご覧ください。

Laravel × Stripeでサブスクリプションを作成する方法

手軽にサクッと実装したい、手間をかけたくない、という方はぜひStripe Checkoutを使ってみてください。

それでは、今回はこちらで以上になります。

ご清聴ありがとうございました!

コメント

タイトルとURLをコピーしました