@montarist/nestpay-api-v2
Version:
Unofficial comprehensive TypeScript API client for Nestpay payment gateway with 3D Secure support
235 lines • 8.86 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.errorHandler = exports.ErrorHandler = exports.ConfigurationError = exports.HashVerificationError = exports.ThreeDSecureError = exports.PaymentError = exports.ApiError = exports.ValidationError = exports.NestpayError = void 0;
const enums_1 = require("../types/enums");
/**
* Base Nestpay error class
*/
class NestpayError extends Error {
constructor(message, code, details) {
super(message);
this.name = 'NestpayError';
this.code = code;
this.details = details;
// Maintains proper stack trace for where our error was thrown (only available on V8)
if (Error.captureStackTrace) {
Error.captureStackTrace(this, NestpayError);
}
}
}
exports.NestpayError = NestpayError;
/**
* Validation error class
*/
class ValidationError extends NestpayError {
constructor(errors, details) {
const message = `Validation failed: ${errors.join(', ')}`;
super(message, 'VALIDATION_ERROR', details);
this.name = 'ValidationError';
this.validationErrors = errors;
}
}
exports.ValidationError = ValidationError;
/**
* API communication error class
*/
class ApiError extends NestpayError {
constructor(message, statusCode, response, code, details) {
super(message, code, details);
this.name = 'ApiError';
this.statusCode = statusCode;
this.response = response;
}
}
exports.ApiError = ApiError;
/**
* Payment processing error class
*/
class PaymentError extends NestpayError {
constructor(message, code, transactionId, orderId, procReturnCode, details) {
super(message, code, details);
this.name = 'PaymentError';
this.transactionId = transactionId;
this.orderId = orderId;
this.procReturnCode = procReturnCode;
}
}
exports.PaymentError = PaymentError;
/**
* 3D Secure specific error class
*/
class ThreeDSecureError extends NestpayError {
constructor(message, code, mdStatus, cavv, eci, details) {
super(message, code, details);
this.name = 'ThreeDSecureError';
this.mdStatus = mdStatus;
this.cavv = cavv;
this.eci = eci;
}
}
exports.ThreeDSecureError = ThreeDSecureError;
/**
* Hash verification error class
*/
class HashVerificationError extends NestpayError {
constructor(message, expectedHash, receivedHash, details) {
super(message, 'HASH_VERIFICATION_ERROR', details);
this.name = 'HashVerificationError';
this.expectedHash = expectedHash;
this.receivedHash = receivedHash;
}
}
exports.HashVerificationError = HashVerificationError;
/**
* Configuration error class
*/
class ConfigurationError extends NestpayError {
constructor(message, details) {
super(message, 'CONFIGURATION_ERROR', details);
this.name = 'ConfigurationError';
}
}
exports.ConfigurationError = ConfigurationError;
/**
* Error handler utility class
*/
class ErrorHandler {
/**
* Create error response object
* @param error Error object
* @returns Formatted error response
*/
static createErrorResponse(error) {
if (error instanceof NestpayError) {
return {
success: false,
errorCode: error.code,
errorMessage: error.message,
details: error.details
};
}
return {
success: false,
errorMessage: error.message || 'An unexpected error occurred'
};
}
/**
* Parse API error response
* @param response API response
* @param statusCode HTTP status code
* @returns Parsed error or null if no error
*/
static parseApiError(response, statusCode) {
if (!response) {
return new ApiError('Empty response received', statusCode);
}
// Check for common error indicators
if (response.Response === 'Error' || response.response === 'Error') {
const errorMessage = response.ErrMsg || response.errorMessage || 'Payment processing failed';
const procReturnCode = response.ProcReturnCode || response.procReturnCode;
const errorCode = this.mapProcReturnCodeToErrorCode(procReturnCode);
return new PaymentError(errorMessage, errorCode, response.TransId || response.transactionId, response.OrderId || response.orderId, procReturnCode, response);
}
// Check for 3D Secure errors
if (response.mdStatus && response.mdStatus !== '1') {
const errorMessage = this.getThreeDErrorMessage(response.mdStatus);
return new ThreeDSecureError(errorMessage, 'THREED_ERROR', response.mdStatus, response.cavv, response.eci, response);
}
// Check for validation errors
if (response.errors && Array.isArray(response.errors)) {
return new ValidationError(response.errors);
}
return null;
}
/**
* Map ProcReturnCode to internal error codes
* @param procReturnCode Process return code from API
* @returns Mapped error code
*/
static mapProcReturnCodeToErrorCode(procReturnCode) {
const errorCodeMap = {
'01': enums_1.ErrorCode.INVALID_MERCHANT,
'02': enums_1.ErrorCode.INVALID_AMOUNT,
'03': enums_1.ErrorCode.INVALID_CARD,
'04': enums_1.ErrorCode.INSUFFICIENT_FUNDS,
'05': enums_1.ErrorCode.EXPIRED_CARD,
'06': enums_1.ErrorCode.INVALID_CVV,
'07': enums_1.ErrorCode.TRANSACTION_NOT_FOUND,
'08': enums_1.ErrorCode.DUPLICATE_TRANSACTION,
'99': enums_1.ErrorCode.SYSTEM_ERROR
};
return errorCodeMap[procReturnCode || ''] || enums_1.ErrorCode.SYSTEM_ERROR;
}
/**
* Get 3D Secure error message based on mdStatus
* @param mdStatus MD status code
* @returns Error message
*/
static getThreeDErrorMessage(mdStatus) {
const statusMessages = {
'0': '3D Secure verification failed',
'2': '3D Secure verification could not be completed',
'3': '3D Secure verification failed - invalid merchant',
'4': '3D Secure verification failed - invalid card',
'5': '3D Secure verification failed - invalid transaction',
'6': '3D Secure verification failed - technical error',
'7': '3D Secure verification failed - system error',
'8': '3D Secure verification failed - unknown card'
};
return statusMessages[mdStatus] || `3D Secure verification failed with status: ${mdStatus}`;
}
/**
* Determine if error is retryable
* @param error Error object
* @returns True if error is retryable
*/
static isRetryableError(error) {
if (error instanceof ApiError) {
// Network errors or 5xx status codes are retryable
return !error.statusCode || error.statusCode >= 500;
}
if (error instanceof PaymentError) {
// Some payment errors are retryable
const retryableCodes = [enums_1.ErrorCode.SYSTEM_ERROR];
return retryableCodes.includes(error.code);
}
return false;
}
/**
* Get user-friendly error message
* @param error Error object
* @returns User-friendly error message
*/
static getUserFriendlyMessage(error) {
if (error instanceof ValidationError) {
return 'Please check your input and try again.';
}
if (error instanceof PaymentError) {
switch (error.code) {
case enums_1.ErrorCode.INVALID_CARD:
return 'Invalid card information. Please check your card details.';
case enums_1.ErrorCode.INSUFFICIENT_FUNDS:
return 'Insufficient funds. Please try a different card.';
case enums_1.ErrorCode.EXPIRED_CARD:
return 'Your card has expired. Please use a different card.';
case enums_1.ErrorCode.INVALID_CVV:
return 'Invalid CVV code. Please check your card security code.';
default:
return 'Payment processing failed. Please try again.';
}
}
if (error instanceof ThreeDSecureError) {
return '3D Secure verification failed. Please try again or use a different card.';
}
if (error instanceof ApiError) {
return 'Service temporarily unavailable. Please try again later.';
}
return 'An unexpected error occurred. Please try again.';
}
}
exports.ErrorHandler = ErrorHandler;
/**
* Default error handler instance
*/
exports.errorHandler = new ErrorHandler();
//# sourceMappingURL=errors.js.map