DEVELOPMENT
web
js
aws
amplify
vue
dynamoDB
AppSync
GraphQL
目次
はじめに
WEBやスマフォアプリケーションにオンライン決済処理を入れる際、使いたいのが、Stripeですが、Stripeはもはや決済プラットフォームの定番です。 さまざまな機能が充実し、こんなこともできるのか!というほどです。
ですが、その分古い仕様と新しい仕様など大きな変化もあるので、どうやって組み込めばいいのか。
結構手こずりましたので、シンプルに、PaymentInsetsを使った組み込み方を紹介します、
Stripeって?
Stripe はインターネットビジネスのためのソフトウェアプラットフォーム決定版です。世界中の先進的な企業のために、毎年何兆円にのぼる決済処理を取り扱っています。
ということで、オンライン決済するのに、カード以外、様々な決済処理も可能で、さらに開発者目線で、さまざまな言語や手法にも対応している決済プラットフォームですね。
環境
この記事の内容での環境は以下です
- Vue-cliをつかったVueアプリケーション
- 決済のサーバー処理はAWS Lambdaで、入り口にAPI Gateway
- APIの認証はAmplifyでAuthを使いCognitoで認証します(Stripe のCustomerもCotnitoのUsernameを使用する)
- Stripeの決済処理は、「PaymentInsets」を使用
Stripeの決済方法がたくさんあってわからない
- 決済方法が数種類あります
Stripe Checkout
とりあえず、ちゃちゃっと決済だけするなら、コレでしょうか。
- Checkoutは、Stripe側のサーバーに遷移して、決済をするか形ですね。
- 参考 ▶ Stripe Checkoutを使って出来ること
Charges API
- WEBの記事でよく見る手法です。tokenを最初にStripe側にリクエストして、そのtokenで決済処理でもう一回投げるような実装ですね
- ちょっと前の仕様のようで、今からやるならPayment Intents APIでやってね的な感じです
- しかしが、AlipayはCharges APIでないと、できない等もあるようです
Payment Intents
- 新しいAPIで事前にpaymentIntentを作る(カード情報の処理は後)ですが、処理的にこちらのほうが楽な気がします。
- どれ使っていいかわからなくて、とりあえず試すならこちらがいいと思います。
- Client側で、決済情報を作り、stripeに渡し、返却されたclient tokenを投げて決済します
手順
Stripeのアカウント作成
- Stripeから
- ログインしてメニューのダッシュボードに、「開発メニュー」があるので、2つメモる(クライアント側とサーバー側)
サーバーサイド
Lambdaの設定
- 適当に新しく関数を作ります。
- ロールはそのままで大丈夫です
- localにlambda用proj作成
$ yarn init
$ yarn add stripe
- index.js 作成(node)
// STRIPE_KEYは環境変数か何かに保存してください。
const stripe = require("stripe")(process.env.STRPE_KEY);
exports.handler = async (event) => {
// TODO implement
// API Gatewayから渡ってくる(マッピングの設定をしている.proxyの場合は変数名が違うはずです)
const customerId = event.requestContext.authorizer.claims["cognito:username"]
const params = JSON.parse(event.body)
const amount = params.amount
const description = params.description
const result = await stripe.paymentIntents.create({
amount: amount,
currency: 'jpy',
description: description,
metadata: { username: customerId }
})
return {
'headers': {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
statusCode: 200,
body: JSON.stringify(result),
};
};
- zipして、lambdaにUPする
API Gateway
API Gatewayの設定手順はこちらを参考にしてください。proxyは使わずマッピングの定義をしてます。
Amplify auth
AmplifyのAuth(Cognito)の設定は以下を参照してください。
クライアントサイド(vue)
- CDNからロードするのが嫌だったんで、@stripe/stripe-jsを使ってロードします
$ yarn add @stripe/stripe-js
- 決済処理をするページのvueファイル
<template>
~
<div id="card-element">
<!-- Elements will create input elements here -->
</div>
<!-- We'll put the error messages in this element -->
<div id="card-errors" ref="cardErrors" role="alert"></div>
<button v-on:click="payment">
購入する
</button>
~
</template>
<script>
export default {
~
=
data() {
return {
stripe: "",
card: null,
}
},
async mounted() {
this.stripe = await loadStripe('pk_test_xxxxxxxxxxxxxxxxxxxxx')
const elements = this.stripe.elements()
this.card = elements.create("card");
this.card.mount("#card-element");
this.card.addEventListener('change', ({error}) => {
const displayError = this.$refs.cardErrors
if (error) {
displayError.textContent = error.message;
} else {
displayError.textContent = '';
}
});
},
methods: {
payment: async function() {
let res = await axios.post("https://xxxxxxxxxx.execute-api.xx-xxxx-1.amazonaws.com/env/", {
amount: 1000
description: "なんとか商店オンラインとか",
},
{
headers: {
"Content-Type": "application/json",
// これはcognitoでサインしていれば、「Amplify.Auth.currentAuthenticatedUser().then((data) => {」から取れるものをstateに入れてるところから取得
'Authorization': store.state.user.signInUserSession.idToken.jwtToken,
}
}
)
const client_secret = res.data.client_secret;
//client_secretを利用して(確認情報をStripeに投げて)決済を完了させる
const confirmRes = await this.stripe.confirmCardPayment(client_secret, {
payment_method: {
// card: this.props.elements.getElement('card'),
card: this.card,
billing_details: {
name: res.data.metadata.username,
}
}
});
if (confirmRes.paymentIntent.status === "succeeded") {
alert("決済完了")
}
}
</script>
-
mountedにて
- stripeを初期化し
- elementを使用
- cardをelementから作成し(フォームができる)
- mountし、描画します
- addEventListenerで、入力フォームのバリデーションをしてます
- 決済ボタンを押すと、AWSに用意したAPIを叩き、決済情報をstripe側に渡し、client tokenを取得します
- そのtokenで、comfirmCardPaymentで決済処理をします。
試す
- カードフォームに「4242 4242 4242 4242」とテストカード番号、未来の有効期限を入れて決済し
- alertで決済完了と表示されればOKです
まとめ
- Stripeは便利で高機能な分、ボリュームが多く、どれをどうやればいいのかわかりませんでしたが、決済方法が数種類あり、見ていくうちに理解できました。
- そこまできたら、実装はとても簡単で、開発者思いだなと感じました。
- 次回はstripe connect を試したいと思います(顧客管理から、ログイン、自動決済、振り込み等、顧客管理からログイン周りまでお願いできるもの)。
参考
- Stripeの各種API(ChargesとPayment Intents)について
- StripeをVueにシンプルに導入してみた
- Stripe.js & Elements を利用して決済フローを理解する
- (2020年元旦時点で最新の)Stripeの決済をReactで使う
リファレンス
⬇🙏よかったらシェアお願いします🙏⬇
Nobuyuki Ukai
株式会社UKAI 代表取締役CEO。建築を専攻していたが、新卒でYahoo!Japanにエンジニアとして入社。その後、転職、脱サラ、フリーランスエンジニアを経て、田舎へ移住し、ゲストハウスの開業、法人成り。ゲストハウス2軒、焼肉店、カフェ、食品製造業を運営しています。詳細はこちらから