Функции чередования, возвращающие вызовы после завершения функции - PullRequest
0 голосов
/ 15 апреля 2020

Относительно плохо знаком с Javascript, однако я пытаюсь работать со Stripe и обойтись с пользователем, который отправляет другой способ оплаты, а затем оплачивает счет этим методом. если платеж снова не удастся - он должен полностью удалить подписку. Я использую базу данных Firebase Realtime с GCF & Node.js 8.

Вот что у меня есть до сих пор

exports.onSecondPaymentAttempt = functions.database.ref("users/{userId}/something/somethingHistory/{subDbId}/newPayment").onCreate((snapshot, context)=>{
var s = snapshot.val();
var fields = s.split(",");
const cardToken = fields[0];
const cus_id = fields[1];
const conn_id = fields[2];
const subDbId = context.params.subDbId;
const userId = context.params.userId;
return stripe.customers.createSource(
    cus_id,
    {source: cardToken},{
        stripeAccount: `${conn_id}`,
      },
  (err, card)=> {
    console.log(err); 
    if(err){
        return console.log("error attaching card "+ err)
    }else{
        const invoiceNo = admin.database().ref(`users/${userId}/something/somethingHistory/${subDbId}`)
        return invoiceNo.once('value').then(snapshot=>{
        const invoiceNumber = snapshot.child("invoiceId").val();
        const subId = snapshot.child("subscriptionId").val();
        return stripe.invoices.pay(
        invoiceNumber,
        {
      expand: ['payment_intent','charge','subscription'],
        },{
            stripeAccount: `${conn_id}`,
          },
          (err, invoice)=>{
              if(err){
                return console.log("error paying invoice "+ err)
              }else{
                if(invoice.payment_intent.status==="succeeded"){
              //DO SOME CODE
                return console.log("New Payment succeeded for "+invoiceNumber)
            }else{
             //DO SOME OTHER CODE

            //CANCEL 
            return stripe.subscriptions.del(
                subId,{
            stripeAccount: `${conn_id}`,
             },
            (err, confirmation)=> {
                if(err){
                    return console.log("Subscription error")
                }else{
                         return console.log("Subscription cancelled")
                }
             });
              }
              }
          });
})
    }
});

Для меня это выглядит невероятно неэффективным / уродливым способом достижения Эффект и в целом пользователь сидит в ожидании ответа в течение приблизительно 15 секунд, хотя функция завершает свое выполнение после 1862 мс - я все еще получаю ответы в течение 5 - 10 секунд после.

Какой наиболее эффективный способ достижения того же желаемого эффекта заключается в регистрации нового источника платежа, оплате подписки и последующей обработке результата этого платежа?

1 Ответ

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

Вы должны использовать обещания, возвращаемые асинхронными методами Stripe, следующим образом (непроверенные, возможно, требуется некоторая тонкая настройка, в частности, с объектами, передаваемыми в методы Stripe):

exports.onSecondPaymentAttempt = functions.database.ref("users/{userId}/something/somethingHistory/{subDbId}/newPayment").onCreate((snapshot, context) => {
    var s = snapshot.val();
    var fields = s.split(",");
    const cardToken = fields[0];
    const cus_id = fields[1];
    const conn_id = fields[2];
    const subDbId = context.params.subDbId;
    const userId = context.params.userId;


    return stripe.customers.createSource(
        //Format of this object to be confirmed....
        cus_id,
        { source: cardToken },
        { stripeAccount: `${conn_id}` }
    )
        .then(card => {
            const invoiceNo = admin.database().ref(`users/${userId}/something/somethingHistory/${subDbId}`)
            return invoiceNo.once('value')
        })
        .then(snapshot => {
            const invoiceNumber = snapshot.child("invoiceId").val();
            const subId = snapshot.child("subscriptionId").val();
            return stripe.invoices.pay(
                invoiceNumber,
                { expand: ['payment_intent', 'charge', 'subscription'] },
                { stripeAccount: `${conn_id}` }
            )
        })
        .then(invoice => {

            if (invoice.payment_intent.status === "succeeded") {
                //DO SOME CODE
                console.log("New Payment succeeded for " + invoiceNumber)
                return null;
            } else {
                //DO SOME OTHER CODE

                //CANCEL 
                return stripe.subscriptions.del(
                    subId, {
                    stripeAccount: `${conn_id}`,
                });
            }

        })
        .catch(err => {
            //....
            return null;
        })

});

Я бы посоветовал вам посмотреть три видео о "JavaScript Promises" из официального Firebase видео-сериала , в которых объясняется, почему это ключ к правильной цепочке , и вернуть обещания, возвращенные асинхронные методы.

...