lamanton33
lamanton33

Reputation: 1

Server returns a page instead of triggering node js endpoint

I’m implementing backend for a website. I’ve chose Node.js for it.
I was asked to integrate getpostman payment gateway using their API (https://documenter.getpostman.com/view/7415068/TVCb4AZw)

 I created backend folder on the hosting and 3 js files: server.js, routes.js and payment.js

 I will show you them here:
**

server.js**

const express = require('express');
const app = express();
const path = require('path');
const routes = require('./routes');

app.use(express.static(path.join(__dirname, 'public_html')));
app.use(express.urlencoded({ extended: true }));
app.use(express.json());

app.use('/', routes);

const port = process.env.PORT || 3000;
app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});



 **routes.js
**

const router = express.Router();
const path = require('path');
const payments = require('./payment');

// Route for the payment form submission
router.post('/payment', async (req, res) => {
  const paymentData = req.body;

  try {
    // Get the payment token
    const token = await payments.getToken(
      paymentData.cardNumber,
      paymentData.expiryMonth,
      paymentData.expiryYear,
      paymentData.cvv
    );

    // Process the payment
    const success = await payments.processPayment({
      token,
      orderId: generateOrderId(),
      price: paymentData.price,
      currency: paymentData.currency,
      lifetime: paymentData.lifetime,
      description: paymentData.description,
      userName: paymentData.userName,
      userPhone: paymentData.userPhone,
      userEmail: paymentData.userEmail,
      userIP: req.ip,
      realUrl: '',
      resultUrl: '',
      successUrl: '',
      failureUrl: ''
    });

    if (success) {
      res.redirect('./luck'); // Redirect to success page if payment was successful
    } else {
      res.redirect('./failure'); // Redirect to failure page if payment failed
    }
  } catch (err) {
    console.error(err);
    res.redirect('/failure'); // Redirect to failure page if an error occurred
  }
});

// Function to generate a random order ID
function generateOrderId() {
  return Math.floor(Math.random() * 1000000).toString();
}

module.exports = router;


**payment.js
**

const request = require('request');
const crypto = require('crypto');

// Function to create HMAC signature
function createSignature(requestBody, keyHex) {
  const values = Object.values(requestBody);
  const hmacData = values.sort().join('|');
  const hmacKey = Buffer.from(keyHex, 'hex');
  const hmacObj = crypto.createHmac('sha256', hmacKey);
  hmacObj.update(hmacData);
  return hmacObj.digest('hex');
}

// Function to obtain the payment token
function getToken(cardNumber, expiryMonth, expiryYear, cvv) {
  return new Promise((resolve, reject) => {
    const getTokenOptions = {
      method: 'POST',
      url: 'https://pinpaygate.com/dev/card/getToken',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        project: 'here_is_my_project_id_provided_by_the_company',
        card_number: cardNumber,
        expiry_month: expiryMonth,
        expiry_year: expiryYear,
        cvv: cvv
      })
    };

    request(getTokenOptions, function (error, response, body) {
      if (error) {
        console.error(error);
        reject('Error processing payment');
        return;
      }

      const { success, token } = JSON.parse(body);

      if (success) {
        resolve(token);
      } else {
        reject('Token acquisition failed');
      }
    });
  });
}

// Function to process the payment
function processPayment(paymentData) {
  return new Promise((resolve, reject) => {
    const {
      token,
      orderId,
      price,
      currency,
      lifetime,
      description,
      userName,
      userPhone,
      userEmail,
      userIP,
      realUrl,
      resultUrl,
      successUrl,
      failureUrl
    } = paymentData;

    const body = {
      project: ‘here_is_my_project_id_provided_by_the_company',
      card_token: token,
      order_id: orderId,
      price: price.toString(),
      currency,
      lifetime: lifetime || '',
      description: description || '',
      user_name: userName || '',
      user_phone: userPhone || '',
      user_contact_email: userEmail || '',
      ip: userIP || '',
      real_url: realUrl || '',
      result_url: resultUrl || '',
      success_url: successUrl || '',
      failure_url: failureUrl || '',
      signature: ''
    };

    body.signature = createSignature(body, 'here_is_my_secret_key_provided_by_the_comp');

    const processPaymentOptions = {
      method: 'POST',
      url: 'https://pinpaygate.com/dev/card/process',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(body)
    };

    request(processPaymentOptions, function (error, response, body) {
      if (error) {
        console.error(error);
        reject('Error processing payment');
        return;
      }

      const { success } = JSON.parse(body);

      if (success) {
        resolve(true); // Payment processed successfully
      } else {
        reject('Payment transaction failed');
      }
    });
  });
}

module.exports = {
  getToken,
  processPayment
};


In public_html folder, I have payment.html (named payment), luck.html (named luck) and failure.html (named failure)
Payment.html is the payment page where payment form is located

here it is



<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="assets/css/style.css">
    <link rel="stylesheet" href="assets/css/TT%20Firs%20Neue.css">
   
    <title>Dystryx - payment</title>
</head>
<body>
<div class="container">
    <h6>Оплата</h6>
    <span><img src="images/cross.svg" alt=""></span>
    <h1>Способ оплаты</h1>
    <form action="https://dystryx.online/backend/payment" method="post">
        <label for="currency">Currency
            <select name="currency" id="currency">
                <option value="usd"> $</option>
                <option value="gbp"> £</option>
                <option value="eur"> €</option>
            </select>
        </label>

        <input type="text" name="cardNumber" id="cardNumber" maxlength="19" onkeypress="cardspace()" placeholder="CARD NUMBER"/>

        <input type="text" name="name" id="name" placeholder="NAME"/>

        <input type="text" name="price" id="price" placeholder="PRICE"/>

        <input type="text" name="email" id="email" placeholder="EMAIL"/>

        <div class="float">
            <label for="expiryMonth">VALID TILL
                <input type="number" min="0" max="12" name="expiryMonth" id="expiryMonth" maxlength="2" onkeypress="addSlashes()" placeholder="Month"/>
            </label>
            <label for="expiryYear">ㅤㅤ
                <input type="number" name="expiryYear" min="2023" id="expiryYear" maxlength="4" onkeypress="addSlashes()" placeholder="Year"/>
            </label>
        </div>

        <div class="float">
            <label for="cvv">
                <input type="number" min="0" max="999" name="cvv" id="cvv" maxlength="3" onkeypress="addSlashes()" placeholder="CVV"/>
            </label>
        </div>
    
        <label for="checkbox">
            <input type="checkbox" name="checkbox" id="checkbox"/>
            <p>I agree with terms.</p>
        </label>

        <button type="submit" id="payButton">Pay</button>
    </form>
</div>
<script src="script.js"></script>
</body>
</html>


As you can see I am using the , to trigger the backend endpoint, but instead of this I get error 404 after clicking on “Pay” button. It’s because it tries to reach a page by that address, but it doesn’t trigger the endpoint.

I ensured that my server works by doing node server.js , while being connected to the hosting through SSH. It showed me that Server running on port 3000 and everything is fine. Also I did the npm init in the backend folder, so node is also installed, as well as express and other dependencies (you can tell this by the fact that server is running)

How to solve this issue?

Upvotes: 0

Views: 184

Answers (1)

Stacks Queue
Stacks Queue

Reputation: 1152

few things I can specify on your code. I'm doing the same implemention in my server.

  1. Your api route should be above your wildcard route that will redirect to page.

  2. You should specify that your route is an api to avoid conflict to your page route.

     app.use('/api', routes);
    
  3. Instead of redirecting to either success or failure page, why don't you just return a json response and let your frontend handle the redirect.

Your server.js should look like this.

/**
 * routes import
 */
const routes = require('./routes');

/**
 * middlewares
 */
app.use(express.json());
app.use(express.urlencoded({ extended: true }));



/**
 * routes
 */
app.use('/api', routes);


/**
 * your wildcard route where everything redirect to here
 */
app.use(express.static(path.join(__dirname, 'public_html')));
app.get("/*", (req, res) => {
  res.sendFile(path.join(__dirname + "public_html/index.html"));
});


const port = process.env.PORT || 3000;
app.listen(port, () => {
  console.log(`Server is running on port ${port}`);
});
    

Upvotes: 0

Related Questions