feat: add payment module and factory
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
import { HttpService } from "@nestjs/axios";
|
||||
import { Inject, Injectable, InternalServerErrorException, Logger } from "@nestjs/common";
|
||||
import { AxiosError } from "axios";
|
||||
import { catchError, firstValueFrom } from "rxjs";
|
||||
|
||||
import { PaymentMessage } from "../../../common/enums/message.enum";
|
||||
import { IZarinpalConfig } from "../../../configs/zarinpal.config";
|
||||
import { ZARINPAL_CONFIG } from "../constants";
|
||||
import { GatewayEnum } from "../enums/gateway.enum";
|
||||
import {
|
||||
IPaymentGateway,
|
||||
IPaymentVerifyParams,
|
||||
IProcessPaymentParams,
|
||||
ZarinPalPGNewArgs,
|
||||
ZarinPalPGNewRequestData,
|
||||
ZarinPalPGVerifyData,
|
||||
} from "../interfaces/IPayment";
|
||||
|
||||
@Injectable()
|
||||
export class ZarinpalGateway implements IPaymentGateway {
|
||||
private readonly logger = new Logger(ZarinpalGateway.name);
|
||||
private readonly gatewayApiUrl: string;
|
||||
private readonly requestHeader: Record<string, string> = { "Content-Type": "application/json", Accept: "application/json" };
|
||||
|
||||
constructor(
|
||||
@Inject(ZARINPAL_CONFIG) private readonly config: IZarinpalConfig,
|
||||
private readonly httpService: HttpService,
|
||||
) {
|
||||
this.gatewayApiUrl = `https://${this.config.ipgType}.${this.config.gatewayApiUrl}`;
|
||||
}
|
||||
//*************************************** */
|
||||
async processPayment(processParams: IProcessPaymentParams) {
|
||||
try {
|
||||
const purchaseData: ZarinPalPGNewArgs = {
|
||||
merchant_id: this.config.merchantId,
|
||||
amount: processParams.amount,
|
||||
callback_url: `${this.config.callBackUrl}/${GatewayEnum.ZARINPAL}`,
|
||||
description: processParams.description,
|
||||
currency: "IRT",
|
||||
metadata: { email: processParams.email, mobile: processParams.mobile },
|
||||
};
|
||||
|
||||
const { data } = await firstValueFrom(
|
||||
this.httpService
|
||||
.post<ZarinPalPGNewRequestData>(`${this.gatewayApiUrl}/v4/payment/request.json`, purchaseData, {
|
||||
headers: this.requestHeader,
|
||||
})
|
||||
.pipe(
|
||||
catchError((err: AxiosError) => {
|
||||
this.logger.error(err);
|
||||
throw new InternalServerErrorException(PaymentMessage.ERROR_IN_PROCESS_PAYMENT);
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
return {
|
||||
redirectUrl: `${this.gatewayApiUrl}/StartPay/${data.data.authority}`,
|
||||
message: data.data.message,
|
||||
reference: data.data.authority,
|
||||
};
|
||||
} catch (error) {
|
||||
this.logger.error(error);
|
||||
throw new InternalServerErrorException(PaymentMessage.ERROR_IN_PROCESS_PAYMENT);
|
||||
}
|
||||
}
|
||||
//********************************** */
|
||||
async verifyPayment(verifyParams: IPaymentVerifyParams) {
|
||||
try {
|
||||
const verifyData = { authority: verifyParams.reference, amount: verifyParams.amount, merchant_id: this.config.merchantId };
|
||||
|
||||
const { data } = await firstValueFrom(
|
||||
this.httpService
|
||||
.post<ZarinPalPGVerifyData>(`${this.config.gatewayApiUrl}/v4/payment/verify.json`, verifyData, { headers: this.requestHeader })
|
||||
.pipe(
|
||||
catchError((err: AxiosError) => {
|
||||
this.logger.error(err);
|
||||
throw new InternalServerErrorException(PaymentMessage.ERROR_IN_VERIFY_PAYMENT);
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
return {
|
||||
code: data.data.code,
|
||||
message: data.data.message,
|
||||
card_hash: data.data.card_hash,
|
||||
card_pan: data.data.card_pan,
|
||||
ref_id: data.data.ref_id,
|
||||
fee_type: data.data.fee_type,
|
||||
fee: data.data.fee,
|
||||
};
|
||||
} catch (error) {
|
||||
this.logger.error(error);
|
||||
throw new InternalServerErrorException(PaymentMessage.ERROR_IN_VERIFY_PAYMENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user