set order status as paid after wallet payment
This commit is contained in:
@@ -37,8 +37,7 @@ export class OrdersService {
|
||||
private readonly logger = new Logger(OrdersService.name);
|
||||
|
||||
private static readonly STATUS_TRANSITIONS: Record<OrderStatus, readonly OrderStatus[]> = {
|
||||
[OrderStatus.NEW]: [OrderStatus.PENDING_PAYMENT, OrderStatus.CONFIRMED, OrderStatus.CANCELED],
|
||||
[OrderStatus.PENDING_PAYMENT]: [OrderStatus.PAID, OrderStatus.FAILED, OrderStatus.CANCELED],
|
||||
[OrderStatus.PENDING_PAYMENT]: [OrderStatus.PAID, OrderStatus.FAILED, OrderStatus.CANCELED, OrderStatus.CONFIRMED],
|
||||
[OrderStatus.PAID]: [OrderStatus.CONFIRMED, OrderStatus.REFUNDED],
|
||||
[OrderStatus.CONFIRMED]: [OrderStatus.PREPARING, OrderStatus.CANCELED],
|
||||
[OrderStatus.PREPARING]: [OrderStatus.READY, OrderStatus.SHIPPED, OrderStatus.CANCELED],
|
||||
@@ -80,8 +79,7 @@ export class OrdersService {
|
||||
totalItems: cart.totalItems || 0,
|
||||
description: cart.description,
|
||||
tableNumber: cart.tableNumber,
|
||||
status: OrderStatus.NEW,
|
||||
paymentStatus: PaymentStatusEnum.Pending,
|
||||
status: OrderStatus.PENDING_PAYMENT,
|
||||
});
|
||||
|
||||
em.persist(order);
|
||||
|
||||
@@ -35,7 +35,6 @@ export class OrderRepository extends EntityRepository<Order> {
|
||||
page = 1,
|
||||
limit = 10,
|
||||
status,
|
||||
paymentStatus,
|
||||
search,
|
||||
startDate,
|
||||
endDate,
|
||||
@@ -57,11 +56,6 @@ export class OrderRepository extends EntityRepository<Order> {
|
||||
where.user = { id: userId };
|
||||
}
|
||||
|
||||
// Filter by payment status
|
||||
if (paymentStatus) {
|
||||
where.paymentStatus = paymentStatus;
|
||||
}
|
||||
|
||||
// Filter by date range
|
||||
if (startDate || endDate) {
|
||||
where.createdAt = {};
|
||||
|
||||
@@ -52,7 +52,11 @@ export class ZarinpalGateway implements IPaymentGateway {
|
||||
};
|
||||
|
||||
try {
|
||||
const res = await axios.post<IZarinpalPaymentResponse>(this.zarinpalRequestUrl, zarinpalRequest, this.axiosConfig);
|
||||
const res = await axios.post<IZarinpalPaymentResponse>(
|
||||
this.zarinpalRequestUrl,
|
||||
zarinpalRequest,
|
||||
this.axiosConfig,
|
||||
);
|
||||
const { data, errors } = res.data ?? {};
|
||||
const code = data?.code;
|
||||
const message = data?.message;
|
||||
@@ -112,7 +116,11 @@ export class ZarinpalGateway implements IPaymentGateway {
|
||||
authority: transactionId,
|
||||
};
|
||||
|
||||
const res = await axios.post<IZarinpalVerifyResponse>(this.zarinpalVerifyUrl, zarinpalVerifyRequest, this.axiosConfig);
|
||||
const res = await axios.post<IZarinpalVerifyResponse>(
|
||||
this.zarinpalVerifyUrl,
|
||||
zarinpalVerifyRequest,
|
||||
this.axiosConfig,
|
||||
);
|
||||
|
||||
// Check if response data exists
|
||||
if (!res.data || !res.data.data) {
|
||||
@@ -128,7 +136,7 @@ export class ZarinpalGateway implements IPaymentGateway {
|
||||
|
||||
return {
|
||||
success: code === 100,
|
||||
referenceId: ref_id ? ref_id.toString() : undefined,
|
||||
referenceId: ref_id ? ref_id.toString() : '',
|
||||
cardPan: card_pan,
|
||||
raw: res.data,
|
||||
};
|
||||
@@ -145,5 +153,4 @@ export class ZarinpalGateway implements IPaymentGateway {
|
||||
getPaymentUrl(authority: string): string {
|
||||
return `${this.zarinpalPaymentBaseUrl}/pg/StartPay/${authority}`;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ export interface IPaymentVerifyParams {
|
||||
|
||||
export interface IPaymentVerifyData {
|
||||
success: boolean;
|
||||
referenceId?: string;
|
||||
referenceId: string;
|
||||
cardPan?: string;
|
||||
raw: Record<string, any>;
|
||||
}
|
||||
|
||||
@@ -20,13 +20,11 @@ export class PaymentsService {
|
||||
private readonly inventoryService: InventoryService,
|
||||
) {}
|
||||
|
||||
async payOrder(
|
||||
orderId: string,
|
||||
): Promise<{ paymentUrl: string | null }> {
|
||||
async payOrder(orderId: string): Promise<{ paymentUrl: string | null }> {
|
||||
const ctx = await this.loadAndValidateOrder(orderId);
|
||||
|
||||
// Idempotency: avoid creating/charging again for already-paid orders
|
||||
if (ctx.order.paymentStatus === PaymentStatusEnum.Paid) {
|
||||
if (ctx.order.status === OrderStatus.PAID) {
|
||||
return { paymentUrl: null };
|
||||
}
|
||||
|
||||
@@ -47,9 +45,7 @@ export class PaymentsService {
|
||||
}
|
||||
}
|
||||
|
||||
private async loadAndValidateOrder(
|
||||
orderId: string,
|
||||
): Promise<OrderPaymentContext> {
|
||||
private async loadAndValidateOrder(orderId: string): Promise<OrderPaymentContext> {
|
||||
const order = await this.em.findOne(
|
||||
Order,
|
||||
{ id: orderId },
|
||||
@@ -98,7 +94,7 @@ export class PaymentsService {
|
||||
const order = await em.findOne(Order, { id: ctx.order.id }, { populate: ['user', 'restaurant'] });
|
||||
if (!order) throw new NotFoundException('Order not found');
|
||||
|
||||
if (order.paymentStatus === PaymentStatusEnum.Paid) {
|
||||
if (order.status === OrderStatus.PAID) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -126,17 +122,14 @@ export class PaymentsService {
|
||||
|
||||
payment.status = PaymentStatusEnum.Paid;
|
||||
payment.paidAt = new Date();
|
||||
order.paymentStatus = PaymentStatusEnum.Paid;
|
||||
order.status = OrderStatus.PAID;
|
||||
|
||||
em.persist([wallet, payment, order]);
|
||||
await em.flush();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
private async handleOnlinePayment(
|
||||
ctx: OrderPaymentContext,
|
||||
): Promise<{ paymentUrl: string }> {
|
||||
private async handleOnlinePayment(ctx: OrderPaymentContext): Promise<{ paymentUrl: string }> {
|
||||
const gateway = this.gatewayManager.get(ctx.gateway!);
|
||||
|
||||
const payment = await this.getOrCreateLatestPendingPayment(ctx.order.id, {
|
||||
@@ -168,11 +161,7 @@ export class PaymentsService {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
async verifyPayment(
|
||||
transactionId: string,
|
||||
orderId: string,
|
||||
): Promise<Payment> {
|
||||
async verifyPayment(transactionId: string, orderId: string): Promise<Payment> {
|
||||
return this.em.transactional(async em => {
|
||||
const payment = await em.findOne(
|
||||
Payment,
|
||||
@@ -207,7 +196,7 @@ export class PaymentsService {
|
||||
this.failPayment(payment);
|
||||
return payment;
|
||||
}
|
||||
this.markPaid(payment);
|
||||
this.markPaid(payment, result.referenceId);
|
||||
this.confirmOrder(payment.order);
|
||||
|
||||
await em.flush();
|
||||
@@ -223,17 +212,16 @@ export class PaymentsService {
|
||||
);
|
||||
}
|
||||
|
||||
private markPaid(payment: Payment) {
|
||||
private markPaid(payment: Payment, referenceId: string) {
|
||||
payment.status = PaymentStatusEnum.Paid;
|
||||
payment.paidAt = new Date();
|
||||
payment.referenceId = payment.referenceId;
|
||||
payment.order.paymentStatus = PaymentStatusEnum.Paid;
|
||||
payment.referenceId = referenceId;
|
||||
}
|
||||
|
||||
private failPayment(payment: Payment) {
|
||||
payment.status = PaymentStatusEnum.Failed;
|
||||
payment.failedAt = new Date();
|
||||
payment.order.paymentStatus = PaymentStatusEnum.Failed;
|
||||
payment.order.status = OrderStatus.FAILED;
|
||||
}
|
||||
|
||||
private confirmOrder(order: Order) {
|
||||
|
||||
Reference in New Issue
Block a user