Nuxt.js+LaravelでStripeのCheckoutの実装をやってみた【Stripe決済ページ遷移編】
概要
LaravelとNuxt.jsでStripeの決済処理を実装しました。
Stripeにはいくつか決済方法があるのですが今回はCheckoutと呼ばれる、Stripeが用意してくれた決済フォームを使用しました。
また、Checkoutにも2種類存在し、「決済時にStripeの決済ページに遷移する方法」と「自前のページに決済フォームを埋め込む方法」があるのですが、今回は「決済時にStripeの決済ページに遷移する方法」の紹介になります。
実装したもの
顧客が1つの商品を購入して完了するまでの実装をしました
事前準備
StripeのAPIキーの取得
以下を参考にAPIキーを取得してください。
公開可能キーはフロントエンド側で使用するキー。
シークレットキーはバックエンド側で使用するAPIキー。
商品の追加
ダッシュボードの商品カタログから、購入してもらいたい商品を追加し、そのAPI IDをメモしておく。(バックエンドで使用する)
顧客アカウントの作成
誰が購入したかがわかるように、Stripeの顧客アカウントを作成する。
今回は記載していないが、Stripe APIを使用して顧客アカウントを作成も可能。
ダッシュボードの顧客より作成し、顧客IDをメモしておく。(バックエンドで使用する)
決済の簡単な流れ
- フロントがバックエンドのCheckoutセッション作成APIを叩く(フロント)
- バックエンドがstripeのセッション作成APIを叩き、その結果をフロントに返す(バックエンド)
- フロントがレスポンスのsessionIdを使用し、stripeの決済ページにリダイレクトする(フロント)
- 決済をし、任意のページにリダイレクト(フロント)
詳しくは以下をチェック↓
バックエンドの実装(Laravel)
ライブラリを使用し、StripeのCheckoutセッション作成APIを叩き、その結果を返すAPIの作成をしました。
ライブラリについて
stripe-phpという、 Stripe公式のphp用のライブラリを使用して実装しました。
採用理由としては、公式で信頼できるという点とドキュメントや使用例がたくさんあった点です。
Laravel CahierというLaravelが提供している別のライブラリも存在したのですが、こちらはドキュメントや使用例が少なく、サブスク支払がメイン機能そうだったので、今回は使用しませんでした。
重要なところの解説
$stripe->checkout->sessions->create()
でStripeのCheckoutセッション作成APIを叩いています。以下にパラメーターについて解説します。
パラメーター | 説明 |
---|---|
line_items->price | 顧客に購入してほしい商品のID。事前準備の商品IDを記載する |
line_items->quantity | 顧客に購入してもらう商品の個数 |
mode | 今支払うか、後払いにするか、サブスクにするかを選択できる |
customer | Stripeの顧客アカウントID。誰が購入したかの把握ができる。事前準備の顧客IDを記載する |
success_url | 支払いに成功した時のリダイレクト先 |
cancel_url | Stripeの決済ページの戻りボタンを押した時のリダイレクト先 |
automatic_tax->enable | 税金の自動徴収をするかどうか。オンにすると価格1万円に設定した商品が、 税込の1万1千円で決済される |
payment_method_options->card->setup_future_usage | クレジットカードの情報を保存する。off_sessionにするとずっと保存してくれる |
payment_method_types | 支払い方法をどうするか。カード決済、ApplePayでの支払いなど選択できる |
idempotency_key | 多重決済を防ぐためのキー。 ユニークである必要がある。顧客が商品を購入する時の初回に作成し、それ以降はDBに保存されたこのキーを参照する |
ソースコード
public function createCheckoutSession(): JsonResponse
{
/** @var string $config */
$config = config('define.stripe.token');
$stripe = new StripeClient($config);
$checkout = $stripe->checkout->sessions->create([
// 商品
'line_items' => [[
'price' => 'price_id',//商品ID
'quantity' => 1,//個数
],
],
'mode' => 'payment', // 支払いモード
'customer' => 'customer_id',//顧客ID
'success_url' => 'http://localhost:8080/success,
'cancel_url' => 'http://localhost:8080/cancel',
// 税金を自動徴収するかどうか
'automatic_tax' => [
'enabled' => true,
],
// 支払い方法を保存するかどうか
'payment_method_options' => [
'card' => [
'setup_future_usage' => 'on_session',
],
],
// 支払い方法
'payment_method_types' => ['card'],
],[
'idempotency_key' => 'G5pobWIO8Q0ODYK1313333333',
]);
return response()->json($checkout);
}
フロントエンドの実装
ボタンを押したら、バックエンドのセッション作成のAPIを叩き、レスポンスのsessionIdを使用し、Stripeの決済ページにリダイレクトさせるような実装になっています。
stripe-jsでの実装
stripe-jsという、Stripeの公式のJavaScript用のライブラリを使用した実装方法の紹介です。
重要なところの解説
バックエンドからもらったclientSecretを使用し、ライブラリのredirectToCheckout()を呼べば、
Stripeの決済ページにリダイレクトします。
// Stripeのページにリダイレクトする
await stripe?.redirectToCheckout({
sessionId: res.data.id,
})
ソースコード
<template>
<div>
<div>
<button @click="submit">支払いをする</button>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue'
import { StripeEmbeddedCheckout, loadStripe } from '@stripe/stripe-js'
import axios from 'axios'
export default Vue.extend({
name: 'StripeTest',
head: () => ({
title: 'StripeTest | back check',
}),
components: {},
data() {
return {
publishableKey: process.env.STRIPE_PUBLISHABLE_KEY,
loading: false,
sessionId: '',
checkout: undefined as StripeEmbeddedCheckout | undefined,
}
},
methods: {
async submit() {
const stripe = await loadStripe(
process.env.STRIPE_PUBLISHABLE_KEY
? process.env.STRIPE_PUBLISHABLE_KEY
: ''
)
await axios
.post('http://localhost:8080/api/create_session')
.then(async (res) => {
// Stripeのページにリダイレクトする
await stripe?.redirectToCheckout({
sessionId: res.data.id,
})
})
},
})
</script>
vue-stripeでの実装
vue-stripeとは、Stripeの認定パートナーのライブラリです。
ドキュメントが充実している。Checkoutで、Stripeの決済ページに遷移する方は実装できるが、自前のページに決済フォームを埋め込む方法は実装できません。
stripe-jsの方がコード量少ないので、個人的にはstripe-jsをお勧めします。
重要なところの解説
以下のように、ライブラリのコンポーネントを使用し、バックエンドからのsessionIdをコンポーネントに設定し、this.$refs.checkoutRef.redirectToCheckout();
を呼び出すだけで、Stripeの決済ページに遷移する。
<stripe-checkout
ref="checkoutRef"
mode="payment"
:pk="publishableKey"
:session-id="sessionId"
@loading="(v) => (loading = v)"
/>
ソースコード
<template>
<div>
<stripe-checkout
ref="checkoutRef"
mode="payment"
:pk="publishableKey"
:session-id="sessionId"
@loading="(v) => (loading = v)"
/>
<div>
<button @click="submit">支払いをする</button>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue'
import { StripeCheckout } from '@vue-stripe/vue-stripe'
import axios from 'axios'
export default Vue.extend({
name: 'StripeTest',
head: () => ({
title: 'StripeTest | back check',
}),
components: {
StripeCheckout,
},
data() {
return {
publishableKey: process.env.STRIPE_PUBLISHABLE_KEY,
loading: false,
sessionId: '',
}
},
methods: {
async submit() {
await axios
.post('http://localhost:8080/create_checkout_session')
.then((res) => {
this.sessionId = res.data.id
})
.then(() => {
;(this.$refs.checkoutRef as any).redirectToCheckout()
})
},
},
})
</script>
終わりに
今回はStripeを使用し、決済ページに遷移するCheckoutの実装をやってみました。
Stripeの使用は初めてだったのですが、実装もそこまで難しなく、簡単に決済処理が作れて驚きでした。
ダッシュボードも使いやすかったので、決済の導入にはStripeをお勧めします。
Discussion