LaravelでPAY.JPのWebhookを使ってサブスク決済完了を自動通知する方法

Laravel pay.jpでwebhook

前回の記事では、PAY.JPの決済機能を導入する方法を解説しました。

今回は、Webhookを使った決済通知方法について説明していきます。

決済機能の導入方法はこちらへ

Laravel11から一部書き方が変更されているため、この記事ではLaravel10とLaravel11の違いや、

変更後の書き方についても解説していきます。

パッケージのインストール手順は先ほど説明した内容の「決済機能の導入方法はこちらへ」から

確認してください。

目次

Webhookとは?

Webhookとは、あるサービスで何かイベント(できごと)が起きたときに、指定されたURL(あなたのサーバー)に対して自動的に通知(HTTPリクエスト)を送る仕組みです。

ざっくり言うと、外部サービスからの自動連絡ですね。。。!

これをすることで、ユーザーが画面を開いていなくても、バックグラウンドでイベントに反応できたり

外部サービスとのリアルタイムな連携ができるんです!

PAY.JPの「秘密鍵(APIキー)」を.envに設定

秘密鍵はPAY.JPの管理画面にあるので、PAY.JPに接続してください。

発行元トークンからwhook_**************************をCOPYしてください。

COPYしたKeyを.envに記載します。

.env

PAYJP_SECRET_KEY=sk_test_xxxxxxxxxxxxxxxxxx #テスト用の秘密鍵
PAYJP_WEBHOOK_SECRET=whook_xxxxxxxxxxxxxxxxx #ここに追加

Webhookを受け入れるURLを作成

Laravel側で「POSTリクエストを受け付けるURL」を作成する必要があるので

PAY.JP管理ページからURLを作成します。

設定ページは添付画像を参照してください。

添付画像で赤の枠で目印しているボタンをクリックすると

モーダルが表示されるので、入力欄にURLを入力してください。

下の添付画像を参考に設定してください。

今はテストモードとします。実際に稼働している場合はテストモードにしてくださいね。
ライブモードにしないと動きませんので。。。

CSRFトークンの除外

LaravelでWebhookを受け取るには、CSRFトークンのチェックをスキップする必要があります。

Laravel 11では、これまで使われていた VerifyCsrfToken ミドルウェアの $except プロパティは使われなくなり、

設定方法が変更されています。

以下のように新しい書き方で除外ルートを指定しましょう。

設定ファイルの編集: bootstrap/app.php

<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Middleware;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        channels: __DIR__.'/../routes/channels.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->validateCsrfTokens(except: [
            'webhook', // ここに追加
        ]);
    })
    ->create();

Laravel10の場合

Laravel 10では、app/Http/Middleware/VerifyCsrfToken.phpファイルでCSRFトークンの除外ルートを指定します。

このファイルを開き、$exceptプロパティにWebhookのURI(/webhook)を追加します。

<?php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;

class VerifyCsrfToken extends Middleware
{
    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array<int, string>
     */
    protected $except = [
        'webhook', // ここに追加
    ];
}

ドメイン部分は含めないので注意!!!

Webhook用のルートを作成する

Laravel 11ではルート定義ファイルが routes/web.php の他に routes/api.php に分かれています。

Webhookは基本的に api.php でOKです。

以下コードを参考にしてください。

use App\Http\Controllers\PayjpWebhookController;//追加

Route::post('/webhook', [PayjpWebhookController::class, 'webhook']);

WebhookControllerを作成する

ターミナルでControllerを作成します。以下のコマンドを実行してください。

WebhookControllerとしてますが、名前はなんでも良いです。好みで。

php artisan make:controller WebhookController

次にPAY.JPから送られてくるリクエストデータを処理していきます。
ここでは、決済完了などのイベント通知に含まれるデータを受け取り、必要な情報を取得していく流れを解説します。

app/Http/Controllers/WebhookController.php


namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;

class WebhookController extends Controller
{
    public function webhook(Request $request)
    {
        $payload = $request->getContent();
        $event = json_decode($payload, true);

        // イベントの種類によって処理を分ける
        if ($event['object'] === 'event') {
            switch ($event['type']) {
                case 'charge.succeeded':
                    // 決済成功時の処理
            //データベースに保存、決済メールの送信など。。
                    break;

                case 'charge.failed':
                    // 決済の失敗時の処理
                    break;

                // 他のイベントも必要に応じて追加
            }
        }

        return response()->json(['status' => 'ok']);
    }
}

決済成功のタイミングで、自動的にメール通知を送ることも可能です。

$event = json_decode($payload, true);

取得したJSON文字列は、json_decode を使ってPHPの連想配列に変換し、そこから必要な情報を取り出します。

決済金額をデータベースで管理したい場合も、Webhookから送られてくるJSONデータから金額を取得できます。

たとえば、customer IDを取得したい場合は以下のようにします。

$event['data']['customer'] → "cus_xxxx"

このように、用途に応じて必要なデータを取り出して処理していきましょう!!

ただし、customer IDが誰のものかを特定できるように、PAY.JP側や自社のデータベースで正しく紐づけて管理しておくことが重要です。

以上がPAY.JPのWebhookで決済を通知する方法です。
Webhookを活用すれば、決済完了後に自動でメールを送信したり、データベースに記録したりと、様々な処理を自動化できます。

PAY.JPはテストモードで自由に試すことができるので、クレジット決済の仕組みに興味がある方は、ぜひ一度触ってみてください!

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

目次