Ошибка при создании платежного намерения для Stripe с Firebase в NodeJS - PullRequest
0 голосов
/ 09 апреля 2020

Я пытаюсь создать платежное намерение Stripe в NodeJS с помощью Firebase. Серверная функция получает JSON из моего приложения iOS, правильно извлекает продукт и получает цену продукта (что подтверждается правильными значениями в консоли), но на самом последнем шаге не передает значение цены правильно.

Вот ошибка, которую я получаю в консоли Firebase:

Error: Invalid integer: {:domain=>{:domain=>"", :_eventsCount=>"1"}}
    at Function.generate (/srv/node_modules/stripe/lib/Error.js:38:16)
    at IncomingMessage.res.once (/srv/node_modules/stripe/lib/StripeResource.js:175:33)
    at Object.onceWrapper (events.js:313:30)
    at emitNone (events.js:111:20)
    at IncomingMessage.emit (events.js:208:7)
    at endReadableNT (_stream_readable.js:1064:12)
    at _combinedTickCallback (internal/process/next_tick.js:139:11)
    at process._tickDomainCallback (internal/process/next_tick.js:219:9)

А вот код:

// New Stripe Payment Intent
const newPaymentIntent = express();
newPaymentIntent.use(bodyParser.urlencoded({ extended: true }));
newPaymentIntent.post('/', (req, res) => { createPaymentIntent(req, res); });
function paymentIntent(req, res) { }
exports.paymentIntent = functions.https.onRequest(newPaymentIntent);

const calculateOrderAmount = items => {
    let price = admin.database().ref('/productAds').orderByChild('code').equalTo(items['code']).once('value').then((snapshot) => {
            var productPrice = 99;

            snapshot.forEach((childSnapshot) => {
          var childData = childSnapshot.val();

                productPrice += childData.price;
                console.log(childData.price);
        });

            console.log(productPrice);
            return productPrice;
    });

    return price;
};

// Create Stripe Customer
async function createPaymentIntent(req, res) {
  const { items, currency } = req.body;

    const paymentIntent = await stripe.paymentIntents.create({
      amount: calculateOrderAmount(items),
      currency: 'aud',
    });
    const clientSecret = paymentIntent.client_secret

    // Send publishable key and PaymentIntent details to client
  res.send({
    publishableKey: 'pk_test_ikLVo1vJSDi89gcfwMiBTDDw',
    clientSecret: clientSecret
  });
}

Есть какие-либо предложения о том, что я делаю неправильно?

Ответы [ 2 ]

1 голос
/ 09 апреля 2020

Ваша функция calculateOrderAmount не возвращает число. Он возвращает обещание, которое разрешится со значением, возвращенным функцией, которую вы передали then.

. Вы должны использовать другой then, чтобы дождаться окончательного значения, и только затем вызывать API полосы. Или используйте asyn c. (Если у вас есть возможность использовать asyn c, вам, вероятно, следует также использовать его в вашей функции calculateOrderAmount вместо then, так как это будет легче читать и рассуждать.)

0 голосов
/ 10 апреля 2020

Так что Даг был прав. Я отредактировал код, включив в него функции asyn c, и теперь он работает без нареканий. Вот как выглядит окончательный код:

// Retrieve product code from Firebase
async function getDataFromFirebase(items) {
	const objects = await admin.database().ref('/productAds').orderByChild('code').equalTo(items['code'])
	const data = await objects.once('value');
	return data;
}

async function getPrice(items) {
	console.log('Executing getPrice method.');
	var resultPrice = 0;

  // we wait for the axios.get Promise to be resolved
	const objects = await getDataFromFirebase(items);

	objects.forEach((childSnapshot) => {
		var childData = childSnapshot.val();
			resultPrice += childData.price;
	});

	console.log('Price is: ' + resultPrice);
  // we then return the data, just like we did in the callback-based version!
  return resultPrice;
}

// Create Stripe Customer
async function createPaymentIntent(req, res) {
  const { items, currency } = req.body;
    const paymentIntent = await stripe.paymentIntents.create({
      amount: await getPrice(items),
      currency: 'aud',
    });
    const clientSecret = paymentIntent.client_secret

    // Send publishable key and PaymentIntent details to client
  res.send({
    publishableKey: 'pk_test_ikLVo1vJSDi89gcfwMiBTDDw',
    clientSecret: clientSecret
  });
}
...