@hipay/hipay-enterprise-sdk-nodejs
Version:
The HiPay Enterprise SDK for NodeJS is a library for developers who want to integrate HiPay Enterprise payment methods to any NodeJS platform.
540 lines (443 loc) • 20.6 kB
JavaScript
'use strict';
const InvalidArgumentException = require('./Error/InvalidArgumentException');
const Configuration = require('./Gateway/HTTP/Configuration/Configuration');
const SimpleHTTPClient = require('./Gateway/HTTP/SimpleHTTPClient');
const PIDataClient = require('./Gateway/PIDataClient/PIDataClient');
const TransactionMapper = require('./Gateway/Response/Mapper/TransactionMapper');
const TransactionV3Mapper = require('./Gateway/Response/TransactionV3/Mapper/TransactionMapper');
const OperationMapper = require('./Gateway/Response/Mapper/OperationMapper');
const HostedPaymentPageMapper = require('./Gateway/Response/Mapper/HostedPaymentPageMapper');
const SecuritySettingsMapper = require('./Gateway/Response/Mapper/SecuritySettingsMapper');
const PaymentCardTokenMapper = require('./Gateway/Response/Mapper/PaymentCardTokenMapper');
const AvailablePaymentProductMapper = require('./Gateway/Response/Mapper/AvailablePaymentProductMapper');
const AbstractModel = require('./Gateway/Request/Model/AbstractModel');
const AbstractRequestPart = require('./Gateway/Request/AbstractRequestPart');
const OrderRequest = require('./Gateway/Request/OrderRequest');
const HostedPaymentPageRequest = require('./Gateway/Request/HostedPaymentPageRequest');
const MaintenanceRequest = require('./Gateway/Request/MaintenanceRequest');
const AvailablePaymentProductRequest = require('./Gateway/Request/Info/AvailablePaymentProductRequest');
const CustomerBillingInfoRequest = require('./Gateway/Request/Info/CustomerBillingInfoRequest');
const CustomerShippingInfoRequest = require('./Gateway/Request/Info/CustomerShippingInfoRequest');
const DeliveryShippingInfoRequest = require('./Gateway/Request/Info/DeliveryShippingInfoRequest');
const ThreeDSTwoModels = require('./Gateway/Request/Model/ThreeDSTwo');
const PaymentMethods = require('./Gateway/Request/PaymentMethod');
const TransactionEnums = require('./Enum/Transaction');
const TransactionV3Enums = require('./Enum/Transaction/V3');
const ThreeDSTwoEnums = require('./Enum/ThreeDSTwo');
const HelperEnums = require('./Enum/Helper');
const CustomerEnums = require('./Enum/Customer');
const CartEnums = require('./Enum/Cart');
const DataCollections = require('./Data');
class HiPay {
/**
* @return {String} ENDPOINT_NEW_ORDER endpoint to create a new transaction order
*/
static get ENDPOINT_NEW_ORDER() {
return '/rest/v1/order';
}
/**
* @return {String} METHOD_NEW_ORDER http method to create a new transaction order
*/
static get METHOD_NEW_ORDER() {
return 'POST';
}
/**
* @return {String} ENDPOINT_HOSTED_PAYMENT_PAGE endpoint to call Hosted payment page
*/
static get ENDPOINT_HOSTED_PAYMENT_PAGE() {
return '/rest/v1/hpayment';
}
/**
* @return {String} ENDPOINT_HOSTED_PAYMENT_PAGE_V2 endpoint to call new Hosted payment page
*/
static get ENDPOINT_HOSTED_PAYMENT_PAGE_V2() {
return '/v1/hpayment';
}
/**
* @return {String} METHOD_HOSTED_PAYMENT_PAGE http method to call Hosted payment page
*/
static get METHOD_HOSTED_PAYMENT_PAGE() {
return 'POST';
}
/**
* @return {String} ENDPOINT_MAINTENANCE_OPERATION endpoint to do a maintenance operation (capture, refund, accept, etc, ...)
*/
static get ENDPOINT_MAINTENANCE_OPERATION() {
return '/rest/v1/maintenance/transaction/{transaction}';
}
/**
* @return {String} METHOD_MAINTENANCE_OPERATION http method to do a maintenance operation
*/
static get METHOD_MAINTENANCE_OPERATION() {
return 'POST';
}
/**
* @return {String} ENDPOINT_TRANSACTION_DETAILS endpoint to call transaction information
*/
static get ENDPOINT_TRANSACTION_INFORMATION() {
return '/rest/v1/transaction/{transaction}';
}
/**
* @return {String} ENDPOINT_TRANSACTION_DETAILS endpoint to call transaction information
*/
static get ENDPOINT_TRANSACTION_V3_INFORMATION() {
return '/v3/transaction/{transaction}';
}
/**
* @return {String} METHOD_TRANSACTION_DETAILS http method to call transaction information
*/
static get METHOD_TRANSACTION_INFORMATION() {
return 'GET';
}
/**
* @return {String} METHOD_TRANSACTIONV3_DETAILS http method to call transactionv3 information
*/
static get METHOD_TRANSACTION_V3_INFORMATION() {
return 'GET';
}
/**
* @return {String} ENDPOINT_ORDER_TRANSACTION_INFORMATION endpoint to call transaction information
*/
static get ENDPOINT_ORDER_TRANSACTION_INFORMATION() {
return '/rest/v1/transaction';
}
/**
* @return {String} METHOD_ORDER_TRANSACTION_INFORMATION http method to call transaction information
*/
static get METHOD_ORDER_TRANSACTION_INFORMATION() {
return 'GET';
}
/**
* @return {String} ENDPOINT_SECURITY_SETTINGS endpoint to call security settings information
*/
static get ENDPOINT_SECURITY_SETTINGS() {
return '/rest/v2/security-settings';
}
/**
* @return {String} METHOD_ORDER_TRANSACTION_INFORMATION http method to call transaction information
*/
static get METHOD_SECURITY_SETTINGS() {
return 'GET';
}
/**
* @var {String} ENDPOINT_LOOKUP_TOKEN ENDPOINT_LOOKUP_TOKEN endpoint to get vault information by token
*/
static get ENDPOINT_LOOKUP_TOKEN() {
return 'v2/token/{token}';
}
/**
* @var {String} METHOD_LOOKUP_TOKEN METHOD_LOOKUP_TOKEN http method to get vault information by token
*/
static get METHOD_LOOKUP_TOKEN() {
return 'GET';
}
/**
* @return {String} ENDPOINT_AVAILABLE_PAYMENT_PRODUCT endpoint to get available payment products
*/
static get ENDPOINT_AVAILABLE_PAYMENT_PRODUCT() {
return 'rest/v2/available-payment-products';
}
/**
* @return {String} METHOD_AVAILABLE_PAYMENT_PRODUCT http method to get available payment products
*/
static get METHOD_AVAILABLE_PAYMENT_PRODUCT() {
return 'GET';
}
static get API_ENV_STAGE() {
return Configuration.API_ENV_STAGE;
}
static get API_ENV_PRODUCTION() {
return Configuration.API_ENV_PRODUCTION;
}
/**
* @type {Configuration}
* @private
*/
_configuration;
/**
* Creates an instance of the SDK
*
* @param {Object} options
* @param {String} [options.apiToken=null] Your authentication token for the HiPay API. Either this or username and password must be specified.
* @param {String} [options.apiUsername=null] Your username for the HiPay API. Either username and password or token must be specified.
* @param {String} [options.apiPassword=null] Your password for the HiPay API. Either username and password or token must be specified.
* @param {String} [options.apiEnv=Configuration.API_ENV_STAGE] The HiPay API environment (production or stage), defaults to stage
* @param {String} [options.apiHTTPHeaderAccept='application/json'] The accept header to set for the requests. Defaults to JSON
* @param {Object} [options.proxy={}] Proxy information to add to the requests
* @param {String} [options.proxy.host] Your proxy host
* @param {Number} [options.proxy.port] Your proxy port
* @param {Object} [options.proxy.auth] Your proxy authentication information
* @param {String} [options.proxy.auth.username] Proxy authentication Username
* @param {String} [options.proxy.auth.password] Proxy authentication Password
* @param {Number} [options.timeout=35] The timeout of the requests. Defaults to 35 seconds
* @param {String} [options.httpUserAgent='HiPayEnterprise/1.0 (SDK NodeJS)'] The user agent of the requests.
*/
constructor(options) {
this._configuration = new Configuration(options);
this._clientProvider = new SimpleHTTPClient(this._configuration);
}
/**
* Request New Order
* @param {OrderRequest} orderRequest
* @param {Object} [options = {}] options
* @param {String} [options.dataId=null] Custom dataId to use in call to Data API
* @returns {Promise<import('./Gateway/Response/Transaction')>}
*/
async requestNewOrder(orderRequest, { dataId = null } = {}) {
if (!(orderRequest instanceof OrderRequest)) {
orderRequest = new OrderRequest(orderRequest);
}
const piDataClient = new PIDataClient(this._clientProvider);
const piDataId = piDataClient.getDataId(dataId);
const formattedParams = {};
HiPay.#formatParams(orderRequest, formattedParams);
const response = await this._clientProvider.request(HiPay.METHOD_NEW_ORDER, HiPay.ENDPOINT_NEW_ORDER, {
baseUrl: this._configuration.apiEndpoint,
body: formattedParams
});
const transactionMapper = new TransactionMapper(response.body);
const transaction = transactionMapper.mappedObject;
if (piDataId) {
piDataClient.sendData(piDataClient.getOrderData(piDataId, orderRequest, transaction));
}
return transaction;
}
/**
* Executes Hosted Payment Page request
* @param {HostedPaymentPageRequest} pageRequest
* @param {Object} [options = {}] options
* @param {String} [options.dataId=null] Custom dataId to use in call to Data API
* @param {Boolean} [options.legacy=false] Call the legacy payment page
* @returns {Promise<import('./Gateway/Response/Transaction')>} Resolves generate page URL
*/
async requestHostedPaymentPage(pageRequest, { legacy = false, dataId = null } = {}) {
if (!(pageRequest instanceof HostedPaymentPageRequest)) {
pageRequest = new HostedPaymentPageRequest(pageRequest);
}
// Data API client
const piDataClient = new PIDataClient(this._clientProvider);
// Gets ID for Data API
const piDataId = piDataClient.getDataId(dataId);
const formattedParams = {};
HiPay.#formatParams(pageRequest, formattedParams);
const endpointHpayment = legacy ? HiPay.ENDPOINT_HOSTED_PAYMENT_PAGE : HiPay.ENDPOINT_HOSTED_PAYMENT_PAGE_V2;
const hpaymentUrl = legacy ? this._configuration.apiEndpoint : this._configuration.hpaymentApiEndpoint;
// Call Hosted Payment Page generation endpoint
const response = await this._clientProvider.request(HiPay.METHOD_HOSTED_PAYMENT_PAGE, endpointHpayment, {
baseUrl: hpaymentUrl,
body: formattedParams,
additionalHeaders: {
['X-HIPAY-DATA-ID']: piDataId
}
});
const transactionMapper = new HostedPaymentPageMapper(response.body);
const transaction = transactionMapper.mappedObject;
// If Data API ID was generated, send data to DATA API
if (piDataId) {
piDataClient.sendData(piDataClient.getOrderData(piDataId, pageRequest, transaction));
}
return transaction;
}
/**
* Executes a maintenance Operation
* @param {MaintenanceRequest} maintenanceRequest
* @param {String} transactionReference Transaction targeted by the maintenance
* @returns {Promise<import('./Gateway/Response/Operation')>}
*/
async requestMaintenanceOperation(maintenanceRequest, transactionReference) {
if (!(maintenanceRequest instanceof MaintenanceRequest)) {
maintenanceRequest = new MaintenanceRequest(maintenanceRequest);
}
if (!transactionReference || typeof transactionReference !== 'string') {
throw new InvalidArgumentException('Transaction reference must be a string');
}
const formattedParams = {};
HiPay.#formatParams(maintenanceRequest, formattedParams);
const endPoint = HiPay.ENDPOINT_MAINTENANCE_OPERATION.split('{transaction}').join(transactionReference);
const response = await this._clientProvider.request(HiPay.METHOD_MAINTENANCE_OPERATION, endPoint, {
baseUrl: this._configuration.apiEndpoint,
body: formattedParams
});
const operationMapper = new OperationMapper(response.body);
return operationMapper.mappedObject;
}
/**
* Returns a transaction information
*
* @param {String} transactionReference The HiPay transaction reference
* @returns {Promise<import('./Gateway/Response/Transaction')|null>}
*/
async requestTransactionInformation(transactionReference) {
if (!transactionReference || typeof transactionReference !== 'string') {
throw new InvalidArgumentException('Transaction reference must be a string');
}
const endPoint = HiPay.ENDPOINT_TRANSACTION_INFORMATION.split('{transaction}').join(transactionReference);
const response = await this._clientProvider.request(HiPay.METHOD_TRANSACTION_INFORMATION, endPoint, {
baseUrl: this._configuration.apiEndpoint
});
if (response.body.transaction) {
response.body.transaction.basket = response.body.basket;
const transactionMapper = new TransactionMapper(response.body.transaction);
return transactionMapper.mappedObject;
} else {
return null;
}
}
/**
* Returns a transaction V3 information
*
* @param {String} transactionReference The HiPay transaction v3 reference
* @returns {Promise<import('./Gateway/Response/TransactionV3/Transaction')|null>}
*/
async requestTransactionV3Information(transactionReference) {
if (!transactionReference || typeof transactionReference !== 'string') {
throw new InvalidArgumentException('TransactionV3 reference must be a string');
}
const endPoint = HiPay.ENDPOINT_TRANSACTION_V3_INFORMATION.split('{transaction}').join(transactionReference);
const response = await this._clientProvider.request(HiPay.METHOD_TRANSACTION_V3_INFORMATION, endPoint, {
baseUrl: this._configuration.consultationApiEndpoint
});
if (response.body) {
const transactionMapper = new TransactionV3Mapper(response.body);
return transactionMapper.mappedObject;
} else {
return null;
}
}
/**
* Returns a transaction information based on a order ID
*
* @param {String} orderId The order id to search for
* @returns {Promise<Array<import('./Gateway/Response/Transaction')>>}
*/
async requestOrderTransactionInformation(orderId) {
if (!orderId || typeof orderId !== 'string') {
throw new InvalidArgumentException('Order ID must be a string');
}
const transactions = [];
const endPoint = `${HiPay.ENDPOINT_ORDER_TRANSACTION_INFORMATION}?orderid=${orderId}`;
const response = await this._clientProvider.request(HiPay.METHOD_ORDER_TRANSACTION_INFORMATION, endPoint, {
baseUrl: this._configuration.apiEndpoint
});
if (response.body.transaction) {
// Single transaction response
if (response.body.transaction.state) {
const transactionMapper = new TransactionMapper(response.body.transaction);
transactions.push(transactionMapper.mappedObject);
} else {
// Array of transactions with format : {index => trx}
for (const transaction of Object.values(response.body.transaction)) {
const transactionMapper = new TransactionMapper(transaction);
transactions.push(transactionMapper.mappedObject);
}
}
}
return transactions;
}
/**
* Returns available payment products
*
* @param {String} availablePaymentProductRequest The HiPay available payment product request
* @returns {Promise<Array<import('./Gateway/Response/AvailablePaymentProduct')>>}
*/
async requestAvailablePaymentProduct(availablePaymentProductRequest) {
if (!(availablePaymentProductRequest instanceof AvailablePaymentProductRequest)) {
availablePaymentProductRequest = new AvailablePaymentProductRequest(availablePaymentProductRequest);
}
const formattedParams = {};
HiPay.#formatParams(availablePaymentProductRequest, formattedParams);
const endPoint = `${HiPay.ENDPOINT_AVAILABLE_PAYMENT_PRODUCT}.json?${availablePaymentProductRequest.toQueryString()}`;
const response = await this._clientProvider.request(HiPay.METHOD_AVAILABLE_PAYMENT_PRODUCT, endPoint, {
baseUrl: this._configuration.apiEndpoint,
body: formattedParams
});
let availablePaymentProducts = [];
response.body.forEach((productData) => {
const availablePaymentProductMapper = new AvailablePaymentProductMapper(productData);
const availablePaymentProduct = availablePaymentProductMapper.mappedObject;
availablePaymentProducts.push(availablePaymentProduct);
});
return availablePaymentProducts;
}
/**
* Returns security settings
*
* @returns {Promise<import('./Gateway/Response/SecuritySettings')>}
*/
async requestSecuritySettings() {
const response = await this._clientProvider.request(HiPay.METHOD_SECURITY_SETTINGS, HiPay.ENDPOINT_SECURITY_SETTINGS, {
baseUrl: this._configuration.apiEndpoint
});
const securitySettingsMapper = new SecuritySettingsMapper(response.body);
return securitySettingsMapper.mappedObject;
}
/**
* Returns vault information by token
*
* @param {String} token
* @param {String} requestId
* @returns {Promise<import('./Gateway/Response/PaymentCardToken')>}
*/
async requestLookupToken(token, requestId = '0') {
let endpoint = HiPay.ENDPOINT_LOOKUP_TOKEN.replace('{token}', token);
endpoint += `?request_id=${requestId}`;
const response = await this._clientProvider.request(HiPay.METHOD_LOOKUP_TOKEN, endpoint, {
baseUrl: this._configuration.secureVaultEndpoint
});
const paymentCardTokenMapper = new PaymentCardTokenMapper(response.body);
return paymentCardTokenMapper.mappedObject;
}
/**
* Formats parameters recursively for order API
* @param {Object} object The object to format
* @param {Object} formattedParams The formatted params to update
*/
static #formatParams(object, formattedParams) {
for (const prop in object) {
if (Object.hasOwn(object, prop)) {
let value = object[prop];
if (typeof value !== 'undefined' && value !== null) {
if (typeof value === 'object') {
if (value instanceof AbstractModel) {
if (value.cleanNullValues()) {
formattedParams[HiPay.#camelCaseToSnakeCase(prop)] = value.toJson();
}
} else if (value instanceof AbstractRequestPart) {
HiPay.#formatParams(value, formattedParams);
} else {
formattedParams[HiPay.#camelCaseToSnakeCase(prop)] = JSON.stringify(value);
}
} else {
formattedParams[HiPay.#camelCaseToSnakeCase(prop)] = value;
}
}
}
}
}
/**
* Transforms a camelCase string into a snake_case string
* @param {String} propName
*/
static #camelCaseToSnakeCase(propName) {
return propName.replace(/([A-Z])/g, '_$1').toLowerCase();
}
}
HiPay.OrderRequest = OrderRequest;
HiPay.HostedPaymentPageRequest = HostedPaymentPageRequest;
HiPay.MaintenanceRequest = MaintenanceRequest;
HiPay.AvailablePaymentProductRequest = AvailablePaymentProductRequest;
HiPay.CustomerBillingInfoRequest = CustomerBillingInfoRequest;
HiPay.CustomerShippingInfoRequest = CustomerShippingInfoRequest;
HiPay.DeliveryShippingInfoRequest = DeliveryShippingInfoRequest;
HiPay.PaymentMethods = PaymentMethods;
HiPay.Transaction = TransactionEnums;
HiPay.TransactionV3 = TransactionV3Enums;
HiPay.ThreeDSTwo = {
...ThreeDSTwoEnums,
...ThreeDSTwoModels
};
HiPay.Helper = HelperEnums;
HiPay.Customer = CustomerEnums;
HiPay.Cart = CartEnums;
HiPay.DataCollections = DataCollections;
module.exports = HiPay;