0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

MTで商品購入ページを作ってみた

Last updated at Posted at 2022-12-17

この記事は 「Movable Type Advent Calendar 2022」、18日目の記事です。

他の方の記事も読むと勉強になるし、楽しいのでぜひ読んでみてください。

今回は記事をqiitaで書いてますが、実は こちら に自分のブログをgatsbyを使って書いてあるブログがあります。
去年までは書いていたはずで、今年もブログを書こうとしたところ、ソースが行方不明。。。
publicの下だけサーバに残っている状態で、自分のPCを検索するも見つからず、githubにもそれらしきリポジトリはなく。。。
これを書いている最中ですが、心が折れている状態です。

気を取り直して今回のテーマについて書いていきます。

MTで商品購入ページ作りたいんだよね

  • モールとかの使い方を覚えるのは嫌だし、商品数も多くない
  • ある程度商品ページをオリジナルでデザイン性のあるものを作りたい
  • 売れるかどうかもわからないので、毎月お金がかかるようなことはしたくない
  • ECサイトを自分で構築したり、サーバー管理したりするのは面倒(心配)
  • MTでサイトとまとめて管理したい

たまにこういう要望をいただくことがあり、今まではこんな形で提案しておりました。

  • 「Baseっていう素敵なプロダクトがあります」
  • 「Yahooショッピングであれば月額費用などはかからず、売れた時の手数料だけです」

そんな中、下記のページをたまたま読むことがあって、以前stripeであれば使ったことがあるし、実験的に実装してみようということで、ノリと勢いだけで実装してみました。
Vue Stripe

vueやvue-stripeのインストール

まずはnpmでvueとvue-stripeをインストール。yarn使いたい人は読み替えてください。

$ npm install -g @vue/cli
$ npm install @vue-stripe/vue-stripe

サンプルプロジェクトの作成

プロジェクトの雛形を作成します。

$ vue create hello-stripe
 or 
$ vue ui

今回初めてuiというものを実行してみたのだけれど、インストーラーみたいな画面が立ち上がって入力するだけで簡単にプロジェクトの雛形が作れました。
あとプロジェクトの設定とかも画面から変えれたりするみたい。cliのほうが慣れれば楽だけど、最初はここからでもいいかもしれません。

サンプルコードの作成

vue-stripeのページを参考に、ボタンを実装してみます。

サンプルコードを表示
App.vue
<template>
  <div>
    <stripe-checkout
      ref="checkoutRef"
      mode="payment"
      :pk="publishableKey"
      :line-items="lineItems"
      :success-url="successURL"
      :cancel-url="cancelURL"
      @loading="v => loading = v"
    />
    <button @click="submit">購入手続きへ進む</button>
  </div>
</template>

<script>
import { StripeCheckout } from '@vue-stripe/vue-stripe';
export default {
  components: {
    StripeCheckout,
  },
  data () {
    this.publishableKey = process.env.STRIPE_PUBLISHABLE_KEY;
    return {
      loading: false,
      lineItems: [
        {
          price: 'some-price-id', // The id of the one-time price you created in your Stripe dashboard
          quantity: 1,
        },
      ],
      successURL: 'https://localhost:8080/',
      cancelURL: 'https://localhost:8080/',
    };
  },
  methods: {
    submit () {
      // You will be redirected to Stripe's secure checkout page
      this.$refs.checkoutRef.redirectToCheckout();
    },
  },
};
</script>

some-price-id ・・・ Stripe上で作成した商品のAPIIDを貼り付ける
successURL ・・・ 決済完了後に戻ってくる画面。サンプルなのでとりあえずlocalhost
cancelURL ・・・ 決済画面から戻るで表示される画面。サンプルなのでとりあえずlocalhost
publishableKey ・・・ Stripe上の開発者>APIキー>公開可能キーを設定。.env.developmentに書く

.env.developmentの作成

プロジェクト直下に.env.developmentファイルを作成。
Stripeはテストモードという便利なモードがあって、テスト用の決済ができたり、決済を失敗させたりするテストができるモードがあります。
テストモードの時にはAPI公開可能キーがpk_test_から始まります。もし違ったら本番公開になってしまっているのでテストモードにしてからAPIキーなど取得しなおしてください。

VUE_APP_STRIPE_PUBLISHABLE_KEY=pk_test_xxxxx

サンプルの実行

$ npm run serve

実行すると、サーバが立ち上がり以下画面が表示されます。

購入ボタンしかない寂しい画面が立ち上がりました。
購入手続きへ進むをクリックすると、Stripeが用意した決済ページへ飛びます。

左上にTEST MODEと書いてあることを確認してください。
これはテストモードで実行していて実際の決済などは発生しないよということになります。
ここで、クレジットカードの入力のテストをしてみましょう。
テストモードでは、テストで使えるカード番号を利用して決済を行います。
テスト用カード

支払いがかならず拒否される番号などもあるので、いつもできない分、色々とテストしてみると面白いです。

MTで商品ページを作ってみる

さて、Movable Type Advent CalendarなのにまったくMTの話がでてこなくてすみません。ここからがMTのお話しです。
とはいえ、上のソースでやりたいことはできてしまっているので、あとはMTでデータを入れる部分と表示する部分だけになります。

今回は極力簡単なサンプルにしたかったため、手抜きモードでお送りします。
手順はこのような形です。

  1. 商品コンテンツタイプを作成
  2. コンテンツタイプテンプレート作成
  3. js側のソースを修正してアップロード
  4. 商品コンテンツタイプにデータを追加

商品コンテンツタイプを作成

実際はもっと考えて項目も増えると思いますが、今回は最低限ということで以下のようにしました。

コンテンツタイプテンプレートを作成

ここも今回はサンプルのため、抜けるところは極力手を抜いてみました。
bootstrap入れてとりあえず簡単に整えたというところです。

コンテンツタイプテンプレートを表示
*コンテンツタイプテンプレート.
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
  <script defer="defer" src="/assets/js/chunk-vendors.js"></script>
  <script defer="defer" src="/assets/js/app.js"></script>
</head>
<body>
   <div class="container">
    <section class="item text-center">
      <h4 id="item_name"><mt:ContentField content_field="商品名"><$mt:ContentFieldValue$></mt:ContentField></h4>
      <div id="item_image"><mt:ContentField content_field="商品画像"><img src="<$mt:AssetURL$>" alt="" class="img-fluid" width="300"></mt:ContentField></div>
      <div id="item_description"><mt:ContentField content_field="商品説明"><$mt:ContentFieldValue$></mt:ContentField></div>
      <div id="item_price" class="mb-3"><mt:ContentField content_field="販売価格(税込)"><$mt:ContentFieldValue numify="1"$>円(税込)</mt:ContentField></div>
      <p style="display: none;" id="item_id"><mt:ContentField content_field="StripeID"><$mt:ContentFieldValue$></mt:ContentField></p>
      <div id="app"></div>
    </section>
  </div>
</body>
</html>

js側のソースを修正してアップロード

some-price-idの部分がMTから登録したデータ(StripeIDフィールド)を使いたいので、下記の様に変更しました。
successURLcancelURLは手抜きしてlocationから取得してます。

サンプルコードを表示
App.vue
<template>
  <div>
    <stripe-checkout
      ref="checkoutRef"
      mode="payment"
      :pk="publishableKey"
      :line-items="lineItems"
      :success-url="successURL"
      :cancel-url="cancelURL"
      @loading="v => loading = v"
    />
    <button @click="submit">購入手続きへ進む</button>
  </div>
</template>

<script>
import { StripeCheckout } from '@vue-stripe/vue-stripe';
export default {
  components: {
    StripeCheckout,
  },
  data () {
    this.publishableKey = process.env.VUE_APP_STRIPE_PUBLISHABLE_KEY;
    return {
      loading: false,
      lineItems: [
        {
          price: '',
          quantity: 1,
        },
      ],
      successURL: '',
      cancelURL: '',
    };
  },
  mounted() {
    window.onload = ()=>{
      this.lineItems[0].price = document.getElementById('item_id').textContent;
      this.successURL = document.location.href;
      this.cancelURL = document.location.href;
      
    }
  }
  methods: {
    submit () {
      // You will be redirected to Stripe's secure checkout page
      this.$refs.checkoutRef.redirectToCheckout();
    },
  },
};
</script>

さて、この状態でビルドして、MTのサイト側にjsをアップロードします。
ビルドするときにキャッシュ対策でハッシュがついてしまうので、configでfilenameHashingfalseにします。

サンプルコードを表示
vue.config.js
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  filenameHashing: false,
  devServer: {
    https: true
  }
})

この状態でbuildしてみます。

$ npm run build

そうすると、プロジェクトの下にdist/js/app.jschunk-vendors.jsが出来上がるので、サイトの/asset/js/でアクセスできるようにアップロードします。

商品コンテンツタイプにデータを追加

ここまできたら後一息。実際に商品を追加してみましょう。
商品はStripe側にも情報が必要となるため、Stripe側でも商品と値段を設定します。
Stripeにログインし、商品 -> 「+商品を追加」をクリックし、商品名、値段などを設定します。
登録が終わったら、画面上にあるAPI IDというprice_からはじまるIDをコピーします。

MTの管理画面に戻り、商品情報を入力します。
その際、StripeIDというところに、上記でコピーしたprice_からはじまるIDを入力します。

実際に表示してみましょう

下記のような画面が表示され、購入手続きへ進むのボタンを押すと決済ページに遷移します。


MTからコンテンツを追加すれば、それをきっかけにStripeAPIなどを通して商品が追加されたりするともっといいのでしょうが、ちょっと時間がなかったのでその辺りはいずれ試してみようかと思ってます。

まだまだ課題は山積みではありますが、簡単にクレジットカード決済などが導入できるようにするというところまででした。

モヤモヤしている方は、ぜひ続きの実装や追加の実装を試してみてください!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?