mobilpay / Node.js

Proof of concept - mobilPay integration in Node.js
8 stars 4 forks source link

Mobilpay_Payment_Request_Sms::loadFromQueryString failed: signature is missing #8

Open eFlavian opened 4 months ago

eFlavian commented 4 months ago

I get an Mobilpay_Payment_Request_Sms::loadFromQueryString failed: signature is missing error.

my order.js:


module.exports = {
  getRequest: getRequest,
  decodeResponse: decodeResponse
};

const privateKeyPath = './privateKeyDev2.key';
const publicKeyPath = './publicKeyDev2.cer';

const rc4 = require('./functions/encrypt.js');
const fs = require('fs');
const privateKey = fs.readFileSync(privateKeyPath).toString();
const publicKey = fs.readFileSync(publicKeyPath).toString();
const xml2js = require('xml2js');
var builder = new xml2js.Builder({
  cdata: true
});
var parser = new xml2js.Parser({
  explicitArray: false
});

function getPayment(orderId, amount, currency,requestBody) {
  let date = new Date();
  const data = {
    order: {
      $: {
        id: orderId,
        timestamp: date.getTime(),
        type: "card",
      },
      signature: "mySignatureHere",
      url: {
        return: "myReturnURL",
        confirm: "myConfirmURL",
      },
      invoice: {
        $: {
          currency: currency,
          amount: amount,
        },
        details: "test plata",
        contact_info: {
          billing: {
            $: {
              type: "person",
            },
            first_name: "Test",
            last_name: "Test",
            address: "strada",
            email: "test@mobilpay.ro",
            mobile_phone: "mobilePhone",
          },
          shipping: {
            $: {
              type: "person",
            },
            first_name: "Test",
            last_name: "Test",
            address: "strada",
            email: "test@mobilpay.ro",
            mobile_phone: "mobilePhone",
          },
        },
      },
      ipn_cipher: "aes-256-cbc",
    },
  };

  console.log("my data: ", data);
  return { data, algorithm: 'aes-256-cbc' };
}

function getRequest(orderId,requestBody) {
  const result = getPayment(orderId, 1, 'RON',requestBody)
  console.log("my result: ", result);
  let xml = builder.buildObject(result.data);
  console.log("my xml: ", xml);

  return rc4.encrypt(publicKey, xml, result.algorithm);
}

function decodeResponse(data) {
  return new Promise(function (resolve, reject) {
    parser.parseString(rc4.decrypt(privateKey, data.iv, data.env_key, data.data, data.cipher), function (err, result) {
      if (err) {
        reject(err);
      }
      resolve(result);
    });
  });
}

how i build it in index.js:

         const encryptedData = getRequest(orderId, requestBody);

            // POST request options
            const request = {
                method: 'POST',
                url: 'https://sandboxsecure.mobilpay.ro', // LIVE: https://secure.mobilpay.ro
                data: encryptedData
            };

             return {
                statusCode: 200,
                headers: {
                    'Access-Control-Allow-Origin': '*',
                    'Access-Control-Allow-Headers': '*',
                },
                body: JSON.stringify({
                    url: request.url,
                    env_key: request.data.envKey,
                    data: request.data.envData,
                }),
            };

and this is how i do the form in front:

        const response = await netopiaPayment(...); // endpoint that returns me the url, env_key, data

        const url = response.url;
        const env_key = response.env_key;
        const data = response.data;

        // Creating the form dynamically
        const form = document.createElement('form');
        form.method = 'POST';
        form.action = url;

        const envKeyInput = document.createElement('input');
        envKeyInput.type = 'hidden';
        envKeyInput.name = 'env_key';
        envKeyInput.value = env_key;

        const dataInput = document.createElement('input');
        dataInput.type = 'hidden';
        dataInput.name = 'data';
        dataInput.value = data;

        form.appendChild(envKeyInput);
        form.appendChild(dataInput);

        document.body.appendChild(form);
        console.log(form);

        form.submit();

Am i missing something ? The signature is clearly inside data (from getPayment).

P.S. I've also tried to change my signature to a random value and gives me the same error.

Thanks.

tyukesz commented 1 month ago

Having the same issue

nagyihuni commented 1 month ago

Hi, we have the same issue, but in PHP, we use MobilPay code on PHP 8.2 https://github.com/mobilpay/PHP_CARD

The signature is included, but the system display the same error... Did you resolved the issue?

alexvrv commented 4 weeks ago

@eFlavian you need all 4 variables in hidden inputs (iv, env_key, data, cipher).

In encrypt function change the return to:

return {
      iv: iv.toString('base64'),
      env_key: envKey.toString('base64'),
      data: encrypted,
      cipher: algorithm
  };
nagyihuni commented 4 weeks ago

Thanks very much, now it's working :)