Rodrigo Villalobos
Rodrigo Villalobos

Reputation: 197

Why these async/await calls are not working properly?

Help please!! During the execution of both await calls in createPayment() and in stripe API charges.create() the execution is made randomly not in order as expected. My code enters into createPayment() then goes back to const {payment} = await createPayment(program, user, toUser, paymentToken); then goes inside createPayment() again, it makes no sense!!!!

exports.subscribeToProgram = async function(req,res){
try {
    const {paymentToken, program} = req.body;
    const user = res.locals.user;

    //Find program to be subscribed
    const foundProgram = await Program.findOne({_id: program._id}).populate('user').exec();
    const toUser = foundProgram.user.id;
    if(toUser === user.id)
    {
        return res.status(422).send({errors: [{title: 'Invalid User!', detail: 'You can\'t subscribe to your own program!'}]})
    }

    // Create Payment
    // THIS PART IS NOT WORKING PROPERLY!!!! 
    const {payment} = await createPayment(program, user, toUser, paymentToken);
    const charge = await stripe.charges.create({
        amount: foundProgram.price * 100 * CUSTOMER_SHARE,
        currency: 'usd',
        description: 'Example charge',
        source: payment.tokenId,
    });

    //If payment was created successfully
    if(payment && charge)
    {
        //Create subscription
        //Save created subscription
        //Append a booking to bookings array
    }else{
        return res.status(422).send({errors: [{title: 'Payment declined!', detail: err }]})
    }
} catch (err) {
    console.log(err)
    return res.status(422).send(err);  
}
}

CreatePayment()

async function createPayment(program, user, toUser, token){
//Get user from booking
const userToCharge  = user;

//Create customer from stripe serices
const customer = await stripe.customers.create({
    source: token.id,
    email: userToCharge.email
});

//If custome exist
if(customer)
{
    //Update user
    User.updateOne({_id: userToCharge.id}, {$set: {stripeCustomerId: customer.id}}, () => {});

    //Create Payment
    const payment = new Payment({
        fromUser: userToCharge,
        toUser, //Destructurize value
        fromStripeCustomerId: customer.id,
        program,
        tokenId: token.id,
        amount: program.price * 100 * CUSTOMER_SHARE // 80% of value if for 
    });

    //Save payment
    try 
    {
        const savedPayment = await payment.save();
        return {payment: savedPayment}
    } 
    catch (error) 
    {
        return {err: err.message};
    }
}else{
    return { err: 'Cannot process Payment!'}
}

}

Upvotes: 0

Views: 1184

Answers (1)

James
James

Reputation: 82096

Two issues, both inside createPayment

  1. You need to await the User.updateOne call as this is also asynchronous
  2. In the event of no customer being found, you will still need to return an object, otherwise your destructuring will throw an error.

Upvotes: 2

Related Questions