1

I'm trying to setup a test payment session on a Verifone p400 plus terminal from Adyen.

I'm following This guide using node and in my case "@adyen/api-library": "13.1.3".

The plan is to run the code in a alpine container, but during testing I'm on a mac.

I've downloaded the root cert and run openssl on it.

openssl x509 -outform der -in adyen-terminalfleet-test.pem -out adyen-terminalfleet-test.crt

I added the crt file to my keychain using security import adyen-terminalfleet-test.crt, it seemed to work.

I created a shared key and put everything as envs.

Then I ran my code:

... (imports + load envs) ... 
async function main() {
  const config: Config = new Config();
  config.merchantAccount = ADYEN_COMPANY_ID;
  config.certificatePath = ADYEN_CERT_PATH; // full path to the .crt file (?)
  config.terminalApiLocalEndpoint = 'https://192.168.1.199';
  config.apiKey = ADYEN_API_KEY;

  const client = new Client({ config });
  client.setEnvironment('TEST');

  const terminalLocalAPI = new TerminalLocalAPI(client);
  const securityKey: SecurityKey = {
    AdyenCryptoVersion: 1,
    KeyIdentifier: ADYEN_ID,
    KeyVersion: parseInt(ADYEN_VERSION),
    Passphrase: ADYEN_PASS,
  };

  const terminalApiRequest: TerminalApiRequest = {
    SaleToPOIRequest: {
      MessageHeader: {
        MessageCategory: MessageCategoryType.Payment,
        MessageClass: MessageClassType.Service,
        MessageType: MessageType.Request,
        POIID: ADYEN_TERMINAL_ID,
      },
      PaymentRequest: {
        PaymentTransaction: {
          AmountsReq: {
            Currency: 'SEK',
            RequestedAmount: 142,
          },
        },
        SaleData: {
          SaleTransactionID: {
            TimeStamp: Date.now().toString(),
            TransactionID: '123456',
          },
        },
      },
    },
  };

  try {
    const terminalApiResponse: TerminalApiResponse =
      await terminalLocalAPI.request(terminalApiRequest, securityKey);
    console.log('terminalApiResponse', terminalApiResponse);
  } catch (err) {
    console.error(err);
  }
}

main();

The result I get from this is:

ApiException {
   name: 'ApiException',
   message: 'unable to get local issuer certificate',
   statusCode: 500
}

If the cert path is pointing to the .pem file it does not work at all.

I'm getting the same responses under alpine linux as mac.

Any idea?

PS: When it comes to linux I installed the crt using this: (Still no luck)

RUN apk add ca-certificates
COPY adyen-terminalfleet-test.crt /usr/local/share/ca-certificates/adyen-terminalfleet-test.crt
RUN update-ca-certificates

When setting the certificatePath to the pem file I get:

TypeError [ERR_INVALID_ARG_TYPE]: The first argument must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object. Received undefined .. 
Herlin
  • 353
  • 1
  • 5
  • 12

2 Answers2

1

Can you try to first simply add .crt file to the root of the project and add this line config.certificatePath = "./cert.cer"; to the config to double check in case it's something with the library certificate validation?

Also just for sanity can you set the environment in the config, and not through the client?

Let me know if you can get it working with this so we can troubleshoot from there.

Jilling
  • 11
  • 1
  • 1
    hey! I managed to get it working using the .pem certificate and set the Config.environment as well. Then I notices I got a lot of errors that had nothing to do with the actual error from the lib, I debugged it and found that I was missing values in my request that I added and got it working. – Herlin Jul 13 '23 at 09:53
1

I eventually got it working using the PEM certificate. The missing part was the config.environment.

...
    const config: Config = new Config();
    config.merchantAccount = ADYEN_COMPANY_ID;
    config.certificatePath = ADYEN_CERT_PATH;
    config.terminalApiLocalEndpoint = `https://${ADYEN_TERMINAL_IP}`;
    config.environment =
      process.env.NODE_ENV === 'production' ? 'LIVE' : 'TEST';
    config.apiKey = ADYEN_API_KEY;

    this.securityKey = {
      AdyenCryptoVersion: 1,
      KeyIdentifier: ADYEN_ID,
      KeyVersion: parseInt(ADYEN_VERSION),
      Passphrase: ADYEN_PASS,
    };

    this.client = new Client({ config });
    this.client.setEnvironment(
      process.env.NODE_ENV === 'production' ? 'LIVE' : 'TEST',
    );

    const serviceId = uuidv4().replace(/-/g, '').substring(0, 10);
    const transactionId = uuidv4().replace(/-/g, '').substring(0, 10);
    const terminalAPIPaymentRequest: TerminalApiRequest = {
      SaleToPOIRequest: {
        MessageHeader: {
          ProtocolVersion: '3.0',
          MessageCategory: MessageCategoryType.Payment,
          MessageClass: MessageClassType.Service,
          MessageType: MessageType.Request,
          POIID: ADYEN_TERMINAL_ID,
          SaleID: ADYEN_SALE_ID,
          ServiceID: serviceId,
        },
        PaymentRequest: {
          PaymentTransaction: {
            AmountsReq: {
              Currency: currency,
              RequestedAmount: amount,
            },
          },
          SaleData: {
            SaleTransactionID: {
              TransactionID: transactionId,
              TimeStamp: new Date().toISOString(),
            },
          },
        },
      },
    };
    const terminalLocalAPI = new TerminalLocalAPI(this.client);

    const terminalApiResponse: TerminalApiResponse =
      await terminalLocalAPI.request(
        terminalAPIPaymentRequest,
        this.securityKey,
      );

    const res = terminalApiResponse.SaleToPOIResponse.PaymentResponse.Response;
    if (res.Result === ResultType.Failure) {
      throw new PaymentException(
        `${res.ErrorCondition} - ${decodeURI(res.AdditionalResponse)}`,
      );
    }
...
Herlin
  • 353
  • 1
  • 5
  • 12