Pritesh Mahajan's answer was on the right track, but I don't know how it was working for him, as the throws and returns break the code. Here is a more complete example with the ctrl.execute converted into a promise for use with await.
This example also does away with the need for a global variable which should never be used for a transactional value in Node.
I also use the to() function from the togo package that implements the to functionality from the go language, eliminating the need for large try / catch blocks.
This example is a fully working example for a node project using ES6 modules running NodeJS 14 or later.
This is setup for use with Accept.js using the Authorize.Net hosted payment information form to collect the card information in a PCI-DSS SAQ A compliant way.
See https://developer.authorize.net/api/reference/features/acceptjs.html#Using_the_Hosted_Payment_Information_Form for more details.
The only data needed for a successful transaction is the authData and the paymentData. The shipping data is included as an example, if you need any of the other data that the Authorize.NET API accommodates, it would be easy to modify this function to support it.
import authorizenet from "authorizenet";
const ApiContracts = authorizenet.APIContracts;
const ApiControllers = authorizenet.APIControllers;
const SDKConstants = authorizenet.Constants;
function to (promise)
{
return promise
.then(val => [null, val])
.catch(err => [err]);
}
async function chargeCustomer (params = {}) {
/*
params = {
authData: {
api_login_id,
transaction_key,
endpoint
}
paymentData: {
opaqueData: {
dataDescriptor,
dataValue
},
amount
}
shipTo: {
firstName,
lastName,
company,
address,
city,
state,
zip,
country
}
}
*/
if ((!params?.authData?.api_login_id) || (!params?.authData?.transaction_key)) {
throw "missing credentials";
}
let merchantAuthenticationType = new ApiContracts.MerchantAuthenticationType();
merchantAuthenticationType.setName(params.authData.api_login_id);
merchantAuthenticationType.setTransactionKey(params.authData.transaction_key);
let opaqueData = new ApiContracts.OpaqueDataType();
opaqueData.setDataDescriptor(params.opaqueData.dataDescriptor);
opaqueData.setDataValue(params.opaqueData.dataValue);
let paymentType = new ApiContracts.PaymentType();
paymentType.setOpaqueData(opaqueData);
let shipTo = new ApiContracts.CustomerAddressType();
shipTo.setFirstName(params?.shipTo?.firstName || null);
shipTo.setLastName(params?.shipTo?.last_name || null);
shipTo.setCompany(params?.shipTo?.company || null);
shipTo.setAddress(params?.shipTo?.address || null);
shipTo.setCity(params?.shipTo?.city || null);
shipTo.setState(params?.shipTo?.state || null);
shipTo.setZip(params?.shipTo?.zip || null);
shipTo.setCountry(params?.shipTo?.country || null);
let transactionRequestType = new ApiContracts.TransactionRequestType();
transactionRequestType.setTransactionType(ApiContracts.TransactionTypeEnum.AUTHCAPTURETRANSACTION);
transactionRequestType.setPayment(paymentType);
transactionRequestType.setAmount(params?.paymentData?.amount);
transactionRequestType.setShipTo(shipTo);
let createRequest = new ApiContracts.CreateTransactionRequest();
createRequest.setMerchantAuthentication(merchantAuthenticationType);
createRequest.setTransactionRequest(transactionRequestType);
let ctrl = new ApiControllers.CreateTransactionController(createRequest.getJSON());
if (params?.authData?.endpoint === "production") {
ctrl.setEnvironment(SDKConstants.endpoint.production);
}
let [err, response] = await to(new Promise((resolve, reject) => {
ctrl.execute( () => {
let apiResponse = ctrl.getResponse();
let response = new ApiContracts.CreateTransactionResponse(apiResponse);
if (response != null) {
if (response.getMessages().getResultCode() == ApiContracts.MessageTypeEnum.OK) {
if (response.getTransactionResponse().getMessages() != null) {
console.log(JSON.stringify(response));
resolve(response);
} else {
console.debug('Failed Transaction.');
if (response.getTransactionResponse().getErrors() != null) {
reject(response.getTransactionResponse().getErrors())
}
}
} else {
reject('null response from Authorize.Net');
}
};
});
}));
if (err) {
throw err;
}
return response;
}