add request wallet charge

This commit is contained in:
2026-07-04 10:55:02 +03:30
parent 95240a311e
commit 9f8d39938c
11 changed files with 274 additions and 5 deletions
@@ -1,15 +1,30 @@
import { BadRequestException, Injectable } from '@nestjs/common';
import { BadRequestException, Injectable, Logger, NotFoundException } from '@nestjs/common';
import { HttpService } from '@nestjs/axios';
import { ConfigService } from '@nestjs/config';
import { EntityManager } from '@mikro-orm/postgresql';
import { AxiosError } from 'axios';
import { catchError, firstValueFrom, throwError } from 'rxjs';
import { Restaurant } from '../entities/restaurant.entity';
import { RestaurantCreditRequest } from '../entities/restaurant-credit-request.entity';
import { RestaurantCreditTransaction } from '../entities/restaurant-credit-transaction.entity';
import {
RestaurantCreditTransactionReason,
RestaurantCreditTransactionType,
} from '../interface/restaurant-credit-transaction.interface';
import { RestaurantCreditRequestStatus } from '../interface/restaurant-credit-request.interface';
import { CreateExternalInvoice } from '../interface/external-invoice.interface';
import { ChargeRequestDto } from '../dto/charge-request.dto';
import { RestMessage } from 'src/common/enums/message.enum';
@Injectable()
export class RestaurantWalletService {
constructor(private readonly defaultEm: EntityManager) {}
private readonly logger = new Logger(RestaurantWalletService.name);
constructor(
private readonly defaultEm: EntityManager,
private readonly httpService: HttpService,
private readonly configService: ConfigService,
) {}
async createTransaction(params: {
restaurant: Restaurant;
@@ -46,4 +61,67 @@ export class RestaurantWalletService {
await em.persistAndFlush([restaurant, creditTransaction]);
}
async chargeRequest(restId: string, dto: ChargeRequestDto): Promise<RestaurantCreditRequest> {
const restaurant = await this.defaultEm.findOne(Restaurant, { id: restId });
if (!restaurant) {
throw new NotFoundException(RestMessage.NOT_FOUND);
}
if (!restaurant.subscriptionId) {
throw new BadRequestException('اشتراک رستوران یافت نشد');
}
const params: CreateExternalInvoice = {
danakSubscriptionId: restaurant.subscriptionId,
businessId: restId,
items: [
{
name: 'dmenu_wallet_charge',
count: 1,
unitPrice: dto.amount,
discount: 0,
},
],
};
const danakApiUrl = this.configService.getOrThrow<string>('DANAK_API_URL');
const xApiKey = this.configService.getOrThrow<string>('EXTERNAL_API_KEYS');
let invoiceId: string;
try {
const { data } = await firstValueFrom(
this.httpService
.post<{ data: { invoice: { id: string } } }>(`${danakApiUrl}/invoices/external/create`, params, {
headers: {
'Content-Type': 'application/json',
'X-API-Key': xApiKey,
},
})
.pipe(
catchError((err: AxiosError) => {
this.logger.error(`Failed to create invoice: ${err.message}`, err.stack);
return throwError(() => err);
}),
),
);
invoiceId = data.data.invoice.id;
} catch (error: unknown) {
this.logger.error(
`Error creating invoice: ${error instanceof Error ? error.message : 'Unknown error'}`,
);
throw new BadRequestException('ایجاد فاکتور با خطا مواجه شد');
}
const creditRequest = this.defaultEm.create(RestaurantCreditRequest, {
restaurant,
amount: dto.amount,
invoiceId,
status: RestaurantCreditRequestStatus.PENDING,
});
await this.defaultEm.persistAndFlush(creditRequest);
return creditRequest;
}
}