決済プラットフォームStripeをVuejsに組み込む
May 16, 2020

DEVELOPMENT

web
js
aws
amplify
vue
dynamoDB
AppSync
GraphQL

はじめに

WEBやスマフォアプリケーションにオンライン決済処理を入れる際、使いたいのが、Stripeですが、Stripeはもはや決済プラットフォームの定番です。 さまざまな機能が充実し、こんなこともできるのか!というほどです。

ですが、その分古い仕様と新しい仕様など大きな変化もあるので、どうやって組み込めばいいのか。

結構手こずりましたので、シンプルに、PaymentInsetsを使った組み込み方を紹介します、

Stripeって?

Stripe はインターネットビジネスのためのソフトウェアプラットフォーム決定版です。世界中の先進的な企業のために、毎年何兆円にのぼる決済処理を取り扱っています。

ということで、オンライン決済するのに、カード以外、様々な決済処理も可能で、さらに開発者目線で、さまざまな言語や手法にも対応している決済プラットフォームですね。

環境

この記事の内容での環境は以下です

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

AmplifyAuthCognito)の設定は以下を参照してください。

クライアントサイド(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 を試したいと思います(顧客管理から、ログイン、自動決済、振り込み等、顧客管理からログイン周りまでお願いできるもの)。

参考

リファレンス

うかい / 株式会社UKAI
うかい@代表取締役兼エンジニア株式会社UKAI
Nobuyuki Ukai

株式会社UKAI 代表取締役CEO。建築を専攻していたが、新卒でYahoo!Japanにエンジニアとして入社。その後、転職、脱サラ、フリーランスエンジニアを経て、田舎へ移住し、ゲストハウスの開業、法人成り。ゲストハウス2軒、焼肉店、カフェ、食品製造業を運営しています。詳細はこちらから

🙏よかったらシェアお願いします🙏
WRITTEN BY
うかい / 株式会社UKAI
うかい@代表取締役兼エンジニア株式会社UKAI

Nobuyuki Ukai

株式会社UKAI 代表取締役CEO。建築を専攻していたが、新卒でYahoo!Japanにエンジニアとして入社。その後、転職、脱サラ、フリーランスエンジニアを経て、田舎へ移住し、ゲストハウスの開業、法人成り。ゲストハウス2軒、焼肉店、カフェ、食品製造業を運営しています。詳細はこちらから

CONACT
入力して下さい
Slack からもどうぞ

※お気軽にどうぞ!(6月20日まで有効!お早めに)

COPYRIGHT © 2020 UKAI CO., LTD. ALL RIGHTS RESERVED.