Nextjs FE с Express BE для выполнения вызовов API к платежному шлюзу

#javascript #reactjs #rest #express #next.js

#javascript #reactjs #rest #экспресс #next.js

Вопрос:

Мне нужно создать API с моего узлового сервера и поделиться данными с моим приложением Nextjs. Сервер узла находится в папке с именем server/index.js в моей корневой папке Nextjs apps.

npm run dev определяется как nodemon server/index.js в моем package.json.

Это моя следующая страница js, которая вызывает сервер узла:

 

// const __DEV__ = document.domain === 'localhost'

const RoomBilling = (props) => {

    const { fromDate, toDate, numberOfGuest, numberOfRooms } = props;



    const loadScript = (src) => {
        return new Promise((resolve) => {
            const script = document.createElement('script');
            script.src = src;
            script.onload = () => {
                resolve(true);
            }
            script.onerror = () => {
                resolve(false)
            }
            document.body.appendChild(script);
        })
    }


    const displayRazorPay = async () => {

        const loadingScript = await loadScript('https://checkout.razorpay.com/v1/checkout.js');
        if(!loadingScript){
            //Show toast error
            return;
        }


        //This is where I make a request to my node server to return certain data defined in the next file
        const data = await fetch('/razorpay',{method: 'POST'}).then((t) => t.json())




        const options = {
            key: document.domain === 'localhost' ? "DEV_KEY" : 'PROD_KEY', // Enter the Key ID generated from the Dashboard
            amount: data.amount, 
            currency: data.currency,
            name: "BNB",
            description: "Bed and Breakfast",
            image: "./../public/dino.svg",
            order_id: data.id,
            handler: function (response){
                alert(response.razorpay_payment_id);
                alert(response.razorpay_order_id);
                alert(response.razorpay_signature)
            },
            prefill: {
                //get user data from info modal
                "name": "Gaurav Kumar",
                "email": "gaurav.kumar@example.com",
                "contact": "9999999999"
            },
            notes: {
                
                "address": "Razorpay Corporate Office"
            },
            theme: {
                "color": "#F37254"
            }
        };
        const paymentObj = new Razorpay(options);
        paymentObj.open();
    }
    
    return(
        <>
        <h2 className="mt-4">Room 3</h2>
            <div className="w-full mt-6 py-4 px-6 bg-gray-200 rounded-lg flex flex-col flex-grow">
                <div className="">
                    <p className="text-2xl"><span>1999</span><span className="text-base"> /night</span></p>
                    <p className="mt-2"><span>{fromDate}</span> to <span>{toDate}</span></p>
                    <p className="mt-6"><span>1999</span> x <span>{numberOfRooms}</span><span className="float-right"><span>3998</span></span></p>
                    <p className="mt-2">Extra Bedding<span className="float-right"><span>750</span></span></p>
                    <p className="mt-4 font-bold">Total<span className="float-right"><span>4748</span></span></p>
                </div>
                <div className="btn-action text-center my-8">
                    <button className="btn-primary ml-2" onClick={displayRazorPay}> Book now</button>
                </div>
            </div>
        </>
    );
}

export default RoomBilling;
  

Мой server/index.js файл:

 const next = require('next')
let RazorPay = require('razorpay');
const shortid = require('shortid');


const PORT = process.env.PORT|| 3000;
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler();



const razorpay = new RazorPay({
                        key_id: 'TEST_KEY',
                        key_secret: 'TEST_SECRET',
                      });

app
  .prepare()
  .then(() => {
    const server = express();


   

    server.get("*", (req, res) => {
      return handle(req, res);
    });

  //   server.get('/rooms', (req, res) => {
  //     const actualPage = '/rooms'
  //     const queryParams = { from: req.params.from, to: req.params.to, guest: req.params.guest, rooms: req.params.rooms } 
  //     app.render(req, res, actualPage, queryParams)
  // })

    server.post('/razorpay ', async (req, res) => {
      const payment_capture = 1;
      const amount = 299 * 100; // convert to paisa
      const currency = 'INR';
      const receipt = shortid.generate();

      const options = {
        amount,
        currency,
        receipt,
        payment_capture
      }
      const response = await razorpay.orders.create(options)
      console.log("response");
      res.json({
        id: response.id,
        currency: response.currency,
        amount: response.amount
      });
    })

    server.listen(PORT, err => {
      if (err) throw err;
      console.log(`> Ready on ${PORT}`);
    });
  })
  .catch(ex => {
    console.error(ex.stack);
    process.exit(1);
  });
  

Всякий раз, когда я делаю этот запрос к своему BE, я получаю ошибку 404 ** не найдено **. Вызов API никогда не доходит до моего экспресс-сервера.

Кроме того, для маршрутизации на страницу / rooms я использую компонент Nextjs <Link/> . Должен ли я отображать страницу с самого моего сервера? Я прокомментировал рендеринг приложения / rooms в моем server/index.js файл. Это не приведет к отображению страницы, если я удалю <Link/> маршрутизацию.

Комментарии:

1. Не совсем уверен, правильно ли я следую, но, похоже, URL-адрес выборки должен быть http://localhost:3000/razorpay . Но для подтверждения вы запускаете оба next.js и ваш сервер прав? Я бы рекомендовал вам изучить nextjs.org/docs/api-routes/introduction потому что это кажется гораздо более элегантным решением, чем то, что у вас есть в настоящее время.

2. Да, я использую оба на http:localhost:3000 . Мне нужен был сервер узла, так как мне нужно интегрировать платежный шлюз. Кроме того, могу ли я использовать nextjs для маршрутизации и express явно для кода, связанного с оплатой?

3. Насколько я знаю, вы не можете запускать 2 приложения на одном порту? В любом случае, если вы используете такой инструмент, как Postman, для тестирования своего API, работает ли он тогда?

4. Да, API-интерфейсы отлично работают в Postman