Search code examples
firebasegoogle-cloud-functionscorsnuxt.jsrazorpay

Unable to solve CORS error in nuxt while running the razorpay function written in firebase functions


I have installed the cors dependency and used it in my code. But after everything is correct in my code it still gave me cors error. Here is the error.

Error 1 -

Access to fetch at 'https://us-central1-my-project-name.cloudfunctions.net/createPayment' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Error 2 -

POST https://us-central1-my-project-name.cloudfunctions.net/createPayment net::ERR_FAILED

I don't understand where I am doing wrong. I am trying to integrate Razorpay. My function is written in Firebase Functions.

My index.js file code written in the functions folder.

const functions = require('firebase-functions')
const Razorpay = require('razorpay')
const admin = require('firebase-admin')
const crypto = require('crypto')
const cors = require('cors')({ origin: true })
admin.initializeApp()
//Function to Create Payment
exports.createPayment = functions.https.onRequest(async (req, res) => {
  cors(req, res, () => {
    admin
      .firestore()
      .collection('payments').doc('pay1')
      .add(req.body.data)
      .then((payment) => {
        var instance = new Razorpay({
          key_id: 'rzp_test_qmwfgfdgA',
          key_secret: 'SsKCt8y5Pbfcbf54hg2lsB',
        })

        var options = {
          amount: req.body.data.amount * 100,
          currency: 'INR',
          receipt: payment.id,
          payment_capture: 1,
        }
        instance.orders.create(options, function (err, order) {
          res.status(201).send({ data: order })
        })
      })
  })
})

// Function to Verify Payment

exports.verifyPayment = functions.https.onRequest(async (req, res) => {
  cors(req, res, () => {
    const order = req.body.data

    const text = order.razorpay_order_id + '|' + order.razorpay_payment_id
    var signature = crypto
      .createHmac('sha256', secret_key)
      .update(text)
      .digest('hex')

    if (signature === order.razorpay_signature) {
      res.status(201).send({ data: { message: 'Successfull Payment' } })
    } else {
      res.status(400).send({ data: { message: 'Signature mismatch' } })
    }
  })
})

Function written in methods in the components to call the function from firebase functions.

methods: {
    async pay() {
      const data = {
        amount: 1000,
        name: 'Name',
        email: 'Email',
        phone: 'Phone',
        status: 'pending',
      }
      var createPayment = firebase.functions().httpsCallable('createPayment')
      createPayment(data)
        .then((res) => {
          let order = res.data
          var options = {
            key: 'rzp_test_qmwfgfdgA',
            amount: order.amount_due,
            currency: order.currency,
            description: 'Payment description ',
            order_id: order.id,
            prefill: {
              name: this.data.name,
              email: this.data.email,
              contact: this.data.phone,
            },
            theme: {
              color: '#ffcc00',
            },
            handler: (response) => {
              this.verifySignature(response)
            },
          }
          console.log('Pay')
          var rzp = new Razorpay(options)
          rzp.open()
        })
        .catch((error) => {
          console.log(error)
        })
    },
    async verifySignature(response) {
      const verifyPayment = firebase.functions().httpsCallable('verifyPayment')
      verifyPayment(response)
        .then((res) => {
          alert('payment received')
        })
        .catch((err) => {
          console.log('error')
        })
    },
  },

Solution

  • You are mixing up callable and HTTP functions. You've defined an HTTP function using onRequest, but you're trying to invoke it as if it was a callable function using the Firebase client SDK. This is not going to work.

    If you want to write an HTTP function, you should invoke it from your app using a standard HTTP client library. If you want to use a callable function to be invoked with the Firebase SDK on the client, you will need to declare your function using onCall as described in the documentation.

    Note that HTTP and callable functions have very different implementations. You should study the documentation to determine which one you want to use, and how to implement it.