Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
uses: actions/checkout@v4

- name: Run secret scan with Gitleaks
uses: zricethezav/gitleaks-action@v8
uses: gitleaks/gitleaks-action@v2
with:
version: 'v8.18.0'
args: '--path=./ --verbose'
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"scripts": {
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"format:check": "prettier --check \"src/app.module.ts\" \"src/users/users.service.ts\" \"src/job-processing/**/*.ts\" \"src/email/email.module.ts\" \"src/email/email.processor.ts\" \"src/email/email.service.ts\" \"src/media/media.controller.ts\" \"src/media/media.jobs.ts\" \"src/media/media.module.ts\" \"src/media/media.processor.ts\" \"src/media/media.service.ts\" \"src/media/services/image-processing.service.ts\" \"src/products/product-images.controller.ts\" \"src/recommendation/recommendation.controller.ts\" \"src/recommendation/recommendation.jobs.ts\" \"src/recommendation/recommendation.module.ts\" \"src/recommendation/recommendation.processor.ts\" \"src/recommendation/recommendation.scheduler.ts\" \"src/recommendation/recommendation.service.ts\" \"src/messaging/**/*.ts\" \"README.md\" \"package.json\" \"docker-compose.yml\" \".github/workflows/*.yml\"",
"format:check": "prettier --check \"src/app.module.ts\" \"src/users/users.service.ts\" \"src/job-processing/**/*.ts\" \"src/email/email.module.ts\" \"src/email/email.processor.ts\" \"src/email/email.service.ts\" \"src/media/media.controller.ts\" \"src/media/media.jobs.ts\" \"src/media/media.module.ts\" \"src/media/media.processor.ts\" \"src/media/media.service.ts\" \"src/media/services/image-processing.service.ts\" \"src/products/product-images.controller.ts\" \"src/recommendation/recommendation.controller.ts\" \"src/recommendation/recommendation.jobs.ts\" \"src/recommendation/recommendation.module.ts\" \"src/recommendation/recommendation.processor.ts\" \"src/recommendation/recommendation.scheduler.ts\" \"src/recommendation/recommendation.service.ts\" \"src/messaging/**/*.ts\" \"src/rewards/**/*.ts\" \"src/payments/payments.module.ts\" \"src/payments/payments.service.ts\" \"src/payments/dto/payment.dto.ts\" \"README.md\" \"package.json\" \"docker-compose.yml\" \".github/workflows/*.yml\"",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
Expand Down
1 change: 1 addition & 0 deletions src/payments/dto/payment.dto.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export class InitiatePaymentDto {
readonly orderId: string;
readonly currency: PaymentCurrency;
readonly timeoutMinutes?: number;
readonly pointsToUse?: number;
}

export class PaymentWebhookDto {
Expand Down
2 changes: 2 additions & 0 deletions src/payments/payments.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { Wallet } from '../wallet/entities/wallet.entity';
import { OrdersModule } from '../orders/orders.module';
import { WalletModule } from '../wallet/wallet.module';
import { WebhooksModule } from '../webhooks/webhooks.module';
import { RewardsModule } from '../rewards/rewards.module';
import { LoggerModule } from '../common/logger/logger.module';

@Module({
Expand All @@ -22,6 +23,7 @@ import { LoggerModule } from '../common/logger/logger.module';
OrdersModule,
WalletModule,
WebhooksModule,
RewardsModule,
LoggerModule,
],
controllers: [PaymentsController],
Expand Down
33 changes: 30 additions & 3 deletions src/payments/payments.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
PaymentTimeoutEvent,
EventNames,
} from '../common/events';
import { RewardsService } from '../rewards/rewards.service';
import { LoggerService } from '../common/logger/logger.service';

@Injectable()
Expand All @@ -45,8 +46,8 @@ export class PaymentsService {
private walletsRepository: Repository<Wallet>,
private configService: ConfigService,
private eventEmitter: EventEmitter2,
private readonly rewardsService: RewardsService,
logger: LoggerService,
private readonly logger: LoggerService,
) {
this.logger = logger;
// Initialize Stellar SDK
Expand Down Expand Up @@ -110,6 +111,32 @@ export class PaymentsService {
return this.mapToResponseDto(existingPayment);
}

// Apply reward points if provided
let finalAmount = parseFloat(order.totalAmount.toString());
let pointsUsed = 0;
let pointsDiscount = 0;

if (initiatePaymentDto.pointsToUse && initiatePaymentDto.pointsToUse > 0) {
try {
const pointsResult = await this.rewardsService.applyPointsToCheckout(
order.buyerId,
initiatePaymentDto.pointsToUse,
finalAmount,
);
pointsUsed = pointsResult.pointsUsed;
pointsDiscount = pointsResult.discountAmount;
finalAmount = finalAmount - pointsDiscount;
this.logger.log(
`Applied ${pointsUsed} reward points for order ${initiatePaymentDto.orderId}, discount: $${pointsDiscount}`,
);
} catch (error) {
this.logger.warn(
`Failed to apply reward points: ${error.message}. Proceeding without points.`,
);
// Continue without points if redemption fails
}
}

// Get buyer's wallet to get payment address
const wallet = await this.walletsRepository.findOne({
where: { userId: order.buyerId },
Expand All @@ -126,7 +153,7 @@ export class PaymentsService {

const payment = this.paymentsRepository.create({
orderId: initiatePaymentDto.orderId,
amount: parseFloat(order.totalAmount.toString()),
amount: finalAmount,
currency: initiatePaymentDto.currency,
status: PaymentStatus.PENDING,
destinationWalletAddress: wallet.publicKey,
Expand All @@ -138,7 +165,7 @@ export class PaymentsService {
const savedPayment = await this.paymentsRepository.save(payment);

this.logger.info(
`Payment initiated for order ${initiatePaymentDto.orderId}: ${savedPayment.id}`,
`Payment initiated for order ${initiatePaymentDto.orderId}: ${savedPayment.id}. Original: $${order.totalAmount}, After points: $${finalAmount}`,
);

// Emit event for payment monitoring
Expand Down
Loading