0
votes

I have a front-end that uses vue-stripe checkout, I added cors as a middleware but every time I make a request from the vue front-end to my node backend I get this error:

Access to XMLHttpRequest at 'localhost:5000/pay' from origin 'http://localhost:8080' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, chrome, chrome-extension, https.

buy.vue

<template>
  <div>
    <stripe-elements
      ref="elementsRef"
      :pk="publishableKey"
      :amount="amount"
      locale="en"
      @token="tokenCreated"
      @loading="loading = $event"
    >
    </stripe-elements>
    <button @click="submit">Pay ${{ amount / 100 }}</button>
  </div>
</template>

<script>
import { StripeElements } from "vue-stripe-checkout";

import axios from "axios";
export default {
  components: {
    StripeElements,
  },
  data: () => ({
    loading: false,
    amount: 2500,
    publishableKey:
      "pk_test_51GyLkaKc91wTjOOi8Usj1n8aW730emkSfgJfKrwhcl6EHAgL5LhLDxQC9JXmwdHjdv3Vg1vhUatgC50fCaOHsHk400JLkwoAiH",
    token: null,
    charge: null,
  }),
  methods: {
    submit() {
      this.$refs.elementsRef.submit();
    },
    tokenCreated(token) {
      this.token = token;
      // for additional charge objects go to https://stripe.com/docs/api/charges/object
      this.charge = {
        source: token.id,
        amount: this.amount, // the amount you want to charge the customer in cents. $100 is 1000 (it is strongly recommended you use a product id and quantity and get calculate this on the backend to avoid people manipulating the cost)
        description: this.description, // optional description that will show up on stripe when looking at payments
      };
      this.sendTokenToServer(this.charge);
    },
    sendTokenToServer(charge) {
      axios.post("localhost:5000/pay", { charge });
    },
  },
};
</script>

server.js

const express = require("express");
const router = express.Router();
const connectDB = require("./config/db");
const cors = require("cors");
const app = express();

console.log(process.env.SECRET_MESSAGE);

//connect DB
connectDB();

//middleware
app.use(express.json({ extended: false }));
app.use(cors());
router.all("*", (_, res) =>
  res.json({ message: "please make a POST request to /stripe/charge" })
);
app.use((_, res, next) => {
  res.header("Access-Control-Allow-Origin", "*");
  res.header(
    "Access-Control-Allow-Headers",
    "Origin, X-Requested-With, Content-Type, Accept"
  );
  next();
});
app.get("/", (req, res) => res.send("API running"));

//routes
app.use("/pay", require("./routes/api/stripe"));
app.use("/pdf", require("./routes/api/pdf"));
app.use("/users", require("./routes/api/users"));
app.use("/auth", require("./routes/api/auth"));

const PORT = process.env.PORT || 5000;

app.listen(PORT, () => console.log(`listening on port ${PORT}`));

payment.js

const express = require("express");
const router = express.Router();
const env = require("dotenv").config({ path: "./.env" });
const stripe = require("stripe")(process.env.STRIPE_SECRET_KEY);

router.post("/", function (req, res) {
  var token_id = req.body.token_id;
  var purchase_price = req.body.price;

  //console.log(token.id +"\n"+purchase_price);

  var charge = stripe.charges.create(
    {
      amount: purchase_price, // Amount in cents
      currency: "usd",
      source: token_id,
      description: "Example charge",
    },
    function (err, charge) {
      if (err && err.type === "StripeCardError") {
        // The card has been declined
        res.json({ status: "failure", reason: "card was declined" });
      } else {
        console.log(charge);
        res.json({ status: "success" });
      }
    }
  );
});

module.exports = router;
1
and you use HTTP and not the filesystem? - Ifaruki

1 Answers

0
votes

CORS considers the port as part of the origin, so localhost:5000 and localhost:8080 are considered different origins here.

You might want to consider something like this which will allow you to use the same origin/domain for both the frontend code and the API during development: https://vuejs-templates.github.io/webpack/proxy.html