質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Stripe

Stripeとは、米国のオンライン決済システム提供企業、及び同社が提供する決裁システムを指します。Webサイトやモバイルアプリにコードを組み込むことでクレジットカードなどの決済サービスが簡潔に追加できます。

Nuxt.js

Nuxt.jsは、ユニバーサルなSPAが開発可能なVue.jsベースのフレームワーク。UIの描画サポートに特化しており、SSRにおけるサーバーサイドとクライアントサイドのUIレンダリングなどさまざまな機能を持ちます。

Q&A

解決済

1回答

795閲覧

Stripeでのサブスクリプション作成が上手くできません

Khy

総合スコア118

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Stripe

Stripeとは、米国のオンライン決済システム提供企業、及び同社が提供する決裁システムを指します。Webサイトやモバイルアプリにコードを組み込むことでクレジットカードなどの決済サービスが簡潔に追加できます。

Nuxt.js

Nuxt.jsは、ユニバーサルなSPAが開発可能なVue.jsベースのフレームワーク。UIの描画サポートに特化しており、SSRにおけるサーバーサイドとクライアントサイドのUIレンダリングなどさまざまな機能を持ちます。

0グッド

0クリップ

投稿2020/04/29 09:20

Nuxt.js、firebase cloud functions、Stripeでサブスクリプション決済の機能を作成中で、2点質問したいことがございます。

質問1

顧客情報を生成してからサブスクリプションの生成をしたいのですが、顧客の生成前にサブスクリプション生成のコードが実行されてしまい、エラーとなってしまいます。
以下のコードで言うと、★★★1のところでは生成した顧客IDが確認できますが、★★★2では空白になっています。

async/awaitを使用して顧客を作成したのち、サブスクリプションを生成しているつもりなのですが、async/awaitの使い方が間違っておりますでしょうか?

質問2

★★★2のところで試しにcustomerId = 'xxxxxxxxxxxxxxxx'と直接IDを指定すると無事にサブスクリプションが作成されました。
しかし、★★★3のところでres.okがfalseになっており、フロント側では生成が失敗しているように見えてしまいます。
こちらは何が原因でしょうか?

js

1 2// functions/index.js 3 4const charge = async (request, response) => { 5 const stripe = new Stripe(functions.config().stripe.token) 6 7 const body = JSON.parse(request.body) 8 const token = body.token.id 9 const email = body.email 10 11 let customerId = '' 12 13 // 顧客を作成 14 await stripe.customers.create( 15 { 16 email: email, 17 source: token, 18 description: description 19 }, 20 function(err, res) { 21 if (err) { 22 console.error(err) 23 } 24 console.log('customer ID1: ', res.id) // ★★★1. IDを取得できていることを確認済み 25 customerId = res.id 26 } 27 ) 28 29 console.log('customer ID2: ', res.id) // ★★★2. ここでは値が空白になっている 30 31 // Subscriptions を作成 32 stripe.subscriptions.create( 33 { 34 customer: customerId, 35 items: [{ plan: 'plan_HArFYxS5axxgmPl' }] 36 }, 37 (err, subscription) => { 38 if (!err && subscription) { 39 return done(null, { my_msg: 'OK' }) 40 } else { 41 return done(null, { message: JSON.stringify(err, null, 2) }) 42 } 43 } 44 ) 45} 46 47exports.charge = functions 48 .region(REGION) 49 .https.onRequest((request, response) => { 50 const CORSRequestHandler = CORS({ origin: true }) 51 CORSRequestHandler(request, response, () => { 52 if (request.method !== 'POST') { 53 send(response, 405, { error: 'Invalid Request' }) 54 } 55 try { 56 charge(request, response) 57 } catch (e) { 58 console.log(e) 59 send(response, 500, { 60 error: `The server received an unexpected error. Please try again and contact the site admin if the error persists.` 61 }) 62 } 63 }) 64 })

vue

1<script> 2import { mapGetters } from 'vuex' 3import { db } from '@/plugins/firebase' 4 5const stripe = Stripe('pk_test_BGKBSXtRPT9rFB9PKwafgTaW7xxLXmuTDe') 6const elements = stripe.elements() 7const style = { 8 base: { 9 color: '#333' 10 } 11} 12const cardNumber = elements.create('cardNumber', { style }) 13const cardExpiry = elements.create('cardExpiry', { style }) 14const cardCvc = elements.create('cardCvc', { style }) 15 16export default { 17 data() { 18 return { 19 email: '' 20 } 21 }, 22 computed: { 23 ...mapGetters(['user', 'uid']) 24 }, 25 26 mounted() { 27 cardNumber.mount('#card-number') 28 cardExpiry.mount('#card-exp') 29 cardCvc.mount('#card-cvc') 30 }, 31 32 methods: { 33 // Stripeのトークンを作成する処理 34 async createStripeToken() { 35 await stripe.createToken(cardNumber).then(async (result) => { 36 if (result.error) { 37 // エラー表示. 38 const errorElement = document.getElementById('card-errors') 39 errorElement.textContent = result.error.message 40 this.loading = false 41 } else { 42 // トークンをサーバに送信 43 const res = await this.stripeTokenHandler(result.token) 44 console.log('結果: ', res) 45 if (res) { 46 db.collection('users') 47 .doc(this.uid) 48 .update({ premium: true }) 49 } else { 50 alert('エラー発生') 51 } 52 } 53 }) 54 }, 55 56 // トークンをサーバーに送信する処理 57 async stripeTokenHandler(token) { 58 const url = 59 'https://asia-northeast1-example.cloudfunctions.net/charge' 60 61 console.log('token: ', token) 62 63 const res = await fetch(url, { 64 method: 'POST', 65 mode: 'no-cors', 66 body: JSON.stringify({ 67 token, 68 email: this.email   69 }) 70 }) 71 console.log(res) // ★★★3. サブスクリプションが無事に生成されていても、ここでresをみてみるとres.ok: falseが入っている 72 if (res.ok) { 73 console.log('ok') 74 return true 75 } else { 76 return false 77 } 78 } 79 } 80} 81</script>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

他に問題がありました。

投稿2020/04/30 18:40

Khy

総合スコア118

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問