Vikrant Patil
Vikrant Patil

Reputation: 23

I'm Requesting POST Method via axios but post method is not working

index.js //backend

const functions = require("firebase-functions");
const express = require("express");
const cors = require("cors");
const stripe = require("stripe") 
('sk_test_51IvTMySJHm59a7wpdl1wmkkj3uAIYN4XEBKuZO0ezF3vKR2dubLbzOEDLjCug
6wtULBK2mUsPWjJLol0NfMw67A000kWGNbvkb'); //Security code provide via stripe

//API


// - App config
const app = express();

// - Middlewares
app.use(cors({ origin: true }));
app.use(express.json());

// - API routes
app.get('/', (req, res) => {
res.status(200).send('hello world');
})

app.post("/payments/create", async (req, res) => {
const total = req.query.total;

console.log('Payment has been received !!! for this amount >>> ', total);

const paymentIntent = await stripe.paymentIntents.create({
    amount: total,  //This is in sub units
    currency: "usd",
});

res.status(201).send({
    clientSecret: paymentIntent.client_secret,
})

})
// - Listen Command
exports.api = functions.https.onRequest(app);

Payment.js //FrontEnd Raect Component

import { CardElement, useElements, useStripe } from '@stripe/react-stripe-js';
import axios from 'axios';
import React, { useEffect, useState } from 'react'
import CurrencyFormat from 'react-currency-format';
import { Link, useHistory } from 'react-router-dom';
import CheckoutProduct from './CheckoutProduct';
import './Payment.css';
import { getBasketTotal } from './reducer';
import { useStateValue } from './StateProvider';

function Payment() {
const [{ user, basket }, dispatch] = useStateValue();
const stripe = useStripe();
const elements = useElements();
const history = useHistory();

const [error, setError] = useState(null);
const [disabled, setDisabled] = useState(true)
const [succeeded, setSucceeded] = useState(false)
const [processing, setProcessing] = useState('')
const [clientSecret, setClientSecret] = useState(true)

useEffect(() => {
    //generate  the special stripe secret which allows us to charge a customer
    const getClientSecret = async () => {
        const responce = await axios({
            method: 'post',
            //  Stripe expects the subunit of whatever currency you are using 
            url: `/payments/create?total=${getBasketTotal(basket) * 100}`
        });
        setClientSecret(responce.data.clientSecret);
    }

    getClientSecret();
}, [basket])

console.log('The Secret is >>>', clientSecret);

const handleSubmit = async e => {
    e.preventDefault();
    setProcessing(true);

    const payload = await stripe.confirmCardPayment(clientSecret, {
        payment_method: {
            card: elements.getElement(CardElement)
        }
    }).then(({ paymentIntent }) => {
        //paymentIntent = payment confirmation
        setSucceeded(true);
        setError(null);
        setProcessing(false);

        history.replace('/orders');
    })
}

const handleChange = e => {
    setDisabled(e.empty);
    setDisabled(e.error ? e.error.message : '')
}
return (
    <div className='payment'>
        <div className="paymentContainer">
            <h1>
                Checkout (<Link to='/checkout'>{basket.length} items</Link>)
            </h1>
            <div className="paymentSection">
                <div className="paymentTitle">
                    <h3>Delivery Address</h3>
                </div>
                <div className="paymentAddress">
                    <p>{user?.email}</p>
                    <p>Om nagar</p>
                    <p>Jayraj Building, Vasai</p>
                </div>
            </div>

            <div className="paymentSection">
                <div className="paymentTitle">
                    <h3>Review items and delivery</h3>
                </div>
                <div className="paymentItems">
                    {basket.map(item => (
                        <CheckoutProduct
                            id={item.id}
                            title={item.title}
                            price={item.price}
                            rating={item.rating}
                            img={item.img} />
                    ))}
                </div>

            </div>

            <div className="paymentSection">
                <div className="paymentTitle">
                    <h3>Payment Method</h3>
                </div>
                <div className="paymentDetails">
                    <form onSubmit={handleSubmit}>
                        <CardElement onChange={handleChange} />
                        <div className="paymentPriceContainer">
                            <CurrencyFormat
                                renderText={(value) => (
                                    <>
                                        <h3>Order Total : {value}</h3>
                                    </>
                                )}
                                decimalScale={2}
                                value={getBasketTotal(basket)}
                                displayType={"text"}
                                thousandSeparator={true}
                                prefix={"$"}
                            />

                            <button disabled={processing || disabled || succeeded}>
                                <span>{processing ? <p>Processing</p> : 'Buy Now'}</span>
                            </button>
                        </div>
                        {error && <div>{error}</div>}
                    </form>
                </div>
            </div>
        </div>
    </div>
)
}

export default Payment

axios.js

import axios from 'axios';

const instance = axios.create({
baseURL='http://localhost:5001/app-eea29/us-central1/api'  //baseurl from firebase emulator suite
})

export default instance;

xhr.js:177 POST http://localhost:3000/payments/create?total=4534 404 (Not Found)

Uncaught (in promise) Error: Request failed with status code 404 at createError (createError.js:16) at settle (settle.js:17) at XMLHttpRequest.handleLoad (xhr.js:62)

Upvotes: 0

Views: 831

Answers (3)

Priyanshu Gupta
Priyanshu Gupta

Reputation: 21

In handleChange function, you have done some mistake...

const handleChange = e => {
    setDisabled(e.empty);
    setDisabled(e.error ? e.error.message : '')
}

    // Instead of this add this code...
const handleChange = e => {
    setDisabled(e.empty);
    setError(e.error ? e.error.message : "");
}

Upvotes: 1

Delice
Delice

Reputation: 856

It looks like you are missing the "data" property inside your axios.

I attached the code. Try and see if it works.

import instance from './path-to-axios'; <------- IMPORTANT

useEffect(() => {
    //generate  the special stripe secret which allows us to charge a customer
    const getClientSecret = async () => {
        const responce = await instance({
            method: 'post',
            //  Stripe expects the subunit of whatever currency you are using 
            url: `/payments/create`,
            data: getBasketTotal(basket) * 100 
        });
        setClientSecret(responce.data.clientSecret);
    }

    getClientSecret();
}, [basket])

EDIT: (because of the first answer provided)

Remember to use your instance you created instead of axios itself.

Upvotes: 0

mhodges
mhodges

Reputation: 11116

You export instance as an instance of axios with a base URL, but then in your react component, you aren't using it - you use axios({ ...}), which doesn't have the base URL in it. I have a feeling that's where your problem lies

Upvotes: 1

Related Questions