node-ebics-client icon indicating copy to clipboard operation
node-ebics-client copied to clipboard

client.keys is undefined when creating a bankLetter

Open FridgeWalaby opened this issue 5 years ago • 5 comments

I ran into the problem that my client.keys are undefined. And thus the bankLetter cannot be created.

Here is my code:

initZKB = async () => {
const ebicsClient = await new ebics.Client({
        url: 'https://testplattform.zkb.ch/ebicsweb/ebicsweb',
        partnerId: 'XXX',
        userId: 'XXX',
        hostId: 'XXX',
        passphrase: 'PASS',
        keyStorage: ebics.fsKeysStorage('./src/keys-dev')
      })

      await ebicsClient
        .send(ebics.Orders.INI)
        .then((resp: any) => {
          console.log('Response for INI order %j', resp);
          return ebicsClient.send(ebics.Orders.HIA);
        })
        .then(async (resp: { technicalCode: string }) => {
          console.log('Response for HIA order %j', resp);
          if (resp.technicalCode !== '000000')
            throw new Error('Something might went wrong');

          console.log(
            'Public keys should be sent to bank now. See examples/bankLetter.js'
          );
        });

      const bankName = 'Zürcher Kantonalbank';
      const template = fs.readFileSync('./src/ini_de.hbs').toString();
      const bankLetterFile = path.join(os.homedir(), 'bankLetter_de.html');

      const letter = await new ebics.BankLetter({
        ebicsClient,
        bankName,
        template
      });

// This serialize() function throws the error
      await letter.serialize(bankLetterFile).then(() => {
        console.log('Send your bank the letter (%s)', bankLetterFile);
      });

}

And this is the error:

UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'keys' of undefined
    at BankLetter.generate (/xxx/node_modules/ebics-client/lib/BankLetter.js:48:34)
    at BankLetter.serialize (/xxx/node_modules/ebics-client/lib/BankLetter.js:63:29)

Does anyone have an idea why the keys are not set? Thanks in advance.

FridgeWalaby avatar Feb 12 '20 18:02 FridgeWalaby

@vladhristov could you please inspect and comment?

nanov avatar Feb 15 '20 07:02 nanov

@FridgeWalaby Hi, the code looks right. I copied/pasted it and tried it numerous times with the exception of putting the code into an express route and passing the Client my test data. It runs without any error. The bank letter is generated as well. I would suggest setting a break point on const bankName = 'Zürcher Kantonalbank'; line and check if you have keys in ./src/keys-dev. Let us know of your findings. Regards, Vlad

vladhristov avatar Feb 17 '20 09:02 vladhristov

I refactored my code wrongly. I created the ebics.Client without using await in the constructor, but it works now. I'm also running it in an express route.

This is my working code.

// ZKBDatalink.ts
const ebics = require('ebics-client');

class ZKBDataLink {
  public client: any;

  constructor() {  }

  initClient = async () => {
    require('dotenv').config();

    this.client = await new ebics.Client({
      url: process.env.ZKB_URL,
      partnerId: process.env.ZKB_PARTNERID,
      userId: process.env.ZKB_USERID,
      hostId: process.env.ZKB_HOSTID,
      passphrase: process.env.ZKB_PASSPHRASE,
      keyStorage: ebics.fsKeysStorage('./src/keys-dev')
    });
  };
}

export default new ZKBDataLink();

And i called the letter creation in the following way:

public async contactZKB(req: any, res: Response) {
    try {
      await ZKBDatalink.initClient();  //
      await ZKBDatalink.client
        .send(ebics.Orders.INI)
        .then((resp: any) => {
          console.log('Response for INI order %j', resp);
          return ZKBDatalink.client.send(ebics.Orders.HIA);
        })
        .then(async (resp: { technicalCode: string }) => {
          console.log('Response for HIA order %j', resp);
          if (resp.technicalCode !== '000000')
            throw new Error('Something might went wrong');

          console.log(
            'Public keys should be sent to bank now. See examples/bankLetter.js'
          );
        });

      const bankName = 'Zürcher Kantonalbank';
      const template = fs.readFileSync('./src/ini_de.hbs').toString();
      const bankLetterFile = path.join(os.homedir(), 'bankLetter_de.html');
      const client = ZKBDatalink.client;
      const letter = await new ebics.BankLetter({
        client,
        bankName,
        template
      });

      await letter.serialize(bankLetterFile).then(() => {
        console.log('Send your bank the letter (%s)', bankLetterFile);
      });

      res.status(200).send();
    } catch (error) {
      res.status(400).send();
    }
  }

FridgeWalaby avatar Feb 18 '20 03:02 FridgeWalaby

Also I have a bank specific question (Which might not fit in here, but maybe @nanov @vladhristov has experience with ZKB Datalink Testplattform): I wonder what parameters I have to send with the orderType Z54 and what file format I will get back when I retrieve the ESR-Gutschrift file from the Zürcher Kantonalbank?

public async sendHPB(req: any, res: Response) {
    try {
      await ZKBDatalink.client
        .send(ebics.Orders.HPB)
        .then(async (resp: { technicalCode: string; bankKeys: any }) => {
          console.log('Response for HPB order %j', resp);
          if (resp.technicalCode !== '000000')
            throw new Error('Something went wrong');

          console.log('Received bank keys: %j', resp.bankKeys);
          await ZKBDatalink.client.setBankKeys(resp.bankKeys);
        });

      const ESROrder = {
        version: 'h004',
        orderDetails: {
          OrderType: 'Z54',
          OrderAttribute: 'DZHNN',
          StandardOrderParams: {}
        },
        operation: 'download'
      };

      await ZKBDatalink.client
        .send(ESROrder)
        .then((resp: { technicalCode: string; bankKeys: any }) => {
          console.log('Response for Z54 order %j', resp);
          if (resp.technicalCode !== '000000')
            throw new Error('Something went wrong');
        });

      res.status(200).send();
    } catch (error) {
      console.log('sendHPB', error);
      res.status(400).send();
    }
  }

I always receive {"businessCodeSymbol":"EBICS_NO_DOWNLOAD_DATA_AVAILABLE","businessCodeShortText":"No data are available at present for the selected download order type"} Which means that no data is present to download.

How can I upload/get ESR test data? Any help would be appreciated.

FridgeWalaby avatar Feb 18 '20 03:02 FridgeWalaby

AFAIK Z54 order should receive same parameters as C53 order, and of course you should have some data for those dates.

As a result you'll receive a zip(stream) which you'll have to unzip and then parse a camt.054 file.

All the Z orders are zipped C orders ( Z53 = zipped C53 ).

nanov avatar Feb 18 '20 17:02 nanov