farsi messages

This commit is contained in:
2025-12-22 19:12:03 +03:30
parent ed251611c4
commit 1802b05e74
14 changed files with 365 additions and 230 deletions
@@ -12,6 +12,7 @@ import {
IZarinpalVerifyResponse,
} from '../interface/gateway';
import { ConfigService } from '@nestjs/config';
import { PaymentMessage } from 'src/common/enums/message.enum';
@Injectable()
export class ZarinpalGateway implements IPaymentGateway {
@@ -64,7 +65,7 @@ export class ZarinpalGateway implements IPaymentGateway {
if (!data) {
this.logger.error('Invalid response from Zarinpal API (missing data)', JSON.stringify(res.data));
throw new BadRequestException('Invalid response from Zarinpal API');
throw new BadRequestException(PaymentMessage.ZARINPAL_INVALID_RESPONSE);
}
if ((Array.isArray(errors) && errors.length > 0) || code !== 100 || !authority) {
@@ -79,7 +80,7 @@ export class ZarinpalGateway implements IPaymentGateway {
orderId,
}),
);
throw new BadRequestException(message ?? 'Zarinpal payment request error');
throw new BadRequestException(message ?? PaymentMessage.ZARINPAL_PAYMENT_REQUEST_ERROR);
}
return { transactionId: authority };
@@ -98,12 +99,12 @@ export class ZarinpalGateway implements IPaymentGateway {
orderId,
}),
);
throw new BadRequestException('Zarinpal payment request error');
throw new BadRequestException(PaymentMessage.ZARINPAL_PAYMENT_REQUEST_ERROR);
}
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
this.logger.error('Zarinpal payment request error', errorMessage);
throw new BadRequestException(`Failed to request payment from gateway: ${errorMessage}`);
throw new BadRequestException(PaymentMessage.GATEWAY_ERROR);
}
}
@@ -124,14 +125,14 @@ export class ZarinpalGateway implements IPaymentGateway {
// Check if response data exists
if (!res.data || !res.data.data) {
throw new BadRequestException('Invalid response from Zarinpal API');
throw new BadRequestException(PaymentMessage.ZARINPAL_INVALID_RESPONSE);
}
const { code, message, ref_id, card_pan } = res.data.data;
// Check if there are errors in the response
if (code !== 100 && code !== 0) {
throw new BadRequestException(message ?? 'Zarinpal error');
throw new BadRequestException(message ?? PaymentMessage.ZARINPAL_VERIFY_ERROR);
}
return {
@@ -146,7 +147,7 @@ export class ZarinpalGateway implements IPaymentGateway {
throw new BadRequestException(error.response.data);
}
const errorMessage = error instanceof Error ? error.message : 'Unknown error';
throw new BadRequestException(`Failed to verify payment with gateway: ${errorMessage}`);
throw new BadRequestException(PaymentMessage.GATEWAY_ERROR);
}
}
@@ -20,6 +20,15 @@ export class PaymentListeners {
this.paymentSuccessSmsTemplateId = this.configService.get<string>('SMS_PATTERN_PAYMENT_SUCCESS') ?? '123';
}
private getPaymentMethodFarsi(method: string): string {
const methodMap: Record<string, string> = {
Cash: 'نقدی',
Wallet: 'کیف پول',
Online: 'آنلاین',
};
return methodMap[method] || method;
}
@OnEvent(paymentSucceedEvent.name)
async handlePaymentSucceed(event: paymentSucceedEvent) {
try {
@@ -36,7 +45,7 @@ export class PaymentListeners {
restaurantId: event.restaurantId,
message: {
title: NotifTitleEnum.PAYMENT_SUCCESS,
content: `payment order #${event.orderNumber} has been paid successfully with ${event.paymentMethod} method and total amount of ${event.total}`,
content: `پرداخت سفارش شماره ${event.orderNumber} با روش ${this.getPaymentMethodFarsi(event.paymentMethod)} و مبلغ ${event.total} تومان با موفقیت انجام شد`,
sms: {
templateId: this.paymentSuccessSmsTemplateId,
parameters: {
@@ -45,8 +54,8 @@ export class PaymentListeners {
},
},
pushNotif: {
title: `Payment Order ${event.orderNumber} has been paid successfully with ${event.paymentMethod} method and total amount of ${event.total} `,
content: `Payment Order ${event.orderNumber} has been paid successfully with ${event.paymentMethod} method and total amount of ${event.total} `,
title: `پرداخت موفق`,
content: `پرداخت سفارش شماره ${event.orderNumber} با روش ${this.getPaymentMethodFarsi(event.paymentMethod)} و مبلغ ${event.total} تومان با موفقیت انجام شد`,
icon: ``,
action: {
type: NotifTitleEnum.PAYMENT_SUCCESS,
@@ -6,6 +6,7 @@ import { CreatePaymentMethodDto } from '../dto/create-payment-method.dto';
import { UpdatePaymentMethodDto } from '../dto/update-payment-method.dto';
import { RequiredEntityData } from '@mikro-orm/core';
import { Restaurant } from '../../restaurants/entities/restaurant.entity';
import { RestMessage, PaymentMessage } from 'src/common/enums/message.enum';
@Injectable()
export class PaymentMethodService {
@@ -18,7 +19,7 @@ export class PaymentMethodService {
// Check if restaurant exists
const restaurant = await this.em.findOne(Restaurant, { id: restId });
if (!restaurant) {
throw new NotFoundException(`Restaurant with ID ${restId} not found`);
throw new NotFoundException(RestMessage.NOT_FOUND);
}
const paymentMethod = this.paymentMethodRepository.create({
@@ -36,7 +37,7 @@ export class PaymentMethodService {
async findOne(id: string): Promise<PaymentMethod> {
const paymentMethod = await this.paymentMethodRepository.findOne({ id }, { populate: ['restaurant'] });
if (!paymentMethod) {
throw new NotFoundException(`PaymentMethod with ID ${id} not found`);
throw new NotFoundException(PaymentMessage.PAYMENT_METHOD_NOT_FOUND);
}
return paymentMethod;
}
@@ -9,6 +9,7 @@ import { UserWallet } from 'src/modules/users/entities/user-wallet.entity';
import { OrderPaymentContext } from '../interface/payment';
import { OrderStatus } from 'src/modules/orders/interface/order.interface';
import { ChartPeriodEnum, PaymentChartDto } from '../dto/payment-chart.dto';
import { PaymentMessage, OrderMessage } from 'src/common/enums/message.enum';
@Injectable()
export class PaymentsService {
@@ -40,7 +41,7 @@ export class PaymentsService {
return this.handleOnlinePayment(ctx);
default:
throw new BadRequestException('Unsupported payment method');
throw new BadRequestException(PaymentMessage.UNSUPPORTED_PAYMENT_METHOD);
}
}
@@ -52,22 +53,22 @@ export class PaymentsService {
);
if (!order) {
throw new NotFoundException('Order not found');
throw new NotFoundException(OrderMessage.NOT_FOUND);
}
if (order.total <= 0) {
throw new BadRequestException('Amount must be greater than zero');
throw new BadRequestException(PaymentMessage.AMOUNT_MUST_BE_GREATER_THAN_ZERO);
}
const pm = order.paymentMethod;
if (!pm) {
throw new NotFoundException('Payment method not found');
throw new NotFoundException(PaymentMessage.PAYMENT_METHOD_NOT_FOUND);
}
if (pm.method === PaymentMethodEnum.Online) {
if (!pm.gateway) throw new BadRequestException('Gateway is required for online payment');
if (!pm.merchantId) throw new BadRequestException('Merchant ID is required for online payment');
if (!pm.restaurant?.domain) throw new BadRequestException('Restaurant domain is required for online payment');
if (!pm.gateway) throw new BadRequestException(PaymentMessage.GATEWAY_REQUIRED);
if (!pm.merchantId) throw new BadRequestException(PaymentMessage.MERCHANT_ID_REQUIRED);
if (!pm.restaurant?.domain) throw new BadRequestException(PaymentMessage.RESTAURANT_DOMAIN_REQUIRED);
}
return {
@@ -91,7 +92,7 @@ export class PaymentsService {
private async handleWalletPayment(ctx: OrderPaymentContext): Promise<void> {
await this.em.transactional(async em => {
const order = await em.findOne(Order, { id: ctx.order.id }, { populate: ['user', 'restaurant'] });
if (!order) throw new NotFoundException('Order not found');
if (!order) throw new NotFoundException(OrderMessage.NOT_FOUND);
if (order.status === OrderStatus.PAID) {
return;
@@ -169,7 +170,7 @@ export class PaymentsService {
);
if (!payment) {
throw new NotFoundException('Payment not found');
throw new NotFoundException(PaymentMessage.PAYMENT_NOT_FOUND);
}
if (payment.status === PaymentStatusEnum.Paid) {
@@ -178,7 +179,7 @@ export class PaymentsService {
const pm = payment.order.paymentMethod;
if (!pm?.merchantId || !payment.gateway) {
throw new BadRequestException('Invalid payment configuration');
throw new BadRequestException(PaymentMessage.INVALID_PAYMENT_CONFIGURATION);
}
const gateway = this.gatewayManager.get(payment.gateway);
@@ -215,13 +216,13 @@ export class PaymentsService {
const payment = await this.em.transactional(async em => {
const payment = await em.findOne(Payment, id, { populate: ['order'] });
if (!payment) {
throw new NotFoundException('Payment not found');
throw new NotFoundException(PaymentMessage.PAYMENT_NOT_FOUND);
}
if (payment.method !== PaymentMethodEnum.Cash) {
throw new BadRequestException('Payment method is not cash');
throw new BadRequestException(PaymentMessage.PAYMENT_METHOD_NOT_CASH);
}
if (payment.status === PaymentStatusEnum.Paid) {
throw new BadRequestException('Payment already paid');
throw new BadRequestException(PaymentMessage.PAYMENT_ALREADY_PAID);
}
payment.order.status = OrderStatus.PAID;
payment.status = PaymentStatusEnum.Paid;
@@ -269,7 +270,7 @@ export class PaymentsService {
if (existing) {
if (existing.method !== params.method) {
throw new BadRequestException('Existing pending payment method does not match order payment method');
throw new BadRequestException(PaymentMessage.EXISTING_PENDING_PAYMENT_MISMATCH);
}
return existing;