Vue.jsでStripeを用いて決済処理を実装しています。
(今回の質問には関係ないかと思いますが、サーバー側はLaravel8系)
Stripeのフォームをモーダルで表示させるところまではうまく行きましたが、
そこから先、axiosをやる前でエラーが出てしまいます。
order_checkの「クレジットカード」をクリックすると↓
クレジットカード入力フォームが出て(Stripe.jsで実装)、お支払をクリックでaxios送信したいのですが、その前でエラーが出ます。
以下、コードです。
■ShopOrderCheck.vue (order_checkページのVueコンポーネント。)
Stripeフォーム用コンポーネントの親コンポーネント
<template> <div> <main class="page-form"> <div class="bg-secondary-lighten-1 py-10"> <div class="container"> <div class="grouping shadow-md mb-6 md:w-10/12 max-w-screen-sm mx-auto"> <div class="flex items-center"> <div class="w-7/12"> <h3 class="font-bold text-lg">{{ product.name }}</h3> </div> </div> <form class="form form--check" action="../epsilon/order_ep.php" method="POST" id="order_form"> <div class="form__group"> <label class="form__label">メールアドレス</label> <div> <div>{{ request.buy_email }}<p style="color:#D31004;" class="text-sm">※正しいメールアドレスかをご確認ください。</p></div> </div> </div> <div class="form__group"> <label class="form__label">名前</label> <div> <div>{{ request.buy_name }}<p style="color:#D31004;" class="text-sm">※ご入力いただいたお名前で領収書を発行いたします。</p></div> </div> </div> <div class="form__group"> <label class="form__label">名前フリガナ</label> <div> <div>{{ request.buy_namekana }}</div> </div> </div> </form> <div class="mt-8" v-if="request.payment_method == 1"> <button type="button" class="form__button w-full button " id="order_card" @click="show">クレジットカード</button> </div> <div class="mt-8" v-else> <button type="button" class="form__button w-full button" id="order_bank">銀行振込</button> </div> </div> </div> </div> </main> <stripe-card :product="product" :request="request" :public_key="send_public_key" :csrf = "csrf" ></stripe-card> </div> </template> <script> export default { props: { csrf: { type: String, }, product: { type: Object, }, request: { type: Object }, public_key: { type: Object, } }, data() { return { errors: [], send_public_key: this.public_key.value, } }, mounted() { console.log(this.public_key.value); }, computed: { getPaymentMethod: function() { if(this.request.payment_method == 1) { return "クレジットカード"; } else { return "銀行振込"; } }, }, methods: { show : function() { this.$modal.show('stripe-card'); }, hide : function () { this.$modal.hide('stripe-card'); }, regist: function() { }, }, } </script>
■問題のStripe用クレジットカードフォームの子コンポーネント StripeCard.vue
<template> <modal name="stripe-card" @opened="setupStripe"> <div> <input type="hidden" name="_token" v-bind:value="this.csrf"> <label for="exampleInputEmail1">カード名義</label> <input type="test" class="form-control col-sm-5" id="card-holder-name" required v-model="Form.cardHolderName"> <label for="exampleInputPassword1">カード番号</label> <div class="form-group MyCardElement col-sm-5" id="card-element"></div> <div id="card-errors" role="alert" style='color:red'></div> <button class="btn btn-primary" id="card-button" @click="regist" >お支払</button> </div> </modal> </template> <script> import {loadStripe} from '@stripe/stripe-js'; export default { props: { product: { type: Object, }, request: { type: Object, }, public_key: { type: String, }, csrf: { type: String, } }, data() { return { stripe: null, stripeCard: null, Form: { cardHolderName: null, }, } }, methods: { setupStripe: async function() { this.stripe = await loadStripe(this.public_key); const elements = this.stripe.elements(); var style = { base: { color: "#32325d", fontFamily: '"Helvetica Neue", Helvetica, sans-serif', fontSmoothing: "antialiased", fontSize: "16px", "::placeholder": { color: "#aab7c4" } }, invalid: { color: "#fa755a", iconColor: "#fa755a" } }; this.stripeCard = elements.create('card', {style: style, hidePostalCode: true}); this.$nextTick(() => { this.stripeCard.mount('#card-element'); }); this.stripeCard.on('change', function(event) { var displayError = document.getElementById('card-errors'); if (event.error) { displayError.textContent = event.error.message; } else { displayError.textContent = ''; } }); }, regist: function() { console.log(this.request.product_id); //consoleに表示される console.log(this.product.id); //consoleに表示される this.stripe.createToken(this.stripeCard,{name: document.querySelector('#card-holder-name').value}).then(function(result) { if(result.error) { //エラーの処理 alert("エラー発生"); } else { //成功の処理 alert(result.token.id); //alertで出力される console.log(this.request.product_id); //★表示されない const url = '/shop/order_stripe'; let params = new FormData(); params.append('product_id', this.request.product_id); params.append('buy_address', this.request.buy_address); params.append('buy_address2', this.request.buy_address2); params.append('buy_email', this.request.buy_email); params.append('buy_name', this.request.buy_name); params.append('buy_namekana', this.request.buy_namekana); params.append('buy_num', this.request.buy_num); params.append('buy_phone', this.request.buy_phone); params.append('buy_post', this.request.buy_post); params.append('getinfo', this.request.getinfo); params.append('payment_method', this.request.payment_method); params.append('stripe_token', result.token.id); axios.post(url, params, { headers: { 'Content-Type': 'application/x-www-form-urlencode', } }) .then(response => { //console.log(this.request.product_id); /* if(response.data == 1) { alert("購入しました"); //location.href= ''; } else { alert(response.data); } */ }); } }); }, }, } </script>
いくつかテスト用にconsole.logをしています。
methodの中のregist関数直後の
console.log(this.request.product_id); console.log(this.product.id);
はconsoleに表示されますが、this.stripe.createTokenのthenの中、成功の処理のconsole.log(this.request.product_id);は表示される以下のエラーが出てしまいます。
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'request')
同じrequest関数中なのに、エラーになってしまうのかがわかりません。。。thenの中だからでしょうか…(Javascript初心者です)
アドバイスいただけますと幸いです。
何卒、よろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/09/25 09:49