Search code examples
node.jsasync-awaitstripe-payments

Error in Node.JS file for integrating Stripe payments in backend


I'm getting an error on this line in my server.js Node file - "const calculation = await stripe.tax.calculations.create({", the error is "await is only valid in async function". Below is the codes of my server.js file

const stripe = require('stripe')('sk_test_');
const express = require('express');
const app = express();

app.use(express.json());

const calculation = await stripe.tax.calculations.create({
  currency: 'usd',
  line_items: [
    {
      amount: 1000,
      reference: 'L1',
      tax_code: 'txcd_99999999',
    },
  ],
  customer_details: {
    address: {
      line1: '920 5th Ave',
      city: 'Seattle',
      state: 'WA',
      postal_code: '98104',
      country: 'US',
    },
    address_source: 'shipping',
  },
});

app.post('/prepare-payment-sheet', async (req, res) => {
try {
    const customer = await stripe.customers.create();
    const ephemeralKey = await stripe.ephemeralKeys.create({customer: customer.id},
                                                           {apiVersion: '2024-06-20; payment_intent_with_tax_api_beta=v1;'});
    const paymentIntent = await stripe.paymentIntents.create({
        amount: 1099,
        currency: 'usd',
        customer: customer.id,
        automatic_payment_methods: {
            enabled: true,
        },
        async_workflows: {
            inputs: {
                tax: {
                calculation: '{{CALCULATION_ID}}',
                },
            },
        },
    });
    
    console.log(req.body)
    console.log(res.body)
    
    res.json({
        paymentIntentID: paymentIntent.id,
        clientSecret: paymentIntent.client_secret,
        ephemeralKey: ephemeralKey.secret,
        customer: customer.id,
        publishableKey: 'pk_test_'
    });
} catch(e) {
    res.status(400).json({ error: { message: e.message }});
}
});

app.post('/update-payment-sheet', async (req, res) => {

    const paymentIntent = await stripe.paymentIntents.update(
        req.body.paymentIntentID,
        {
            amount: req.body.amount,
        }
    );
    console.log(req.body)
    console.log(res.body)
    
    res.json({});
});

app.listen(3000, () => console.log('Running now on port 3000'));
app.get('/', (req,res) => res.json('My API is running'))

Below is a copy of the code from the Stripe website that is not working

// Set your secret key. Remember to switch to your live secret key in production.
// See your keys here: https://dashboard.stripe.com/apikeys
const stripe = require('stripe')(
  'sk_test_',
  {apiVersion: '2024-06-20; payment_intent_with_tax_api_beta=v1;'}
);

const paymentIntent = await stripe.paymentIntents.create({
  amount: 1000,
  currency: 'usd',
  automatic_payment_methods: {
    enabled: true,
  },
  async_workflows: {
    inputs: {
      tax: {
        calculation: '{{CALCULATION_ID}}',
      },
    },
  },
});

Solution

  • The problem is you are using the await keyword in the top level of your code, however, you are only allowed to use the await keyword inside an async function.

    With this slight change your code will work

    const stripe = require('stripe')('sk_test_');
    const express = require('express');
    const app = express();
    
    app.use(express.json());
    // put the create calculation code inside an async function
    async function createCalculation(){
        const calculation = await stripe.tax.calculations.create({
            currency: 'usd',
            line_items: [
                {
                amount: 1000,
                reference: 'L1',
                tax_code: 'txcd_99999999',
                },
            ],
            customer_details: {
                address: {
                line1: '920 5th Ave',
                city: 'Seattle',
                state: 'WA',
                postal_code: '98104',
                country: 'US',
                },
                address_source: 'shipping',
            },
        });
    }
    // call that function without using the await keyword, it will be executed asynchronously though
    createCalculation();
    
    app.post('/prepare-payment-sheet', async (req, res) => {
    try {
        const customer = await stripe.customers.create();
        const ephemeralKey = await stripe.ephemeralKeys.create({customer: customer.id},
                                                               {apiVersion: '2024-06-20; payment_intent_with_tax_api_beta=v1;'});
        const paymentIntent = await stripe.paymentIntents.create({
            amount: 1099,
            currency: 'usd',
            customer: customer.id,
            automatic_payment_methods: {
                enabled: true,
            },
            async_workflows: {
                inputs: {
                    tax: {
                    calculation: '{{CALCULATION_ID}}',
                    },
                },
            },
        });
        
        console.log(req.body)
        console.log(res.body)
        
        res.json({
            paymentIntentID: paymentIntent.id,
            clientSecret: paymentIntent.client_secret,
            ephemeralKey: ephemeralKey.secret,
            customer: customer.id,
            publishableKey: 'pk_test_'
        });
    } catch(e) {
        res.status(400).json({ error: { message: e.message }});
    }
    });
    
    app.post('/update-payment-sheet', async (req, res) => {
    
        const paymentIntent = await stripe.paymentIntents.update(
            req.body.paymentIntentID,
            {
                amount: req.body.amount,
            }
        );
        console.log(req.body)
        console.log(res.body)
        
        res.json({});
    });
    
    app.listen(3000, () => console.log('Running now on port 3000'));
    app.get('/', (req,res) => res.json('My API is running'))