Laravel + Stripe Payment Link で有料ダウンロード機能をつくる

こんにちは。フリーランス・コンサルタント&エンジニアの 九保すこひ です。

さてさて、開発の業界もそうですが、サービスの世界でも進化が早い時代になりました。

そんな「早い変化」を逃さないよう皆さんのブログ・ツイートはチェックするようにしているのですが、そんな中、あるニュースを目にしました。

それは・・・・・・??

リンクをつくるだけで決済ができる「Payment Link」

です。

これは 2022年2月1日 に発表された新機能なのですが、以下のようにシンプルに決済機能を用意することができます。

  1. Stripe で URLをつくる
  2. ブログやウェブサイトにリンクを設置する
  3. 完了!(決済できるようになる)

つまり、決済部分はStripeが受け持ってくれるようになったんですね。

もちろん画面移動しないといけませんので、ユーザーが「あれ、これ大丈夫なの?」と少し不安にさせてしまう部分があるかもしれませんが、サイト運営者からするとStripe内の決済なのでセキュリティ的に安心できるんじゃないでしょうか。

そこで❗

今回は、この「Payment Link」を使って以下の「有料ダウンロード機能」を作ってみることにします。

  1. リンクから移動して1,000円 を払う
  2. ウェブフックでダウンロード用のパスワードをメール送信
  3. ダウンロードする(👈 今回ここは省略します)

ぜひ何かの参考になりましたら嬉しいです。😄✨

「ドラクエの『旅の扉』っぽい
須濱神社へ行ってきました
勇者ご一行がいました

開発環境: Laravel 9.x

Stripe で Payment Link をつくる

まずは、StripePayment Link(決済URL)をつくります。

Stripeにログインして、画面左にある「Payments > Payment links」へ移動してください。

すると、ページ右上に「+ New」というボタンがあるのでこれをクリック。

ページ移動すると商品を選択する入力ボックスがあるので、今回は新しい商品を追加することにします。「Add new product」をクリックしてください。(もちろん登録済みの商品を選択してもOKです)

すると、以下のようなポップアップが表示されますので、以下の項目を入力&選択して「Add product」ボタンをクリックしてください。

Description(説明文)は任意です。
※ また、One timeは一回だけの決済で、Recurringは繰り返しの決済です。

商品をセットしたら、「Create link」ボタンをクリックしてください。

※ ちなみに、オプションでは電話番号や住所を必須にしたりできます。また「サンキュー・メッセージ」を変更することもできますよ👍

すると、「ペイメント・リンク」が作成されますので、このURLを控えておいてください。テスト時に使います。

ウェブフックをつくる

続いて、Stripeで「ウェブフック」をつくります。

ウェブフックとは、シンプルに言うと「処理が完了したら知らせるね」機能のことで、今回の場合だと「決済が完了すると、Stripe側から情報を送ってくれる」機能ということになります。

では、実際につくっていきましょう。
まず、ページ右上にある「Developers」ボタンをクリックします。

そして、ページ左側メニューの「Webhooks」をクリックしましょう。

すると、ウェブフックのページに移動するので、「Add an endpoint」ボタンをクリックします。

ウェブフックの詳細を入力するページになるので、「Endpoint URL」を入力します。

Endpoint URLは、後ほどLaravelで設定するURLのことで、今回は「https://************/webhook/stripe」になるよう進めます。

そして、「Select events」をクリックしてください。

有効にできるウェブフックの種類リストが表示されるので、charge.succeededにチェックを入れます。

そして、「Add events」ボタンをクリックしましょう。

これで、ウェブフックに必要な情報の入力は完了したので、「Add an endpoint」ボタンをクリックして保存してください。

すると、完了ページが表示されるので、「Reveal」リンクをクリックします。

ウェブフック用の「シークレット・キー」が表示されるので、これをコピーして.envにセットしておいてください。

.env

STRIPE_WEBHOOK_SECRET=whsec_*************************

これでStripe側の設定は完了です。

ウェブフックを受けつける部分をつくる

では、ここからはLaravel側の作業になります。

パッケージをインストールする

今回はシンプルにStripeが用意してくれているstripe-phpというパッケージを使って実装します。

以下のコマンドを実行してください。

composer require stripe/stripe-php

メール送信部分をつくる

そして、支払いが完了したらメール送信できるようにMailableをつくります。
以下のコマンドを実行してください。

php artisan make:mail PaymentSucceeded

すると、ファイルが作成されるので中身を以下のようにします。

app/Mail/PaymentSucceeded.php

// 省略

class PaymentSucceeded extends Mailable
{
    // 省略

    public function build()
    {
        $download_password = 'secret'; // 👈 ダウンロード用パスワード

        return $this
            ->view('emails.payment_succeeded', [
                'download_password' => $download_password
            ])
            ->subject('ご購入ありがとうございました。');
    }
}

また、メール文面は以下のようにつくります。

resources/views/emails/payment_succeeded.blade.php

ダウンロードパスワードは「{{ $download_password }}」です。

コントローラーをつくる

次に、実際にデータを取得することになるコントローラーをつくります。
以下のコマンドを実行してください。

php artisan make:controller Webhook\\StripeController

するとファイルが作成されるので、中身を以下のようにします。

app/Http/Controllers/Webhook/StripeController.php

<?php

namespace App\Http\Controllers\Webhook;

use App\Http\Controllers\Controller;
use App\Mail\PaymentSucceeded;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;

class StripeController extends Controller
{
    public function handleWebhook(Request $request)
    {
        $payload = $request->getContent();
        $sigHeader = $request->header('Stripe-Signature');
        $secret = env('STRIPE_WEBHOOK_SECRET'); // 本来は config から呼び出すべきです
        $event = null;

        try {

            $event = \Stripe\Webhook::constructEvent(
                $payload,
                $sigHeader,
                $secret
            );

        } catch(\Exception $e) {

            abort(400);

        }

        $event_type = $event->type;

        if($event_type === 'charge.succeeded') {

            $customer_email = data_get($event, 'data.object.billing_details.email');

            if(!empty($customer_email)) {

                Mail::to($customer_email)->send(new PaymentSucceeded());

            }

        }

    }
}

この中で重要なのが、\Stripe\Webhook::constructEvent()$sigHeaderが正しいものかどうかを検証している部分です。

try 〜 catchにすることで検証に失敗した場合は例外として処理されます。

なお、地味にそこまで有名ではないかもですが、37行目にあるLaravelのヘルパー関数data_get()は便利なので紹介させてください。

…というのも、この関数を使うことで「該当する値がなければ null を返す」、つまりエラーで途中終了しなくなるからです。

また、第二引数にデフォルト値をセットするとその値が帰ってくるので、使い方を覚えておくといろいろと便利ですよ👍

※ ちなみにウェブフックは「アカウント」ごとに設定するので、複数商品が登録されている場合は商品IDでチェックしてif分岐するといいでしょう。Stripeinvoice objectの詳細は こちら

ルートをつくる

続いて、URLを決める「ルート」です。

use App\Http\Controllers\Webhook\StripeController;

// 省略

Route::post('webhook/stripe', [StripeController::class, 'handleWebhook']);

CSRF 制限を解除する

忘れては行けないのが、CSRF制限の解除です。

Laravelでは、セキュリティ向上のために「CSRF制限」が有効になっていますが、これがあると今回のウェブフックも拒否されてしまうので、「ウェブフックのURLだけ」解除します。

app/Http/Middleware/VerifyCsrfToken.php

<?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/stripe' // 👈 ここを追加しました
    ];
}

これで作業は終了です。
お疲れ様でした😄✨

テストしてみる

では、実際に「Payment Link」にアクセスして「ダウンロード用のパスワード」がメール送信されるかチェックしてみましょう❗

まずは「Stripe で Payment Link をつくる」でつくったURLにブラウザからアクセスします。

すると以下のように決済フォームが表示されるので必要な項目を入力します。(ページが横長なので2つに分割しています)

※ ちなみにStripeのテスト用クレジットカード番号は こちら をご覧ください。

そして、「Pay」ボタンをクリックすると・・・・・・??

はい❗
クレジットカードでの支払いが完了しました。(ちなみにこのメッセージは設定で日本語に変更できます)

では、肝心のメールの方はどうでしょうか・・・・・・??

はい❗
メールが送信されてきて、中にはダウンロード用のパスワードが書かれていました。

全て成功です😄✨

企業様へのご提案

今回ご紹介した「Payment Link」を使うと、極端な話ウェブサイトを持っていなくても決済ができるようになります。

例えば、LINEで決済URLを送信することもできますし、ツイッターを使ってもいいかもしれません。

また、途中ご紹介しましたが決済をStripeのサイト内で行うことになりますので、サイトのセキュリティとは切り離して利用できることが大きなメリットとなっています。(また、決済完了時にリダイレクトすることもできます)

もし、「Payment Link」をご利用になりたい場合はぜひお問い合わせからご連絡ください。

お待ちしております。😄✨

開発のご依頼お待ちしております
開発のご依頼はこちらから: お問い合わせ
どうぞよろしくお願いいたします! by 九保すこひ

おわりに

ということで、今回はStripeの新機能「Payment Link」をLaravelで使えるようにしてみました。

以前このブログでStripeを使ったときはLaravel Cashierという公式ドキュメントにも書かれているパッケージを使いましたが、Stripe自体が提供しているパッケージでもシンプルに書けて好感触でした👍

ちなみに、ペイメント・リンクが使えるといろんなところで簡単に決済できるようになるので、使い方を考えてみたいと思います。

ぜひ皆さんも試してみてくださいね。

ではでは〜❗

「おいしいタコ焼き屋さん
見つけました❗」

このエントリーをはてなブックマークに追加       follow us in feedly