Added the Payment Data Persistence API
This commit is contained in:
parent
45d57cee8d
commit
a2c2ed2a68
@ -51,7 +51,7 @@ export class PRICE_DTO {
|
||||
// @Max(999999999, {
|
||||
// message: 'Property P_PRICE must not exceed 999999999',
|
||||
// })
|
||||
@Min(0.1, { message: 'Property P_PRICE must be greater than zero' })
|
||||
@Min(0.01, { message: 'Property P_PRICE must be greater than zero' })
|
||||
// @IsInt({ message: 'Property P_PRICE allows only whole numbers' })
|
||||
@IsNumber({}, { message: 'Property P_PRICE must be a number' })
|
||||
@Transform(({ value }) => Number(value))
|
||||
@ -59,6 +59,33 @@ export class PRICE_DTO {
|
||||
P_PRICE: number;
|
||||
}
|
||||
|
||||
export class PAYMENTAMOUNT_DTO {
|
||||
@ApiProperty({ required: true })
|
||||
// @Max(999999999, {
|
||||
// message: 'Property P_PRICE must not exceed 999999999',
|
||||
// })
|
||||
@Min(0.01, { message: 'Property P_PAYMENTAMOUNT must be greater than zero' })
|
||||
// @IsInt({ message: 'Property P_PRICE allows only whole numbers' })
|
||||
@IsNumber({}, { message: 'Property P_PAYMENTAMOUNT must be a number' })
|
||||
@Transform(({ value }) => Number(value))
|
||||
@IsDefined({ message: 'Property P_PAYMENTAMOUNT is required' })
|
||||
P_PAYMENTAMOUNT: number;
|
||||
}
|
||||
|
||||
export class PAYMENTSTATUS_DTO {
|
||||
@ApiProperty({ required: true })
|
||||
@IsString({ message: 'Property P_STATUS must be a string' })
|
||||
@IsDefined({ message: 'Property P_STATUS is required' })
|
||||
P_STATUS: string;
|
||||
}
|
||||
|
||||
export class PAYMENTERROR_DTO {
|
||||
@ApiProperty({ required: true })
|
||||
@IsString({ message: 'Property P_PAYMENTERROR must be a string' })
|
||||
@IsDefined({ message: 'Property P_PAYMENTERROR is required' })
|
||||
P_PAYMENTERROR: string | null = null;
|
||||
}
|
||||
|
||||
export class DESCRIPTION_DTO {
|
||||
@ApiProperty({ required: true })
|
||||
@IsString()
|
||||
|
||||
@ -5,7 +5,8 @@ import {
|
||||
COUNTRYTABLE_DTO, CUSTCOURIERNO_DTO, DELIVERYMETHOD_DTO, DELIVERYTYPE_DTO,
|
||||
DESCRIPTION_DTO,
|
||||
EXIBITIONS_FAIR_FLAG_DTO, EXTENSION_PERIOD_DTO, FORMOFSECURITY_DTO, GLTABLE_DTO, GLTABLE_ITEMNO_OPTIONAL_DTO, GOODS_COUNTRY_DTO, GOODS_PORT_DTO, HEADERID_DTO,
|
||||
HORSE_FLAG_DTO, INSPROTECTION_DTO, ITEMNO_DTO, LDIPROTECTION_DTO, ORDERID_DTO, ORDERTYPE_DTO, PAYMENTMETHOD_DTO,
|
||||
HORSE_FLAG_DTO, INSPROTECTION_DTO, ITEMNO_DTO, LDIPROTECTION_DTO, ORDERID_DTO, ORDERTYPE_DTO, PAYMENTAMOUNT_DTO, PAYMENTERROR_DTO, PAYMENTMETHOD_DTO,
|
||||
PAYMENTSTATUS_DTO,
|
||||
PRICE_DTO,
|
||||
PRINTGL_DTO,
|
||||
PROF_EQUIPMENT_FLAG_DTO, REASON_CODE_DTO, REFNO_DTO, SHIPADDRID_DTO, SHIPCONTACTID_DTO, SHIPNAME_DTO, SHIPTOTYPE_DTO, USSETS_DTO
|
||||
@ -71,7 +72,10 @@ export class SaveExtensionApplicationDTO extends (IntersectionType(
|
||||
export class PrintCarnetDTO extends (IntersectionType(SPID_DTO, HEADERID_DTO, PRINTGL_DTO)) { }
|
||||
export class PrintGLDTO extends (IntersectionType(SPID_DTO, HEADERID_DTO)) { }
|
||||
export class CapturePaymentDTO extends (IntersectionType(ORDERID_DTO)) { }
|
||||
export class InitiatePaymentDTO extends (IntersectionType(PRICE_DTO, DESCRIPTION_DTO)){}
|
||||
export class InitiatePaymentDTO extends (IntersectionType(PRICE_DTO, DESCRIPTION_DTO)) { }
|
||||
export class GetOrderDetailsDTO extends (IntersectionType(ORDERID_DTO)) { }
|
||||
export class GetPaymentHistoryDTO extends (IntersectionType(APPLICATIONNAME_DTO, USERID_DTO)) { }
|
||||
export class SaveHistoryDTO extends (IntersectionType(APPLICATIONNAME_DTO, ORDERID_DTO, PAYMENTAMOUNT_DTO, PAYMENTSTATUS_DTO, USERID_DTO, PartialType(PAYMENTERROR_DTO))) { }
|
||||
|
||||
export class CreateApplicationDTO extends IntersectionType(
|
||||
SPID_DTO, CLIENTID_DTO, LOCATIONID_DTO, USERID_DTO, APPLICATIONNAME_DTO,
|
||||
|
||||
@ -8,7 +8,7 @@ import {
|
||||
AddGenerallistItemsDTO,
|
||||
CA_UpdateHolderDTO,
|
||||
CapturePaymentDTO,
|
||||
CarnetProcessingCenterDTO, CarnetProcessingCenterDTO2, CopyCarnetDTO, CreateApplicationDTO, DeleteGenerallistItemsDTO, EditGenerallistItemsDTO, GetCarnetControlCenterDTO, GetExtendedSectionDTO, InitiatePaymentDTO, PrintCarnetDTO, PrintGLDTO, SaveCarnetApplicationDTO, SaveExtensionApplicationDTO, TransmitApplicationtoProcessDTO,
|
||||
CarnetProcessingCenterDTO, CarnetProcessingCenterDTO2, CopyCarnetDTO, CreateApplicationDTO, DeleteGenerallistItemsDTO, EditGenerallistItemsDTO, GetCarnetControlCenterDTO, GetExtendedSectionDTO, GetOrderDetailsDTO, GetPaymentHistoryDTO, InitiatePaymentDTO, PrintCarnetDTO, PrintGLDTO, SaveCarnetApplicationDTO, SaveExtensionApplicationDTO, SaveHistoryDTO, TransmitApplicationtoProcessDTO,
|
||||
UpdateExpGoodsAuthRepDTO,
|
||||
UpdateShippingDetailsDTO
|
||||
} from 'src/dto/property.dto';
|
||||
@ -275,16 +275,30 @@ export class CarnetApplicationController {
|
||||
//[payment]
|
||||
|
||||
@Post('InitiatePayment')
|
||||
@UseGuards()
|
||||
async InitiatePayment(@Body() body: InitiatePaymentDTO) {
|
||||
return this.carnetApplicationService.InitiatePayment(body);
|
||||
}
|
||||
|
||||
@Post('CompletePayment')
|
||||
@HttpCode(200)
|
||||
@UseGuards()
|
||||
async CapturePayment(@Body() body: CapturePaymentDTO) {
|
||||
return this.carnetApplicationService.CapturePayment(body);
|
||||
}
|
||||
|
||||
// @Get('OrderDetails/:P_ORDERID')
|
||||
async OrderDetails(@Param() body: GetOrderDetailsDTO) {
|
||||
return this.carnetApplicationService.OrderDetails(body);
|
||||
}
|
||||
|
||||
@Get('GetPaymentHistory/:P_APPLICATIONNAME/:P_USERID')
|
||||
async GetPaymentHistory(@Param() body: GetPaymentHistoryDTO) {
|
||||
return this.carnetApplicationService.GetPaymentHistory(body);
|
||||
}
|
||||
|
||||
@Post('SaveHistory')
|
||||
@HttpCode(200)
|
||||
async SaveHistory(@Body() body: SaveHistoryDTO) {
|
||||
return this.carnetApplicationService.SaveHistory(body);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -22,7 +22,10 @@ import {
|
||||
SaveExtensionApplicationDTO,
|
||||
CarnetProcessingCenterDTO2,
|
||||
CapturePaymentDTO,
|
||||
InitiatePaymentDTO
|
||||
InitiatePaymentDTO,
|
||||
GetOrderDetailsDTO,
|
||||
GetPaymentHistoryDTO,
|
||||
SaveHistoryDTO
|
||||
} from 'src/dto/property.dto';
|
||||
import { OracleService } from '../oracle.service';
|
||||
import { BadRequestException } from 'src/exceptions/badRequest.exception';
|
||||
@ -1605,6 +1608,7 @@ export class CarnetApplicationService {
|
||||
|
||||
|
||||
async InitiatePayment(body: InitiatePaymentDTO) {
|
||||
// console.log(body);
|
||||
|
||||
const quantity = 1;
|
||||
|
||||
@ -1613,7 +1617,10 @@ export class CarnetApplicationService {
|
||||
try {
|
||||
const accessToken = await this.payPalService.generateAccessToken();
|
||||
|
||||
// return { accessToken, orderid: "1abc" }
|
||||
// return {
|
||||
// id: "6CU709471L678832M",
|
||||
// href: "https://www.sandbox.paypal.com/checkoutnow?token=6CU709471L678832M"
|
||||
// }
|
||||
|
||||
const response = await axios({
|
||||
url: process.env.PAYPAL_BASE_URL + '/v2/checkout/orders',
|
||||
@ -1697,6 +1704,7 @@ export class CarnetApplicationService {
|
||||
});
|
||||
|
||||
const capture = response?.data?.purchase_units?.[0]?.payments?.captures?.[0];
|
||||
// console.log(JSON.stringify(response?.data));
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
@ -1723,4 +1731,157 @@ export class CarnetApplicationService {
|
||||
}
|
||||
}
|
||||
|
||||
async OrderDetails(body: GetOrderDetailsDTO) {
|
||||
try {
|
||||
|
||||
// Max length of Order ID: 36 characters (UUID)
|
||||
if (!body.P_ORDERID || body.P_ORDERID.length > 36) {
|
||||
throw new BadRequestException("Invalid Order ID");
|
||||
}
|
||||
|
||||
const accessToken = await this.payPalService.generateAccessToken();
|
||||
|
||||
const response = await axios({
|
||||
url: `${process.env.PAYPAL_BASE_URL}/v2/checkout/orders/${body.P_ORDERID}`,
|
||||
method: 'get',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${accessToken}`,
|
||||
},
|
||||
});
|
||||
|
||||
// console.log("PayPal Order Details:", JSON.stringify(response.data));
|
||||
|
||||
return {
|
||||
statusCode: 200,
|
||||
message: "Order details retrieved successfully",
|
||||
data: response.data,
|
||||
};
|
||||
|
||||
} catch (error: any) {
|
||||
const isAxiosError = error.isAxiosError;
|
||||
|
||||
if (isAxiosError) {
|
||||
const axiosErrorCode = error.code;
|
||||
|
||||
switch (axiosErrorCode) {
|
||||
case 'ECONNABORTED':
|
||||
case 'ETIMEDOUT':
|
||||
console.error("PayPal request timed out. Please try again later.")
|
||||
throw new InternalServerException("Service is currently unreachable. Please try again later.");
|
||||
case 'ENOTFOUND':
|
||||
case 'ECONNREFUSED':
|
||||
console.error("PayPal service is currently unavailable. Please try again later.")
|
||||
throw new InternalServerException("Service is currently unreachable. Please try again later.");
|
||||
}
|
||||
}
|
||||
|
||||
const status = error.response?.status || 500;
|
||||
const message = error.response?.data?.message || "Failed to fetch order details.";
|
||||
|
||||
|
||||
console.error("PayPal OrderDetails Error:", {
|
||||
status,
|
||||
message,
|
||||
details: error.response?.data,
|
||||
});
|
||||
|
||||
if (status === 404) {
|
||||
throw new NotFoundException(message);
|
||||
}
|
||||
|
||||
throw new InternalServerException("A Error Occured while Processing your Request");
|
||||
}
|
||||
}
|
||||
|
||||
async GetPaymentHistory(body: GetPaymentHistoryDTO) {
|
||||
let connection;
|
||||
try {
|
||||
connection = await this.oracleDBService.getConnection();
|
||||
|
||||
const result = await connection.execute(
|
||||
`BEGIN
|
||||
Pay_GetPaymentHistory(
|
||||
:P_APPLICATIONNAME, :P_USERID, :P_CURSOR
|
||||
);
|
||||
END;`,
|
||||
{
|
||||
P_APPLICATIONNAME: { val: body.P_APPLICATIONNAME, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_USERID: { val: body.P_USERID, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_CURSOR: { dir: oracledb.BIND_OUT, type: oracledb.CURSOR },
|
||||
// P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
{ outFormat: oracledb.OUT_FORMAT_OBJECT }
|
||||
);
|
||||
|
||||
await connection.commit();
|
||||
|
||||
const outBinds = result.outBinds;
|
||||
if (!outBinds?.P_CURSOR) {
|
||||
this.logger.error('One or more expected cursors are missing from stored procedure output.');
|
||||
throw new InternalServerException("Incomplete data received from the database.");
|
||||
}
|
||||
|
||||
const fres: any = await fetchCursor(outBinds.P_CURSOR, CarnetApplicationService.name);
|
||||
|
||||
if (fres.length > 0 && fres[0].ERRORMESG) {
|
||||
this.logger.warn(fres[0].ERRORMESG);
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
return fres.length > 0 ? fres[0] : {}
|
||||
|
||||
} catch (error) {
|
||||
handleError(error, CarnetApplicationService.name)
|
||||
} finally {
|
||||
await closeOracleDbConnection(connection, CarnetApplicationService.name)
|
||||
}
|
||||
}
|
||||
async SaveHistory(body: SaveHistoryDTO) {
|
||||
let connection;
|
||||
try {
|
||||
connection = await this.oracleDBService.getConnection();
|
||||
|
||||
const result = await connection.execute(
|
||||
`BEGIN
|
||||
Pay_SaveHistory(
|
||||
:P_APPLICATIONNAME, :P_ORDERID, :P_PAYMENTAMOUNT, :P_STATUS, :P_USERID, :P_PAYMENTERROR, :P_CURSOR
|
||||
);
|
||||
END;`,
|
||||
{
|
||||
P_APPLICATIONNAME: { val: body.P_APPLICATIONNAME, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_ORDERID: { val: body.P_ORDERID, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_PAYMENTAMOUNT: { val: body.P_PAYMENTAMOUNT, type: oracledb.DB_TYPE_NUMBER },
|
||||
P_STATUS: { val: body.P_STATUS, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_USERID: { val: body.P_USERID, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_PAYMENTERROR: { val: body.P_PAYMENTERROR, type: oracledb.DB_TYPE_NVARCHAR },
|
||||
P_CURSOR: { dir: oracledb.BIND_OUT, type: oracledb.CURSOR },
|
||||
// P_CURSOR: { type: oracledb.CURSOR, dir: oracledb.BIND_OUT }
|
||||
},
|
||||
{ outFormat: oracledb.OUT_FORMAT_OBJECT }
|
||||
);
|
||||
|
||||
await connection.commit();
|
||||
|
||||
const outBinds = result.outBinds;
|
||||
if (!outBinds?.P_CURSOR) {
|
||||
this.logger.error('One or more expected cursors are missing from stored procedure output.');
|
||||
throw new InternalServerException("Incomplete data received from the database.");
|
||||
}
|
||||
|
||||
const fres: any = await fetchCursor(outBinds.P_CURSOR, CarnetApplicationService.name);
|
||||
|
||||
if (fres.length > 0 && fres[0].ERRORMESG) {
|
||||
this.logger.warn(fres[0].ERRORMESG);
|
||||
throw new BadRequestException(fres[0].ERRORMESG)
|
||||
}
|
||||
|
||||
return { statusCode: 200, message: "Saved Successfully", ...fres[0] };
|
||||
|
||||
} catch (error) {
|
||||
handleError(error, CarnetApplicationService.name)
|
||||
} finally {
|
||||
await closeOracleDbConnection(connection, CarnetApplicationService.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user