英文:
Adyen ApiException unable to get local issuer certificate
问题
I'm trying to set up a test payment session on a Verifone P400 Plus terminal from Adyen. I'm following this guide using Node.js, specifically version "13.1.3" of the "@adyen/api-library".
The plan is to run the code in an Alpine container, but during testing, I'm on a Mac. I downloaded the root certificate and ran OpenSSL on it using the command:
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 environment variables. Then I ran my code:
... (imports + load envs) ...
// Rest of your code...
The result I get is:
ApiException {
name: 'ApiException',
message: 'unable to get local issuer certificate',
statusCode: 500
}
If the certificate path is pointing to the .pem file, it does not work at all. I'm getting the same responses under Alpine Linux as on macOS. Any ideas?
PS: When it comes to Linux, I installed the certificate using this:
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 ..
Is there anything specific you'd like to know or clarify regarding this code issue?
英文:
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 ..
答案1
得分: 1
请尝试首先将.crt文件添加到项目的根目录,并将以下行添加到配置中以进行双重检查,以查看是否与库证书验证有关:
config.certificatePath = "./cert.cer";
另外,为了确保一切正常,您可以在配置中设置环境,而不是通过客户端设置。
如果您能够使用这种方式使其工作,请告诉我,这样我们可以从那里进行故障排除。
英文:
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.
答案2
得分: 1
我最终使用了PEM证书使其工作。缺失的部分是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)}`,
);
}
...
英文:
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)}`,
);
}
...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论