Stripe × PHP(laravel)でクレジットカード登録・決済処理機能を実装してみよう!(事前準備編)

Stripe × PHP(laravel)でクレジットカード登録・決済処理機能を実装!(事前準備編)

久しぶりのブログとなってしまいました・・・11月は本当仕事でバタバタしてしまい、ろくにブログもかけず、ちょっと自己管理の出来なさに反省をしている次第でございます。。。

さて、久しぶりのブログなんですが、今回はStripe×PHP(Laravel)を使ったクレジットカード決済処理機能の実装に関するブログを、自分の備忘録もかねて3回に渡って記載したいと思います。

3回の内容については、以下の通りの区分になっています!

※3回分のブログにさせていただく内容の最終形コードは、上記Githubに掲載しております。こちらの内容を元にお話を進めていきたいと思います!

全ての工程をこと細かに説明するわけではないので、その点ご了承ください!もし同じものを追いたい場合は、https://github.com/majikarikeruo/laravel-stripe-base からコードをpullなりダウンロードなりしてみてください!

(Laravel5.8使用)

今回の作成物について

諸々説明をする前に、3回のブログ記事に分けてご説明させていただく内容を通じて作成するものについての、簡単な画面遷移図を用意してみました。

LaravelとStripeで作成するものの画面遷移図
ログイン or 会員登録までの画面遷移
LaravelとStripeで作成するものの画面遷移図
カード情報表示並びにカード情報登録削除関連
LaravelとStripeで作成するものの画面遷移図
ユーザー情報表示関連

内容としては主に以下の3つに分けられます。

  • ログイン or 会員登録(未ログイン)
  • ユーザー情報表示画面(ログイン後)
  • クレジットカード情報の登録・表示画面(ログイン後)

ユーザーには、「無料会員」「有料会員」の2種類が存在し、「登録したクレジットカードを使って500円を支払うと有料会員になることができる」そんな仕様を想定しています。

以降、全てのコードや機能をこと細かに説明するわけではなく、Stripeに関連する部分を中心にお話を進めていきますので、あらかじめご了承ください!

そもそもStripeとは??

この記事にご興味をもたれている方であればご存知の方が大半かと思いますが、念の為まずは、そもそも「 Stripeとは何か」について、記載しておきたいと思います。

Stripeは、API型のオンライン決済機能提供サービスです。インターネット上で料金の決済を行うことができるようになっているのですが、プログラミングを用いることで、シンプルに決済処理を実装することができ、自サイトへの決済機能の導入をスムーズに行うことが出来ます。

クレジットカード情報などは「token(トークン)」と呼ばれるものに暗号化され、Stripe上に保存されるので、会社や個人が所有しているデータベースに直接クレジットカード情報を保存することはありません。

Stripe × PHPでクレジットカード登録・決済処理機能を実装するために必要な事前準備

それでは、ここからは実際にStripe×PHPでクレジットカード登録や決済処理機能を実装するために、必要な事前準備について書かせていただきたいと思います!

ちなみに今回ご紹介する内容は、僕が実際に行った内容(https://github.com/majikarikeruo/laravel-stripe-base)をベースにしています。

また、1ユーザーあたりのカード登録が1枚であるケースを想定した実装についてご紹介させていただきます!(Stripeでは1ユーザーあたり複数のカード登録を行うこともできるようになっていますが、その方法は今回ご紹介しませんので、ご了承ください!)

1、Stripeへの登録

まずは当然と言えば当然ですが、Stripeのサービスを利用するので、Stripeへの登録を忘れずに行ってください。

先述もさせていただきましたが、「 Stripe」のページから登録をお願いいたします!

登録ができたら、ダッシュボード(管理画面)の中で、以下の2つが発行されているのが確認できるかと思います。

この「公開可能キー」「シークレットキー」にある「トークン」に書かれた暗号は、この後使用しますので、覚えておいてください!

なお、今回Stripeから発行された「公開可能キー」「シークレットキー」は、テスト用として使用できるものになります。

あくまで今回はテスト用なので、本番環境でStripeを使用したい場合は、別途Stripeの管理画面から本番用の「公開可能キー」「シークレットキー」の2つを発行する必要がありますので、その点ご注意くださいね!

2、Composer経由でstripe/stripe-phpライブラリを導入

次に、Composer経由でstripe/stripe-phpライブラリを導入します。

composer require stripe/stripe-php

ターミナルで上記コマンドを打っていただくことで、stripe/stripe-phpライブラリ導入をすることが可能です。

3、Stripe.js

次に必要となってくるのが、Stripe.jsになります。

<script src="https://js.stripe.com/v3/"></script>

この記事では「 Stripeを使ったクレジットカード登録フォーム」を実装してみようと思いますが、基本的には上記のScriptタグをそのままフォームを埋め込んでいる HTMLなりPHPに付け足していただければ OKです!

<form>
//ここにクレジットカードの登録フォームのパーツが入ります。
</form>


<script src="https://js.stripe.com/v3/"></script>
<script src="js/payment.js"></script>
<!--payment.jsに、決済に関するフロントエンド側の処理を今後書いていきます。-->

イメージとしては上記のソースコードのような感じで、要するにクレジットカード登録のフォームと同じページの中の下部に、stripe.jsを読み込みする記述をしていただく形です。

また、同時にpayment.jsというJavaScriptファイルを読み込んでいますが、今回の記事では、payment.jsの中に、Stripeを使ったクレジットカード決済に関するフロントエンド 側の処理を書いていきます。

なので、ファイル名は自由ですし、任意の場所にファイルを作成して、きちんと読み込みができていればOKになります!

※ちなみに今回のgithubサンプルにおいては、resources/views/parts/payment.blade.phpに

<script src="https://js.stripe.com/v3/"></script>
<script src="js/payment.js"></script>

以上の部分を用意し、resources/views/layouts/app.blade.php内に

    @if(request()->path()==='user/payment/form')
        @include('parts.payment');
    @endif

という記述を書いて、/user/payment/formのページが表示された時にだけ、Stripeに関連するJavaScriptを読み込むようにしています。

Stripe × PHPで決済処理機能を実装するために参考となるサイト

さて、準備も出来たし実装スタート!といきたいところなのですが、Stripe × PHPで決済処理機能を実装する上で参考とすべきWebサイト・公式ドキュメントも掲載しておきます。

基本的には上記2つのページです。

Stripeは、プログラミングを使ってStripeにおける決済機能を実装するために「こうやってプログラムを書くとこんなことができるよ」という情報を教えてくれています。

そのページに該当するのがhttps://stripe.com/docs/apiのページになります。

実は。前の章の2番でも紹介した「stripe/stripe-php」ライブラリを事前準備として用意しておく理由はここにあります。

stripe/stripe-phpライブラリを利用することで、https://stripe.com/docs/apiに掲載されているプログラミングの内容をベースに決済処理を実装すれば、決済機能を導入することが可能な状態になるわけなんですね!

Stripe × PHPでクレジットカード登録を実装してみる工程

それではここからは、実際にStripe × PHPで決済処理機能を実装する工程を追ってみたいと思います!

0,データベース・必要なテーブルの作成

この部分についてはLaravel本体のお話になってくるので今回は省略いたしますが、データベース作成を忘れないようにしてください!

ちなみに今回は、Laravel5.8に備わっているmake::auth機能を使ってサクッと認証機能を作成→make::auth機能によって作成されたUserテーブルに、以下2つのカラムを追加しています。

  • Stripeの顧客IDを保存するための「stripe_id」というカラム
  • 有料会員か無料会員かを規程する「status」というカラム(0が無料会員、1が有料会員)

Userテーブルに関する必要最低限のカラム情報だけ下記に抜粋しておきますね!

idnamestatusstripe_id
int(10)、auto incrementvarchar(255)、uniqueint(10)varchar(255)、unique

1,Stripe KEYを.envファイルに設定

まずは、.envファイルにStripeから発行された2種類のKeyを設定します。

Laravelであれば、.envというファイルが初めから提供されていますので、

STRIPE_PUBLIC_KEY=
STRIPE_SECRET_KEY=

という2行を用意し、STRIPE_PUBLIC_KEY=のイコールの右側に、Stripe管理画面に書かれた公開可能キーを入力してください!

同様にして、STRIPE_SECRET_KEY=のイコールの右側には、Stripe管理画面に書かれたシークレットキーを入力してください!

このKEYを入力することによって、PHPでStripeの決済機能を実装するために書かれたプログラミングの内容と、実際のStripeのアカウントを紐づける準備ができた形になります!

(※ Stripeを利用している方はたくさんいらっしゃいますので、「どのStripeアカウントを利用するか」を設定してあげないと、せっかくプログラミングしても決済ができないわけです。そうならないようにするために、アカウントを特定する作業が今回の作業だと思ってください!)

ちなみに、Laravelをご使用であれば、configフォルダの中にpayment.phpを作り、以下のコードを記述しておけば、Config::get()関数からもStripeのキーを参照することができるようになります!(※今回掲載しているgithubのsampleにおいてはこちらを実装しています)

<?php
/* config/payment.php */
return [
   'stripe_public_key' => env('STRIPE_PUBLIC_KEY'),
   'stripe_secret_key' => env('STRIPE_SECRET_KEY'),
];

2、クレジットカード情報登録フォームを用意

次に、クレジットカード情報を入力するためのフォームを用意します。

実はStripeを使ってクレジットカード情報登録フォームを作成する際、大まかにいうと、作成方法は2つあります。

  1. Stripe Checkoutを使用する。これはStripeが作ってくれたフォームをそのまま利用する方法です。そのまま利用するので、デザインを一切いじることはできません。
  2. Stripe Elementsを使用する。これは、Stripe Checkoutと違って、ある程度のデザインカスタマイズが可能です。

今回は、後者の方法、つまりStripe Elementsを使った実装方法をご紹介していきます!

Stripe Elementsについては、Stripe Elements利用方法紹介公式ページでも紹介されています!

必要なルーティング設定を実施&必要なファイルを作成し、コード記述

routes/web.phpにて必要なルーティング設定を行い、該当のController(※今回のgithubサンプルでいうとapp/Http/Controllers/User/PaymentController.phpに該当)、該当のbladeファイル(※今回のgithubサンプルでいうとresources/views/user/payment/form.blade.phpに該当)を用意します。

以下、今回のgithubサンプルから関連部分を抜粋します。

/* app/Http/Controllers/User/PaymentController.php内 */

public function getPaymentForm(){
    return view('users.payments.form');
}
/* route/web.php内より抜粋 */

Route::get('/user/payment', 'User\PaymentController@getCurrentPayment')->name('user.payment');
Route::get('/user/payment/form', 'User\PaymentController@getPaymentForm')->name('user.payment.form');
Route::post('/user/payment/store', 'User\PaymentController@storePaymentInfo')->name('user.payment.store');
/* resources/views/user/payment/form.blade.phpより抜粋 */

<div class="card-body">
    <form action="{{route('user.payment.store')}}" class="card-form" id="form_payment" method="POST">
        @csrf
        <div class="form-group">
            <label for="name">カード番号</label>
            <div id="cardNumber"></div>
        </div>

        <div class="form-group">
            <label for="name">セキュリティコード</label>
            <div id="securityCode"></div>
        </div>

        <div class="form-group">
            <label for="name">有効期限</label>
            <div id="expiration"></div>
        </div>

        <div class="form-group">
            <label for="name">カード名義</label>
            <input type="text" name="cardName" id="cardName" class="form-control" value="" placeholder="カード名義を入力">
        </div>
        <div class="form-group">
            <button type="submit" id="create_token" class="btn btn-primary">カードを登録する</button>
        </div>
    </form>
    <a href="{{route('user.payment')}}">クレジットカード情報ページに戻る</a>
</div>

ここで、HTMLがお分かりの方であれば、「あれ、なんでフォームなのにinputタグじゃなくてdivタグで実装されているところがほとんどなんだ・・・?」と思うかと思います。

Stripe Elementsにおいては、例えば、<div id="securityCode"></div>と書かれた場所に対して、JavaScript側から適切な命令をしてあげることによって、Stripeに最適化された機能を備えたフォームを作成することができる(dibvタグだったものがフォームに変換される)、そんな仕組みになっているわけなんですね!

payment.jsにJavaScriptコードを記述

それでは、resources/views/user/payment/form.blade.phpに書かれたフォームをStripeに最適化させるための JavaScriptをpublic/js/payment.js内に記述してあげましょう!

/* public/js/payment.js */

/* 基本設定*/
const stripe = Stripe("ここにStripeから発行された公開可能キーを入力");
const elements = stripe.elements();

/* Stripe Elementsを使ったFormの各パーツをどんなデザインにしたいかを定義 */
const style = {
    base: {
        fontSize: '12px',
        color: "#32325d",
        border: "solid 1px ccc"
    }
};

/* フォームでdivタグになっている部分をStripe Elementsを使ってフォームに変換 */
const cardNumber = elements.create('cardNumber', {style:style});
cardNumber.mount('#cardNumber');
const cardCvc = elements.create('cardCvc', {style:style});
cardCvc.mount('#securityCode');
const cardExpiry = elements.create('cardExpiry', {style:style});
cardExpiry.mount('#expiration');

payment.js内に上記のようなJavaScriptコードを実装していきましょう!

冒頭2行の部分については、どんなクレジットカード決済フォームを作るにしても必ず必要になります。(公開可能キーの入力を忘れないでくださいね)

今回のgithubサンプルでは、resources/views/parts/payment.blade.phpに

    var stripe_public_key = '{{ config('payment.stripe_public_key');

というJavaScript変数を用意し、変数stripe_public_keyを使って

/* public/js/payment.js の冒頭部分 */ 
const stripe = Stripe(stripe_public_key);

と設定しています。

/* Stripe Elementsを使ったFormの各パーツをどんなデザインにしたいかを定義 */の部分では、文字通り、カード情報入力フォームの見た目をどんな風にしたいのか定義している箇所になります。

そして、重要になってくるのが、フォームでdivタグになっている部分をStripe Elementsを使ってフォームに変換 の部分です!

JavaScriptコードから、1つ分のコードを切り取って解説を入れたものが上記画像になります。

ポイントは以下の2つです。

  • elements.create()の丸括弧の中に 、Stripe Elementsの決まり事に従って、「どんな種類のカード情報を入力するパーツを作りたいか」を設定する。
  • mount()の丸括弧の中に、どのHTMLをStripeに最適化されたフォームのパーツに変換したいかを、id名を使って設定する。

ここまでの「Stripe Elements」に関する決まり事は、https://stripe.com/docs/stripe-js/reference#element-typesに掲載されていますので、ぜひご覧になってみてくださいね!

ここまでの工程を行うと、情報を入力することができるフォームが表示されるようになります!

3、フロントエンド(JavaScript)側でクレジットカード登録に必要な処理を実装

次に、いよいよクレジットカード登録に必要な処理を実装していきたいと思います。

まずは、フロントエンド(JavaScript)側で必要な処理を実装していきましょう!

まずは、payment.jsに加えるコードを紹介します!

以下のコードは、先ほどご紹介したJavaScriptコードの直下に記述するようにしてくださいね!

/* id="form_paymentがついたFormのsubmitEvent発生時のプログラム処理を定義"*/
document.querySelector('#form_payment').addEventListener('submit', function(e) {

/* 何も処理をかまさないとそのままクレジットカード情報が送信されてしまうので一旦HTMLのFormタグがが従来もっている送信機能を停止させる。 */
    e.preventDefault();

/* Stripe.jsを使って、フォームに入力されたコードをStripe側に送信。今回ご紹介している方法の場合、「カード名義」だけはStripe Elementsの仕組みを使っていないため、このままだとカード名義の情報が足りずにカード情報の暗号化ができなくなってしまうので、{name:document.querySelector('#cardName').value}を足すことで、フォームに入力されたカード名義情報も、他の情報と同時にStripeに送ることができるようになる。 */
    stripe.createToken(cardNumber,{name: document.querySelector('#cardName').value}).then(function(result) {


/* errorが返ってきた場合はその旨を表示 */
        if (result.error) {
            alert("カード登録処理時にエラーが発生しました。カード番号が正しいものかどうかをご確認いただくか、別のクレジットカードで登録してみてください。");
        } else {

/* 暗号化されたコードが返ってきた場合は以下のStripeTokenHandler関数を実行。その際、引数として暗号化されたコードを渡してあげる。 */
            stripeTokenHandler(result.token);
        }
    });


/* id="form_payment"が指定されたformの送信ボタン直前に、input type="hidden"のHTMLを挿入し、値にStripeから返ってきた暗号化情報を設定。そして、実際にフォームの内容を送信(事実上、送信されるのは暗号化情報のみとなる) */
    function stripeTokenHandler(token) {
        const form = document.getElementById('form_payment');
        const hiddenInput = document.createElement('input');
        hiddenInput.setAttribute('type', 'hidden');
        hiddenInput.setAttribute('name', 'stripeToken');
        hiddenInput.setAttribute('value', token.id);
        form.appendChild(hiddenInput);

        form.submit();
    }

},false);

上記のJavaScriptコードは、送信ボタンが押された時に実行されるコードになります。

Stripeやpay.jpどの決済サービスにおいては、最初の方にも説明させていただいたように、クレジットカード情報を直接、個人や会社のサーバ・データベースに保存しません。

上記の画像で説明しているように、入力されたクレジットカード情報は、Stripe.jsによってStripeのサーバ側に情報が送られて、暗号化され、最終的に暗号化されたコードがStripeから返却されます。

個人や会社は、Stripeから返却された暗号化コードのみを活用してStripe上に顧客登録&暗号化されたカード情報を登録し、自サイトのデータベースにはStripeの顧客 IDのみを保存すればOK、そんな仕組みになっているんですね。

送信ボタンを押した瞬間にこれだけのことを行うことができるだなんて、テクノロジーの力って改めてすごいなって思います・・・

以上でフロントエンド側の処理は終了となります。

ここまでの内容はStripe.jsのドキュメントにも書かれている内容ではあるのですが、英語なので読み解くのがちょっと大変です!

以上で、事前準備編として、一度ブログ記事の内容を区切らせていただきたいと思います!

まとめ

ということで、今回は「Stripe × PHPでクレジットカード登録・決済処理機能を実装!(事前準備編)」ということで、クレジットカード登録フォームを用意する部分までの内容について、記事を書かせていただきました!

久しぶりのブログがだいぶ超大作な記事となりましたが、良いリハビリになりました笑

クレジットカード登録に関して関連性の高いところを中心にコードを掲載したりもしましたが、誤記やもっと良い方法などありましたら、お問い合わせページからコソっとご教示いただけると幸いです。(もっとスマートな書き方もあるはずなので、見出したら記事も修正していこうと思います)

これを機に、またちょっとずつ、Arrownらしい記事を書いていきたいと思います!

次回は、クレジットカード登録・更新編について書いていきたいと思います!

いつかPHPスクラッチ編も書きます・・・

シェアする

  • このエントリーをはてなブックマークに追加

フォローする