diff --git a/package.json b/package.json index 9933cfb..eb1eada 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,8 @@ "passport": "^0.6.0", "passport-jwt": "^4.0.1", "pg": "^8.10.0", + "randomized-string": "^2.0.0", + "randomstring": "^1.3.0", "reflect-metadata": "^0.1.13", "rxjs": "^7.2.0", "slugify": "^1.6.6", diff --git a/src/common/constants/enums.ts b/src/common/constants/enums.ts index aeb4c3d..eb7608b 100644 --- a/src/common/constants/enums.ts +++ b/src/common/constants/enums.ts @@ -21,6 +21,7 @@ export enum SenderType { PAYER = 'PAYER', PATIENT = 'PATIENT', PROVIDER = 'PROVIDER', + WIIQARE_MANAGER = 'WIIQARE_MANAGER' } export enum ReceiverType { diff --git a/src/modules/patient-svc/patient-svc.service.ts b/src/modules/patient-svc/patient-svc.service.ts index dfddc0d..b0722be 100644 --- a/src/modules/patient-svc/patient-svc.service.ts +++ b/src/modules/patient-svc/patient-svc.service.ts @@ -18,7 +18,7 @@ export class PatientSvcService { private readonly patientRepository: Repository, @InjectRepository(Transaction) private readonly transactionRepository: Repository, - ) {} + ) { } /** * This function is used to register a patient account @@ -43,9 +43,9 @@ export class PatientSvcService { const updateData = patientDto; delete updateData.id; - await this.patientRepository.save( {...patient, ...updateData } ); + await this.patientRepository.save({ ...patient, ...updateData }); - return { ...patient,...updateData}; + return { ...patient, ...updateData }; } /** @@ -95,18 +95,18 @@ export class PatientSvcService { .select('patient.id', 'id') .where('patient.added_by = :payerId', { payerId }) .getRawMany(); - const addedByUserUniqueIds = addedByUser.map( result => result.id ); + const addedByUserUniqueIds = addedByUser.map(result => result.id); const uniquePatientIds = uniquePatientIdsQuery.map( (result) => result.ownerId, ); - const combinedPatientIds = Object.values( [...uniquePatientIds, ...addedByUserUniqueIds ].reduce( ( acc, item ) => { - acc[ item ] = item; + const combinedPatientIds = Object.values([...uniquePatientIds, ...addedByUserUniqueIds].reduce((acc, item) => { + acc[item] = item; return acc; - }, {} )); + }, {})); - console.log('combined', combinedPatientIds ); + console.log('combined', combinedPatientIds); const patients = await this.patientRepository .createQueryBuilder('patient') diff --git a/src/modules/payer-svc/payer-svc.controller.ts b/src/modules/payer-svc/payer-svc.controller.ts index 74bc1d0..a2c30c0 100644 --- a/src/modules/payer-svc/payer-svc.controller.ts +++ b/src/modules/payer-svc/payer-svc.controller.ts @@ -50,7 +50,7 @@ export class PayerSvcController { private readonly cachingService: CachingService, private readonly sessionService: SessionService, private readonly patientService: PatientSvcService, - ) {} + ) { } @Get('patient') @Roles(UserRole.PAYER) @@ -126,6 +126,19 @@ export class PayerSvcController { return await this.patientService.registerPatient(createPatientAccountDto); } + @Post('patient/admin') + @Roles(UserRole.WIIQARE_MANAGER) + @ApiOperation({ + summary: 'This API is used register new Patient by WIIQARE MANAGER.', + }) + async registerNewPatientForAdmin( + @Body() createPatientAccountDto: CreatePatientDto, + @AuthUser() authUser: JwtClaimsDataDto, + ): Promise { + console.log(authUser); + return await this.patientService.registerPatient(createPatientAccountDto); + } + @Put('patient') @Roles(UserRole.PAYER) @ApiOperation({ diff --git a/src/modules/smart-contract/payment.controller.ts b/src/modules/smart-contract/payment.controller.ts index 6bbf7be..48c0f74 100644 --- a/src/modules/smart-contract/payment.controller.ts +++ b/src/modules/smart-contract/payment.controller.ts @@ -39,6 +39,7 @@ import { Voucher } from './entities/voucher.entity'; import { operationService } from '../operation-saving/operation.service'; import { OperationType } from '../operation-saving/entities/operation.entity'; import { PaymentWithoutStripe } from './dto/mint-voucher.dto'; +import randomstring from 'randomstring'; @ApiTags('payment') @Controller('payment') @@ -81,6 +82,8 @@ export class PaymentController { @Body() event: Stripe.Event, @Req() req: RawBodyRequest, ) { + console.log("test"); + try { // Verify the webhook event with Stripe to ensure it is authentic const webhookSecret = this.appConfigService.stripeWebHookSecret; @@ -208,7 +211,8 @@ export class PaymentController { } @Post('notification/admin-pmt') - @Public() + @Roles(UserRole.WIIQARE_MANAGER) + // @Public() @ApiOperation({ summary: 'This API receive payment notification without stripe webhook', }) @@ -217,116 +221,94 @@ export class PaymentController { ) { try { - let status = 'payment_intent.succeeded'; - - // Handle the event based on its type - switch (status) { - case 'payment_intent.succeeded': - - // const { - // id: stripePaymentId, - // amount: senderAmount, - // currency: senderCurrency, - // } = verifiedEvent.data.object as Stripe.PaymentIntent; - - // const { metadata } = verifiedEvent.data.object as unknown as Record< - // string, - // any - // >; - - //TODO: Please use our own BE exchange rate API to get the latest exchange rate!! - const { - senderId, - patientId, - currencyPatientAmount, - currencyPatient, - currencyRate, - senderAmount, - senderCurrency - } = event; - - const voucherData = await this.smartContractService.mintVoucher({ - amount: Math.round(currencyPatientAmount), - ownerId: patientId, - currency: currencyPatient, - patientId: patientId, - }); - - // console.log('vdata', voucherData.events.mintVoucherEvent.returnValues.voucherID ); - - const voucherJSON = { - id: _.get(voucherData, 'events.mintVoucherEvent.returnValues.0'), - amount: _.get( - voucherData, - 'events.mintVoucherEvent.returnValues.1.[0]', - ), - currency: _.get( - voucherData, - 'events.mintVoucherEvent.returnValues.1.[1]', - ), - ownerId: _.get( - voucherData, - 'events.mintVoucherEvent.returnValues.1.[2]', - ), - hospitalId: _.get( - voucherData, - 'events.mintVoucherEvent.returnValues.1.[3]', - ), - patientId: _.get( - voucherData, - 'events.mintVoucherEvent.returnValues.1.[4]', - ), - status: _.get( - voucherData, - 'events.mintVoucherEvent.returnValues.1.[5]', - ) - }; - - const transactionHash = _.get( - voucherData, - 'events.mintVoucherEvent.transactionHash', - ); - - const shortenHash = transactionHash.slice(0, 8); + //TODO: Please use our own BE exchange rate API to get the latest exchange rate!! + const { + senderId, + patientId, + currencyPatientAmount, + currencyPatient, + currencyRate, + senderAmount, + senderCurrency + } = event; + + const voucherData = await this.smartContractService.mintVoucher({ + amount: Math.round(currencyPatientAmount), + ownerId: patientId, + currency: currencyPatient, + patientId: patientId, + }); + + // console.log('vdata', voucherData.events.mintVoucherEvent.returnValues.voucherID ); + + const voucherJSON = { + id: _.get(voucherData, 'events.mintVoucherEvent.returnValues.0'), + amount: _.get( + voucherData, + 'events.mintVoucherEvent.returnValues.1.[0]', + ), + currency: _.get( + voucherData, + 'events.mintVoucherEvent.returnValues.1.[1]', + ), + ownerId: _.get( + voucherData, + 'events.mintVoucherEvent.returnValues.1.[2]', + ), + hospitalId: _.get( + voucherData, + 'events.mintVoucherEvent.returnValues.1.[3]', + ), + patientId: _.get( + voucherData, + 'events.mintVoucherEvent.returnValues.1.[4]', + ), + status: _.get( + voucherData, + 'events.mintVoucherEvent.returnValues.1.[5]', + ) + }; + + const transactionHash = _.get( + voucherData, + 'events.mintVoucherEvent.transactionHash', + ); - const transactionToSave = this.transactionRepository.create({ - senderAmount, - senderCurrency: senderCurrency.toUpperCase(), - amount: Math.round(currencyPatientAmount), - currency: currencyPatient, - conversionRate: currencyRate, - senderId, - ownerId: patientId, - stripePaymentId: "admin", - voucher: voucherJSON, - status: TransactionStatus.PENDING, - }); - const savedTransaction = await this.transactionRepository.save( - transactionToSave, - ); + const shortenHash = transactionHash.slice(0, 8); + + const transactionToSave = this.transactionRepository.create({ + senderAmount, + senderCurrency: senderCurrency.toUpperCase(), + amount: Math.round(currencyPatientAmount), + currency: currencyPatient, + conversionRate: currencyRate, + senderId, + ownerId: patientId, + stripePaymentId: randomstring.generate(12), + voucher: voucherJSON, + status: TransactionStatus.PENDING, + }); + const savedTransaction = await this.transactionRepository.save( + transactionToSave, + ); - // update this - const voucherToSave = this.voucherRepository.create({ - vid: voucherJSON.id, - voucherHash: transactionHash, - shortenHash: shortenHash, - value: Math.round(currencyPatientAmount), - senderId: senderId, - senderType: SenderType.PAYER, - receiverId: patientId, - receiverType: ReceiverType.PATIENT, - status: VoucherStatus.UNCLAIMED, - transaction: transactionToSave, - }); - await this.voucherRepository.save(voucherToSave); + // update this + const voucherToSave = this.voucherRepository.create({ + vid: voucherJSON.id, + voucherHash: transactionHash, + shortenHash: shortenHash, + value: Math.round(currencyPatientAmount), + senderId: senderId, + senderType: SenderType.WIIQARE_MANAGER, + receiverId: patientId, + receiverType: ReceiverType.PATIENT, + status: VoucherStatus.UNCLAIMED, + transaction: transactionToSave, + }); + await this.voucherRepository.save(voucherToSave); + + return savedTransaction - break; - case 'payment_intent.payment_failed': - // Handle the failure in some way - break; - default: - logInfo(`Unhandled Stripe event type: `); - } } catch (err) { logError(`Error processing webhook event: ${err}`); return { error: 'Failed to process payment event' }; diff --git a/yarn.lock b/yarn.lock index dcd684b..bbcc754 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7590,6 +7590,11 @@ quick-lru@^5.1.1: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== +randombytes@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.3.tgz#674c99760901c3c4112771a31e521dc349cc09ec" + integrity sha512-lDVjxQQFoCG1jcrP06LNo2lbWp4QTShEXnhActFBwYuHprllQV6VUpwreApsYqCgD+N1mHoqJ/BI/4eV4R2GYg== + randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -7597,6 +7602,18 @@ randombytes@^2.1.0: dependencies: safe-buffer "^5.1.0" +randomized-string@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/randomized-string/-/randomized-string-2.0.0.tgz#38c54decadca38f39d77ef29283ffb8ec4a604a1" + integrity sha512-nQnPDFxRbaI2YSyV4C0tQufAvBXA9qnbisYL9z1aXXLG06BJMpYT0dlIuwyvN76hKdkto/C0L7x+4GcZDDEfDQ== + +randomstring@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/randomstring/-/randomstring-1.3.0.tgz#1bf9d730066899e70aee3285573f84708278683d" + integrity sha512-gY7aQ4i1BgwZ8I1Op4YseITAyiDiajeZOPQUbIq9TPGPhUm5FX59izIaOpmKbME1nmnEiABf28d9K2VSii6BBg== + dependencies: + randombytes "2.0.3" + range-parser@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031"