Yak shaving logs


My life is just yak shaving.

PAY.JPのチェックアウトのスクリプトをVue.jsのSPAで実装する

2018/06/29 #vue.js #pay.jp #SPA

By Yusuke Takita


こんにちは。Kajitz inc.の瀧田です。

クレジットカード情報の入力フォームは、課金に直結するのでできるだけリッチに作成したいですよね。
ただ、PAY.JPのチェックアウトのスクリプトはSPAだと動かないかもねと書かれており、実際に動かなかったので対応方法をまとめます。

  • PAY.JPの注意書き
注意事項
チェックアウトは、HTMLドキュメントの読み込みを起点として決済フォームを構築するため、各種のシングルページアプリケーションフレームワークやRuby on Railsのturbolinks機能など、 通常の画面遷移やドキュメント読み込みとは違う方法を利用する場合に、正しく表示されないことがあります。 この場合は payjp.js を利用して決済フォームをご用意いただくことをご検討ください。

refs: Checkout | PAY.JP

PAY.JPのチェックアウトボタンが消えてしまう

コンポーネント化してくれてるのがあるやないかということで、以下を使って実装してみます。
実装したのはいいものの、リロードやページ遷移を挟むとPAY.JPのクレジットカード情報を入力するモーダルを表示するボタンが消えてしまいます・・・

GitHub - ngs/vue-payjp-checkout: PAY.JP Checkout Button component for Vue.js

Vue.jsのすごくできる方(名前だしていいかわからないのでIDとか伏せます)に相談してみたところ、
この問題が解決しました。

以下を参考にして対応してくださりました。

PAY.JP の Checkout 用の React.js コンポーネント · GitHub

Reactの実装例を用いて修正してみる

ボタンが消える問題が解決した後に、以下のようにsubmit時にエラーが出るという問題に遭遇しましたが、2つ目のsetTimeoutで解決しました。と言ってもgistを参考にさせていただいたのですが・・・
setTimeoutのところはもう少しいい感じにしたいですね。

https://gyazo.com/853c10aa4fd9470fec65f5fc073d2672

<template>
// 省略
        <tr>
          <td>決済方法</td>
          <td>クレジットカード</td>
          <td>
            <div ref="payjpArea"></div>
          </td>
        </tr>
// 省略
</template>

<script>
// 省略
export default {
// 省略
  created () {
    // HTML描画を待って要素をappendしたい
    setTimeout(() => {
      this.appendPayJpScriptTag()
    }, 1000)

    // appendPayJpScriptTagでscriptタグをappendとpayjpのscript実行後に処理したい
    setTimeout(() => {
      window.onTokenCreated = this.onTokenCreated
      window.onTokenFailed = this.onTokenFailed
    }, 1000)
  },
  beforeDestroy () {
    const payjpCheckoutIframeEl = document.getElementById('payjp-checkout-iframe')
    payjpCheckoutIframeEl.parentElement.remove()
    this.$refs.payjpArea.removeChild(this.scriptEl)
    window.PayjpCheckout = null
    window.onTokenCreated = null
    window.onTokenFailed = null
  },
  methods: {
    appendPayJpScriptTag () {
      const attrs = {
        'id': 'payjp-script',
        'src': 'https://checkout.pay.jp/',
        'class': 'payjp-button',
        'data-key': 'pk_test_d4b1a4668323c8ce49ab7ec5',
        'data-partial': false,
        'data-text': 'カード情報を入力する',
        'data-submit-text': '支払い',
        'data-lang': 'ja',
        'data-on-created': 'onTokenCreated',
        'data-on-failed': 'onTokenFailed',
        'data-name-placeholder': 'YAMADA TARO'
      }
      this.scriptEl = document.createElement('script')
      _.forEach(attrs, (v, k) => {
        this.scriptEl.setAttribute(k, v)
      })
      this.$refs.payjpArea.appendChild(this.scriptEl)
    },
    onTokenCreated () {
      const token = document.getElementsByName('payjp-token')
      // 処理
    },
    onTokenFailed (res) {
      // 処理
    }
  }
}
</script>
このエントリーをはてなブックマークに追加

categories


最新記事


tags